GL: flip overlays vertically during recordings

This commit is contained in:
Megamouse 2025-10-17 09:37:42 +02:00
parent e4ae5bdce1
commit 9124d08fdb
6 changed files with 40 additions and 15 deletions

View file

@ -395,7 +395,7 @@ namespace gl
} }
} }
void ui_overlay_renderer::run(gl::command_context& cmd_, const areau& viewport, GLuint target, rsx::overlays::overlay& ui) void ui_overlay_renderer::run(gl::command_context& cmd_, const areau& viewport, GLuint target, rsx::overlays::overlay& ui, bool flip_vertically)
{ {
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["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["ui_scale"] = color4f(static_cast<f32>(ui.virtual_width), static_cast<f32>(ui.virtual_height), 1.f, 1.f);
@ -445,12 +445,13 @@ namespace gl
} }
} }
rsx::overlays::vertex_options vert_opts; rsx::overlays::vertex_options vert_opts {};
program_handle.uniforms["vertex_config"] = vert_opts program_handle.uniforms["vertex_config"] = vert_opts
.disable_vertex_snap(cmd.config.disable_vertex_snap) .disable_vertex_snap(cmd.config.disable_vertex_snap)
.enable_vertical_flip(flip_vertically)
.get(); .get();
rsx::overlays::fragment_options draw_opts; rsx::overlays::fragment_options draw_opts {};
program_handle.uniforms["fragment_config"] = draw_opts program_handle.uniforms["fragment_config"] = draw_opts
.texture_mode(texture_mode) .texture_mode(texture_mode)
.clip_fragments(cmd.config.clip_region) .clip_fragments(cmd.config.clip_region)

View file

@ -90,7 +90,7 @@ namespace gl
void emit_geometry(gl::command_context& cmd) override; void emit_geometry(gl::command_context& cmd) override;
void run(gl::command_context& cmd, const areau& viewport, GLuint target, rsx::overlays::overlay& ui); void run(gl::command_context& cmd, const areau& viewport, GLuint target, rsx::overlays::overlay& ui, bool flip_vertically);
}; };
struct video_out_calibration_pass final : public overlay_pass struct video_out_calibration_pass final : public overlay_pass

View file

@ -294,7 +294,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
m_overlay_manager->dispose(uids_to_dispose); m_overlay_manager->dispose(uids_to_dispose);
} }
const auto render_overlays = [this, &cmd](gl::texture* dst, const areau& aspect_ratio) const auto render_overlays = [this, &cmd](gl::texture* dst, const areau& aspect_ratio, bool flip_vertically = false)
{ {
if (m_overlay_manager && m_overlay_manager->has_visible()) if (m_overlay_manager && m_overlay_manager->has_visible())
{ {
@ -316,7 +316,7 @@ void GLGSRender::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(cmd, aspect_ratio, target, *view.get()); m_ui_renderer.run(cmd, aspect_ratio, target, *view.get(), flip_vertically);
} }
} }
}; };
@ -359,7 +359,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
static const position3u offset{}; static const position3u offset{};
gl::g_hw_blitter->copy_image(cmd, image_to_flip, tex, 0, 0, offset, offset, { tex->width(), tex->height(), 1 }); gl::g_hw_blitter->copy_image(cmd, image_to_flip, tex, 0, 0, offset, offset, { tex->width(), tex->height(), 1 });
render_overlays(tex, areau(0, 0, image_to_flip->width(), image_to_flip->height())); render_overlays(tex, areau(0, 0, image_to_flip->width(), image_to_flip->height()), true);
m_sshot_fbo.remove(); m_sshot_fbo.remove();
} }

View file

@ -33,12 +33,14 @@ layout(%push_block) uniform Configuration
struct config_t struct config_t
{ {
bool no_vertex_snap; bool no_vertex_snap;
bool flip_vertically;
}; };
config_t unpack_vertex_options() config_t unpack_vertex_options()
{ {
config_t result; config_t result;
result.no_vertex_snap = bitfieldExtract(vertex_config, 0, 1) != 0; result.no_vertex_snap = bitfieldExtract(vertex_config, 0, 1) != 0;
result.flip_vertically = bitfieldExtract(vertex_config, 1, 1) != 0;
return result; return result;
} }
@ -47,12 +49,14 @@ vec2 snap_to_grid(const in vec2 normalized)
return floor(fma(normalized, viewport.xy, vec2(0.5))) / viewport.xy; return floor(fma(normalized, viewport.xy, vec2(0.5))) / viewport.xy;
} }
vec4 clip_to_ndc(const in vec4 coord) vec4 clip_to_ndc(const in vec4 coord, const in bool flip_vertically)
{ {
vec4 ret = (coord * ui_scale.zwzw) / ui_scale.xyxy; vec4 ret = (coord * ui_scale.zwzw) / ui_scale.xyxy;
#ifndef VULKAN #ifndef VULKAN
// Flip Y for OpenGL // Flip Y for OpenGL
ret.yw = 1. - ret.yw; if (!flip_vertically) ret.yw = 1. - ret.yw;
#else
if (flip_vertically) ret.yw = 1. - ret.yw;
#endif #endif
return ret; return ret;
} }
@ -64,12 +68,13 @@ vec4 ndc_to_window(const in vec4 coord)
void main() void main()
{ {
config_t config = unpack_vertex_options();
tc0.xy = in_pos.zw; tc0.xy = in_pos.zw;
color = albedo; color = albedo;
clip_rect = ndc_to_window(clip_to_ndc(clip_bounds)); clip_rect = ndc_to_window(clip_to_ndc(clip_bounds, config.flip_vertically));
vec4 pos = vec4(clip_to_ndc(in_pos).xy, 0.5, 1.); vec4 pos = vec4(clip_to_ndc(in_pos, config.flip_vertically).xy, 0.5, 1.);
config_t config = unpack_vertex_options();
if (!config.no_vertex_snap) if (!config.no_vertex_snap)
{ {

View file

@ -59,12 +59,31 @@ namespace rsx
class vertex_options class vertex_options
{ {
private:
u32 value = 0; u32 value = 0;
void set_bit(u32 bit, bool enable)
{
if (enable)
{
value |= (1u << bit);
}
else
{
value &= ~(1u << bit);
}
}
public: public:
vertex_options& disable_vertex_snap(bool enable) vertex_options& disable_vertex_snap(bool enable)
{ {
value = enable ? 1 : 0; set_bit(0, enable);
return *this;
}
vertex_options& enable_vertical_flip(bool enable)
{
set_bit(1, enable);
return *this; return *this;
} }

View file

@ -543,7 +543,7 @@ namespace vk
push_buf[14] = m_clip_region.x2; push_buf[14] = m_clip_region.x2;
push_buf[15] = m_clip_region.y2; push_buf[15] = m_clip_region.y2;
rsx::overlays::vertex_options vert_opts; rsx::overlays::vertex_options vert_opts {};
const auto vert_config = vert_opts const auto vert_config = vert_opts
.disable_vertex_snap(m_disable_vertex_snap) .disable_vertex_snap(m_disable_vertex_snap)
.get(); .get();
@ -552,7 +552,7 @@ namespace vk
vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_VERTEX_BIT, 0, 68, push_buf); vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_VERTEX_BIT, 0, 68, push_buf);
// 2. Fragment stuff // 2. Fragment stuff
rsx::overlays::fragment_options frag_opts; rsx::overlays::fragment_options frag_opts {};
const auto frag_config = frag_opts const auto frag_config = frag_opts
.texture_mode(m_texture_type) .texture_mode(m_texture_type)
.clip_fragments(m_clip_enabled) .clip_fragments(m_clip_enabled)