rsx: Properly scale overlay passes to match drawable area

This commit is contained in:
kd-11 2019-09-28 12:53:20 +03:00 committed by kd-11
parent 28534e8833
commit 2275259bf5
6 changed files with 75 additions and 87 deletions

View file

@ -664,7 +664,8 @@ struct area_base
{
}
constexpr area_base(const coord_base<T>& coord) : x1{ coord.x }, x2{ coord.x + coord.width }, y1{ coord.y }, y2{ coord.y + coord.height }
template<typename N>
constexpr area_base(const coord_base<N>& coord) : x1{ T(coord.x) }, x2{ T(coord.x + coord.width) }, y1{ T(coord.y) }, y2{ T(coord.y + coord.height) }
{
}

View file

@ -1589,33 +1589,33 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
gl::screen.bind();
gl::screen.clear(gl::buffers::color);
// Calculate blit coordinates
coordi aspect_ratio;
sizei csize(m_frame->client_width(), m_frame->client_height());
sizei new_size = csize;
if (!g_cfg.video.stretch_to_display_area)
{
const double aq = (double)buffer_width / buffer_height;
const double rq = (double)new_size.width / new_size.height;
const double q = aq / rq;
if (q > 1.0)
{
new_size.height = int(new_size.height / q);
aspect_ratio.y = (csize.height - new_size.height) / 2;
}
else if (q < 1.0)
{
new_size.width = int(new_size.width * q);
aspect_ratio.x = (csize.width - new_size.width) / 2;
}
}
aspect_ratio.size = new_size;
if ((u32)info.buffer < display_buffers_count && buffer_width && buffer_height)
{
// Calculate blit coordinates
coordi aspect_ratio;
sizei csize(m_frame->client_width(), m_frame->client_height());
sizei new_size = csize;
if (!g_cfg.video.stretch_to_display_area)
{
const double aq = (double)buffer_width / buffer_height;
const double rq = (double)new_size.width / new_size.height;
const double q = aq / rq;
if (q > 1.0)
{
new_size.height = int(new_size.height / q);
aspect_ratio.y = (csize.height - new_size.height) / 2;
}
else if (q < 1.0)
{
new_size.width = int(new_size.width * q);
aspect_ratio.x = (csize.width - new_size.width) / 2;
}
}
aspect_ratio.size = new_size;
// Find the source image
const u32 absolute_address = rsx::get_address(display_buffers[info.buffer].offset, CELL_GCM_LOCATION_LOCAL);
GLuint image = GL_NONE;
@ -1722,8 +1722,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
const bool limited_range = !g_cfg.video.full_rgb_range_output;
gl::screen.bind();
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
m_video_output_pass.run(m_frame->client_width(), m_frame->client_height(), image, areai(aspect_ratio), gamma, limited_range);
m_video_output_pass.run(areau(aspect_ratio), image, gamma, limited_range);
}
}
@ -1749,14 +1748,13 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
if (m_overlay_manager->has_visible())
{
gl::screen.bind();
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
// Lock to avoid modification during run-update chain
std::lock_guard lock(*m_overlay_manager);
for (const auto& view : m_overlay_manager->get_views())
{
m_ui_renderer.run(m_frame->client_width(), m_frame->client_height(), 0, *view.get());
m_ui_renderer.run(areau(aspect_ratio), 0, *view.get());
}
}
}

View file

