mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
rsx: Properly scale overlay passes to match drawable area
This commit is contained in:
parent
28534e8833
commit
2275259bf5
6 changed files with 75 additions and 87 deletions
|
@ -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) }
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue