From 792c481f6d33ab6862102830f28eb19bebb26029 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 8 Feb 2020 20:55:47 +0300 Subject: [PATCH] rsx/overlays: Fix clipped rendering of UI elements - Take viewport offset into account when applying window transforms. This is necessary because gl_FragCoord is based on the framebuffer and not the viewport. --- rpcs3/Emu/RSX/GL/GLOverlays.h | 28 ++++++++++++++++++---------- rpcs3/Emu/RSX/VK/VKOverlays.h | 29 ++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 94a3d3a0f7..44f3b45133 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -368,24 +368,32 @@ namespace gl "layout(location=0) out vec2 tc0;\n" "layout(location=1) flat out vec4 clip_rect;\n" "uniform vec4 ui_scale;\n" - "uniform vec2 viewport;\n" + "uniform vec4 viewport;\n" "uniform vec4 clip_bounds;\n" "\n" "vec2 snap_to_grid(vec2 normalized)\n" "{\n" - " return (floor(normalized * viewport) + 0.5) / viewport;\n" + " return (floor(normalized * viewport.xy) + 0.5) / viewport.xy;\n" + "}\n" + "\n" + "vec4 clip_to_ndc(const in vec4 coord)\n" + "{\n" + " vec4 ret = (coord * ui_scale.zwzw) / ui_scale.xyxy;\n" + " ret.yw = 1. - ret.yw;\n" + " return ret;\n" + "}\n" + "\n" + "vec4 ndc_to_window(const in vec4 coord)\n" + "{\n" + " return fma(coord, viewport.xyxy, viewport.zwzw);\n" "}\n" "\n" "void main()\n" "{\n" " tc0.xy = in_pos.zw;\n" - " clip_rect = clip_bounds;\n" - " clip_rect.yw = ui_scale.yy - clip_rect.wy; // Invert y axis\n" - " clip_rect *= (ui_scale.zwzw * viewport.xyxy) / ui_scale.xyxy; // Normalize and convert to window coords\n" - " vec2 window_coord = (in_pos.xy * ui_scale.zw) / ui_scale.xy;\n" - " window_coord = snap_to_grid(window_coord); // Half-integer offset\n" - " window_coord.y = (1. - window_coord.y); // Invert y axis\n" - " vec4 pos = vec4(window_coord, 0., 1.);\n" + " clip_rect = ndc_to_window(clip_to_ndc(clip_bounds)).xwzy; // Swap y1 and y2 due to flipped origin!\n" + " vec4 pos = vec4(clip_to_ndc(in_pos).xy, 0.5, 1.);\n" + " pos.xy = snap_to_grid(pos.xy);\n" " gl_Position = (pos + pos) - 1.;\n" "}\n"; @@ -632,7 +640,7 @@ namespace gl void run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui) { - program_handle.uniforms["viewport"] = color2f(static_cast(viewport.width()), static_cast(viewport.height())); + program_handle.uniforms["viewport"] = color4f(static_cast(viewport.width()), static_cast(viewport.height()), static_cast(viewport.x1), static_cast(viewport.y1)); program_handle.uniforms["ui_scale"] = color4f(static_cast(ui.virtual_width), static_cast(ui.virtual_height), 1.f, 1.f); program_handle.uniforms["time"] = static_cast(get_system_time() / 1000) * 0.005f; diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index c4cd588647..5ebc3af10f 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -476,7 +476,7 @@ namespace vk bool m_clip_enabled = false; int m_texture_type; areaf m_clip_region; - size2f m_viewport_size; + coordf m_viewport; std::vector> resources; std::unordered_map> font_cache; @@ -498,20 +498,29 @@ namespace vk "layout(location=3) out vec4 clip_rect;\n" "layout(location=4) out vec4 parameters2;\n" "\n" - "vec2 snap_to_grid(vec2 normalized)\n" + "vec2 snap_to_grid(const in vec2 normalized)\n" "{\n" " return (floor(normalized * regs[5].xy) + 0.5) / regs[5].xy;\n" "}\n" "\n" + "vec4 clip_to_ndc(const in vec4 coord)\n" + "{\n" + " return (coord * regs[0].zwzw) / regs[0].xyxy;\n" + "}\n" + "\n" + "vec4 ndc_to_window(const in vec4 coord)\n" + "{\n" + " return fma(coord, regs[5].xyxy, regs[5].zwzw);\n" + "}\n" + "\n" "void main()\n" "{\n" " tc0.xy = in_pos.zw;\n" " color = regs[1];\n" " parameters = regs[2];\n" " parameters2 = regs[4];\n" - " clip_rect = (regs[3] * regs[0].zwzw) / regs[0].xyxy; // Normalized coords\n" - " clip_rect *= regs[5].xyxy; // Window coords\n" - " vec4 pos = vec4((in_pos.xy * regs[0].zw) / regs[0].xy, 0.5, 1.);\n" + " clip_rect = ndc_to_window(clip_to_ndc(regs[3]));\n" + " vec4 pos = vec4(clip_to_ndc(in_pos).xy, 0.5, 1.);\n" " pos.xy = snap_to_grid(pos.xy);\n" " gl_Position = (pos + pos) - 1.;\n" "}\n"; @@ -768,9 +777,11 @@ namespace vk // regs[4] = fs config parameters 2 dst[16] = m_blur_strength; - // regs[5] = viewport size - dst[20] = m_viewport_size.width; - dst[21] = m_viewport_size.height; + // regs[5] = viewport + dst[20] = m_viewport.width; + dst[21] = m_viewport.height; + dst[22] = m_viewport.x; + dst[23] = m_viewport.y; m_ubo.unmap(); } @@ -821,7 +832,7 @@ namespace vk { m_scale_offset = color4f(ui.virtual_width, ui.virtual_height, 1.f, 1.f); m_time = static_cast(get_system_time() / 1000) * 0.005f; - m_viewport_size = { static_cast(viewport.width()), static_cast(viewport.height()) }; + m_viewport = { { static_cast(viewport.x1), static_cast(viewport.y1) }, { static_cast(viewport.width()), static_cast(viewport.height()) } }; for (auto &command : ui.get_compiled().draw_commands) {