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.
This commit is contained in:
kd-11 2020-02-08 20:55:47 +03:00 committed by kd-11
parent 7973b01b1c
commit 792c481f6d
2 changed files with 38 additions and 19 deletions

View File

@ -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<f32>(viewport.width()), static_cast<f32>(viewport.height()));
program_handle.uniforms["viewport"] = color4f(static_cast<f32>(viewport.width()), static_cast<f32>(viewport.height()), static_cast<f32>(viewport.x1), static_cast<f32>(viewport.y1));
program_handle.uniforms["ui_scale"] = color4f(static_cast<f32>(ui.virtual_width), static_cast<f32>(ui.virtual_height), 1.f, 1.f);
program_handle.uniforms["time"] = static_cast<f32>(get_system_time() / 1000) * 0.005f;

View File

@ -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<std::unique_ptr<vk::image>> resources;
std::unordered_map<u64, std::unique_ptr<vk::image>> 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<f32>(get_system_time() / 1000) * 0.005f;
m_viewport_size = { static_cast<f32>(viewport.width()), static_cast<f32>(viewport.height()) };
m_viewport = { { static_cast<f32>(viewport.x1), static_cast<f32>(viewport.y1) }, { static_cast<f32>(viewport.width()), static_cast<f32>(viewport.height()) } };
for (auto &command : ui.get_compiled().draw_commands)
{