@ -132,7 +132,7 @@ namespace gl
glBindVertexArray(old_vao);
}
virtual void run(u16 w, u16 h, GLuint target_texture, bool depth_target, bool use_blending = false)
virtual void run(const areau& region, GLuint target_texture, bool depth_target, bool use_blending = false)
{
if (!compiled)
{
@ -198,7 +198,7 @@ namespace gl
}
// Set initial state
glViewport(0, 0, w, h);
glViewport(region.x1, region.y1, region.width(), region.height());
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(depth_target ? GL_TRUE : GL_FALSE);
@ -311,7 +311,7 @@ namespace gl
saved_sampler_state saved(31, m_sampler);
glBindTexture(GL_TEXTURE_2D, source->id());
overlay_pass::run(dst_area.x2, dst_area.y2, target->id(), true);
overlay_pass::run(dst_area, target->id(), true);
}
};
@ -341,12 +341,12 @@ namespace gl
"}\n";
}
void run(u16 w, u16 h, GLuint target, GLuint source)
void run(const areau& viewport, GLuint target, GLuint source)
{
saved_sampler_state saved(31, m_sampler);
glBindTexture(GL_TEXTURE_2D, source);
overlay_pass::run(w, h, target, false);
overlay_pass::run(viewport, target, false);
}
};
@ -608,9 +608,9 @@ namespace gl
}
}
void run(u16 w, u16 h, GLuint target, rsx::overlays::overlay& ui)
void run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui)
{
program_handle.uniforms["viewport"] = color2f(f32(w), f32(h));
program_handle.uniforms["viewport"] = color2f((f32)viewport.width(), (f32)viewport.height());
program_handle.uniforms["ui_scale"] = color4f((f32)ui.virtual_width, (f32)ui.virtual_height, 1.f, 1.f);
program_handle.uniforms["time"] = (f32)(get_system_time() / 1000) * 0.005f;
@ -658,7 +658,7 @@ namespace gl
program_handle.uniforms["blur_strength"] = (s32)cmd.config.blur_strength;
program_handle.uniforms["clip_region"] = (s32)cmd.config.clip_region;
program_handle.uniforms["clip_bounds"] = cmd.config.clip_rect;
overlay_pass::run(w, h, target, false, true);
overlay_pass::run(viewport, target, false, true);
}
ui.update();
@ -672,17 +672,13 @@ namespace gl
vs_src =
"#version 420\n\n"
"layout(location=0) out vec2 tc0;\n"
"uniform float x_scale;\n"
"uniform float y_scale;\n"
"uniform float x_offset;\n"
"uniform float y_offset;\n"
"\n"
"void main()\n"
"{\n"
" vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n"
" vec2 coords[] = {vec2(0., 1.), vec2(1., 1.), vec2(0., 0.), vec2(1., 0.)};\n"
" tc0 = coords[gl_VertexID % 4];\n"
" vec2 pos = positions[gl_VertexID % 4] * vec2(x_scale, y_scale) + (2. * vec2(x_offset, y_offset));\n"
" vec2 pos = positions[gl_VertexID % 4];\n"
" gl_Position = vec4(pos, 0., 1.);\n"
"}\n";
@ -708,23 +704,14 @@ namespace gl
input_filter = GL_LINEAR;
}
void run(u16 w, u16 h, GLuint source, const areai& region, f32 gamma, bool limited_rgb)
void run(const areau& viewport, GLuint source, f32 gamma, bool limited_rgb)
{
const f32 x_scale = (f32)(region.x2 - region.x1) / w;
const f32 y_scale = (f32)(region.y2 - region.y1) / h;
const f32 x_offset = (f32)(region.x1) / w;
const f32 y_offset = (f32)(region.y1) / h;
program_handle.uniforms["x_scale"] = x_scale;
program_handle.uniforms["y_scale"] = y_scale;
program_handle.uniforms["x_offset"] = x_offset;
program_handle.uniforms["y_offset"] = y_offset;
program_handle.uniforms["gamma"] = gamma;
program_handle.uniforms["limit_range"] = (int)limited_rgb;
saved_sampler_state saved(31, m_sampler);
glBindTexture(GL_TEXTURE_2D, source);
overlay_pass::run(w, h, GL_NONE, false, false);
overlay_pass::run(viewport, GL_NONE, false, false);
}
};
}

View file

