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.bind();
gl::screen.clear(gl::buffers::color); 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) 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 // Find the source image
const u32 absolute_address = rsx::get_address(display_buffers[info.buffer].offset, CELL_GCM_LOCATION_LOCAL); const u32 absolute_address = rsx::get_address(display_buffers[info.buffer].offset, CELL_GCM_LOCATION_LOCAL);
GLuint image = GL_NONE; 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; const bool limited_range = !g_cfg.video.full_rgb_range_output;
gl::screen.bind(); gl::screen.bind();
glViewport(0, 0, m_frame->client_width(), m_frame->client_height()); m_video_output_pass.run(areau(aspect_ratio), image, gamma, limited_range);
m_video_output_pass.run(m_frame->client_width(), m_frame->client_height(), image, areai(aspect_ratio), gamma, limited_range);
} }
} }
@ -1749,14 +1748,13 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
if (m_overlay_manager->has_visible()) if (m_overlay_manager->has_visible())
{ {
gl::screen.bind(); gl::screen.bind();
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
// Lock to avoid modification during run-update chain // Lock to avoid modification during run-update chain
std::lock_guard lock(*m_overlay_manager); std::lock_guard lock(*m_overlay_manager);
for (const auto& view : m_overlay_manager->get_views()) 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); 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) if (!compiled)
{ {
@ -198,7 +198,7 @@ namespace gl
} }
// Set initial state // 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); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(depth_target ? GL_TRUE : GL_FALSE); glDepthMask(depth_target ? GL_TRUE : GL_FALSE);
@ -311,7 +311,7 @@ namespace gl
saved_sampler_state saved(31, m_sampler); saved_sampler_state saved(31, m_sampler);
glBindTexture(GL_TEXTURE_2D, source->id()); 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"; "}\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); saved_sampler_state saved(31, m_sampler);
glBindTexture(GL_TEXTURE_2D, source); 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["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; 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["blur_strength"] = (s32)cmd.config.blur_strength;
program_handle.uniforms["clip_region"] = (s32)cmd.config.clip_region; program_handle.uniforms["clip_region"] = (s32)cmd.config.clip_region;
program_handle.uniforms["clip_bounds"] = cmd.config.clip_rect; 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(); ui.update();
@ -672,17 +672,13 @@ namespace gl
vs_src = vs_src =
"#version 420\n\n" "#version 420\n\n"
"layout(location=0) out vec2 tc0;\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" "\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\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" " vec2 coords[] = {vec2(0., 1.), vec2(1., 1.), vec2(0., 0.), vec2(1., 0.)};\n"
" tc0 = coords[gl_VertexID % 4];\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" " gl_Position = vec4(pos, 0., 1.);\n"
"}\n"; "}\n";
@ -708,23 +704,14 @@ namespace gl
input_filter = GL_LINEAR; 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["gamma"] = gamma;
program_handle.uniforms["limit_range"] = (int)limited_rgb; program_handle.uniforms["limit_range"] = (int)limited_rgb;
saved_sampler_state saved(31, m_sampler); saved_sampler_state saved(31, m_sampler);
glBindTexture(GL_TEXTURE_2D, source); 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); renderpass = vk::get_renderpass(*m_device, key);
} }
m_attachment_clear_pass->run(*m_current_command_buffer, rtt, m_attachment_clear_pass->run(*m_current_command_buffer, rtt, region.rect, renderpass);
region.rect, renderpass);
rtt->change_layout(*m_current_command_buffer, old_layout); 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()) 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); 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{}; VkViewport vp{};
vp.width = (f32)max_w; vp.x = (f32)x;
vp.height = (f32)max_h; vp.y = (f32)y;
vp.width = (f32)w;
vp.height = (f32)h;
vp.minDepth = 0.f; vp.minDepth = 0.f;
vp.maxDepth = 1.f; vp.maxDepth = 1.f;
vkCmdSetViewport(cmd, 0, 1, &vp); 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); 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); 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 = {}; VkRenderPassBeginInfo rp_begin = {};
rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rp_begin.renderPass = render_pass; rp_begin.renderPass = render_pass;
rp_begin.framebuffer = fbo->value; rp_begin.framebuffer = fbo->value;
rp_begin.renderArea.offset.x = 0; rp_begin.renderArea.offset.x = (s32)viewport.x1;
rp_begin.renderArea.offset.y = 0; rp_begin.renderArea.offset.y = (s32)viewport.y1;
rp_begin.renderArea.extent.width = w; rp_begin.renderArea.extent.width = viewport.width();
rp_begin.renderArea.extent.height = h; rp_begin.renderArea.extent.height = viewport.height();
vkCmdBeginRenderPass(cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
emit_geometry(cmd); emit_geometry(cmd);
vkCmdEndRenderPass(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)); auto fbo = static_cast<vk::framebuffer_holder*>(get_framebuffer(target, render_pass));
fbo->add_ref(); fbo->add_ref();
run(cmd, w, h, fbo, src, render_pass); run(cmd, viewport, fbo, src, render_pass);
fbo->release(); 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 }; 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_x = f32(src_area.x2) / real_src->width();
src_scale_y = f32(src_area.y2) / real_src->height(); 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) 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_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_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) for (auto &command : ui.get_compiled().draw_commands)
{ {
@ -799,7 +801,7 @@ namespace vk
break; break;
} }
overlay_pass::run(cmd, w, h, target, { src }, render_pass); overlay_pass::run(cmd, viewport, target, { src }, render_pass);
} }
ui.update(); ui.update();
@ -877,11 +879,13 @@ namespace vk
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data); 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{}; VkViewport vp{};
vp.width = (f32)max_w; vp.x = (f32)x;
vp.height = (f32)max_h; vp.y = (f32)y;
vp.width = (f32)w;
vp.height = (f32)h;
vp.minDepth = 0.f; vp.minDepth = 0.f;
vp.maxDepth = 1.f; vp.maxDepth = 1.f;
vkCmdSetViewport(cmd, 0, 1, &vp); vkCmdSetViewport(cmd, 0, 1, &vp);
@ -915,9 +919,8 @@ namespace vk
// Coverage sampling disabled, but actually report correct number of samples // Coverage sampling disabled, but actually report correct number of samples
renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false); renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false);
overlay_pass::run(cmd, target->width(), target->height(), target, overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target,
target->get_view(0xAAE4, rsx::default_remap_vector), target->get_view(0xAAE4, rsx::default_remap_vector), render_pass);
render_pass);
} }
}; };
} }

View file

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