@ -2023,8 +2023,7 @@ void VKGSRender::clear_surface(u32 mask)
renderpass = vk::get_renderpass(*m_device, key);
}
m_attachment_clear_pass->run(*m_current_command_buffer, rtt,
region.rect, renderpass);
m_attachment_clear_pass->run(*m_current_command_buffer, rtt, region.rect, renderpass);
rtt->change_layout(*m_current_command_buffer, old_layout);
}
@ -3425,7 +3424,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
for (const auto& view : m_overlay_manager->get_views())
{
m_ui_renderer->run(*m_current_command_buffer, direct_fbo->width(), direct_fbo->height(), direct_fbo, single_target_pass, m_texture_upload_buffer_ring_info, *view.get());
m_ui_renderer->run(*m_current_command_buffer, areau(aspect_ratio), direct_fbo, single_target_pass, m_texture_upload_buffer_ring_info, *view.get());
}
}

View file

@ -327,51 +327,53 @@ namespace vk
vkCmdDraw(cmd, num_drawable_elements, 1, first_vertex, 0);
}
virtual void set_up_viewport(vk::command_buffer &cmd, u16 max_w, u16 max_h)
virtual void set_up_viewport(vk::command_buffer &cmd, u32 x, u32 y, u32 w, u32 h)
{
VkViewport vp{};
vp.width = (f32)max_w;
vp.height = (f32)max_h;
vp.x = (f32)x;
vp.y = (f32)y;
vp.width = (f32)w;
vp.height = (f32)h;
vp.minDepth = 0.f;
vp.maxDepth = 1.f;
vkCmdSetViewport(cmd, 0, 1, &vp);
VkRect2D vs = { { 0, 0 }, { 0u + max_w, 0u + max_h } };
VkRect2D vs = { { (s32)x, (s32)y }, { w, h } };
vkCmdSetScissor(cmd, 0, 1, &vs);
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* fbo, const std::vector<vk::image_view*>& src, VkRenderPass render_pass)
void run(vk::command_buffer &cmd, const areau& viewport, vk::framebuffer* fbo, const std::vector<vk::image_view*>& src, VkRenderPass render_pass)
{
load_program(cmd, render_pass, src);
set_up_viewport(cmd, w, h);
set_up_viewport(cmd, viewport.x1, viewport.y1, viewport.width(), viewport.height());
VkRenderPassBeginInfo rp_begin = {};
rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rp_begin.renderPass = render_pass;
rp_begin.framebuffer = fbo->value;
rp_begin.renderArea.offset.x = 0;
rp_begin.renderArea.offset.y = 0;
rp_begin.renderArea.extent.width = w;
rp_begin.renderArea.extent.height = h;
rp_begin.renderArea.offset.x = (s32)viewport.x1;
rp_begin.renderArea.offset.y = (s32)viewport.y1;
rp_begin.renderArea.extent.width = viewport.width();
rp_begin.renderArea.extent.height = viewport.height();
vkCmdBeginRenderPass(cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
emit_geometry(cmd);
vkCmdEndRenderPass(cmd);
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, const std::vector<vk::image_view*>& src, VkRenderPass render_pass)
void run(vk::command_buffer &cmd, const areau& viewport, vk::image* target, const std::vector<vk::image_view*>& src, VkRenderPass render_pass)
{
auto fbo = static_cast<vk::framebuffer_holder*>(get_framebuffer(target, render_pass));
fbo->add_ref();
run(cmd, w, h, fbo, src, render_pass);
run(cmd, viewport, fbo, src, render_pass);
fbo->release();
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, vk::image_view* src, VkRenderPass render_pass)
void run(vk::command_buffer &cmd, const areau& viewport, vk::image* target, vk::image_view* src, VkRenderPass render_pass)
{
std::vector<vk::image_view*> views = { src };
run(cmd, w, h, target, views, render_pass);
run(cmd, viewport, target, views, render_pass);
}
};
@ -433,7 +435,7 @@ namespace vk
src_scale_x = f32(src_area.x2) / real_src->width();
src_scale_y = f32(src_area.y2) / real_src->height();
overlay_pass::run(cmd, dst_area.x2, dst_area.y2, dst, src, render_pass);
overlay_pass::run(cmd, dst_area, dst, src, render_pass);
}
};
@ -756,12 +758,12 @@ namespace vk
}
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* target, VkRenderPass render_pass,
void run(vk::command_buffer &cmd, const areau& viewport, vk::framebuffer* target, VkRenderPass render_pass,
vk::data_heap &upload_heap, rsx::overlays::overlay &ui)
{
m_scale_offset = color4f((f32)ui.virtual_width, (f32)ui.virtual_height, 1.f, 1.f);
m_time = (f32)(get_system_time() / 1000) * 0.005f;
m_viewport_size = { f32(w), f32(h) };
m_viewport_size = { f32(viewport.width()), f32(viewport.height()) };
for (auto &command : ui.get_compiled().draw_commands)
{
@ -799,7 +801,7 @@ namespace vk
break;
}
overlay_pass::run(cmd, w, h, target, { src }, render_pass);
overlay_pass::run(cmd, viewport, target, { src }, render_pass);
}
ui.update();
@ -877,11 +879,13 @@ namespace vk
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data);
}
void set_up_viewport(vk::command_buffer &cmd, u16 max_w, u16 max_h) override
void set_up_viewport(vk::command_buffer &cmd, u32 x, u32 y, u32 w, u32 h) override
{
VkViewport vp{};
vp.width = (f32)max_w;
vp.height = (f32)max_h;
vp.x = (f32)x;
vp.y = (f32)y;
vp.width = (f32)w;
vp.height = (f32)h;
vp.minDepth = 0.f;
vp.maxDepth = 1.f;
vkCmdSetViewport(cmd, 0, 1, &vp);
@ -915,9 +919,8 @@ namespace vk
// Coverage sampling disabled, but actually report correct number of samples
renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false);
overlay_pass::run(cmd, target->width(), target->height(), target,
target->get_view(0xAAE4, rsx::default_remap_vector),
render_pass);
overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target,
target->get_view(0xAAE4, rsx::default_remap_vector), render_pass);
}
};
}

View file

@ -268,7 +268,7 @@ namespace vk
overlay_pass::run(
cmd,
(u16)resolve_image->width(), (u16)resolve_image->height(),
{ 0, 0, resolve_image->width(), resolve_image->height() },
resolve_image, src_view,
render_pass);
}
@ -299,7 +299,7 @@ namespace vk
overlay_pass::run(
cmd,
(u16)msaa_image->width(), (u16)msaa_image->height(),
{ 0, 0, msaa_image->width(), msaa_image->height() },
msaa_image, src_view,
render_pass);
}
@ -364,7 +364,7 @@ namespace vk
overlay_pass::run(
cmd,
(u16)resolve_image->width(), (u16)resolve_image->height(),
{ 0, 0, resolve_image->width(), resolve_image->height() },
resolve_image, stencil_view,
render_pass);
}
@ -432,7 +432,7 @@ namespace vk
overlay_pass::run(
cmd,
(u16)msaa_image->width(), (u16)msaa_image->height(),
{ 0, 0, msaa_image->width(), msaa_image->height() },
msaa_image, stencil_view,
render_pass);
}
@ -474,7 +474,7 @@ namespace vk
overlay_pass::run(
cmd,
(u16)resolve_image->width(), (u16)resolve_image->height(),
{ 0, 0, resolve_image->width(), resolve_image->height() },
resolve_image, { depth_view, stencil_view },
render_pass);
}
@ -519,7 +519,7 @@ namespace vk
overlay_pass::run(
cmd,
(u16)msaa_image->width(), (u16)msaa_image->height(),
{ 0, 0, msaa_image->width(), msaa_image->height() },
msaa_image, { depth_view, stencil_view },
render_pass);
}