GPUDevice: Fix incorrect positioning with PostFX and GL

This commit is contained in:
Stenzek 2023-12-10 23:26:43 +10:00
parent 27162e34a0
commit 39913b2a39
No known key found for this signature in database
5 changed files with 33 additions and 35 deletions

View file

@ -1722,6 +1722,8 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
const u32 target_height = target ? target->GetHeight() : g_gpu_device->GetWindowHeight(); const u32 target_height = target ? target->GetHeight() : g_gpu_device->GetWindowHeight();
const bool really_postfx = (postfx && HasDisplayTexture() && PostProcessing::IsActive() && const bool really_postfx = (postfx && HasDisplayTexture() && PostProcessing::IsActive() &&
PostProcessing::CheckTargets(hdformat, target_width, target_height)); PostProcessing::CheckTargets(hdformat, target_width, target_height));
const Common::Rectangle<s32> real_draw_rect =
g_gpu_device->UsesLowerLeftOrigin() ? GPUDevice::FlipToLowerLeft(draw_rect, target_height) : draw_rect;
if (really_postfx) if (really_postfx)
{ {
g_gpu_device->ClearRenderTarget(PostProcessing::GetInputTexture(), 0); g_gpu_device->ClearRenderTarget(PostProcessing::GetInputTexture(), 0);
@ -1762,13 +1764,15 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
uniforms.src_size[3] = rcp_height; uniforms.src_size[3] = rcp_height;
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms)); g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
g_gpu_device->SetViewportAndScissor(draw_rect.left, draw_rect.top, draw_rect.GetWidth(), draw_rect.GetHeight()); g_gpu_device->SetViewportAndScissor(real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
real_draw_rect.GetHeight());
g_gpu_device->Draw(3, 0); g_gpu_device->Draw(3, 0);
if (really_postfx) if (really_postfx)
{ {
return PostProcessing::Apply(target, draw_rect.left, draw_rect.top, draw_rect.GetWidth(), draw_rect.GetHeight(), return PostProcessing::Apply(target, real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
m_display_texture_view_width, m_display_texture_view_height); real_draw_rect.GetHeight(), m_display_texture_view_width,
m_display_texture_view_height);
} }
else else
{ {

View file

@ -529,6 +529,7 @@ void GPUDevice::RenderImGui()
PushUniformBuffer(ortho_projection, sizeof(ortho_projection)); PushUniformBuffer(ortho_projection, sizeof(ortho_projection));
// Render command lists // Render command lists
const bool flip = UsesLowerLeftOrigin();
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
@ -546,9 +547,21 @@ void GPUDevice::RenderImGui()
if (pcmd->ElemCount == 0 || pcmd->ClipRect.z <= pcmd->ClipRect.x || pcmd->ClipRect.w <= pcmd->ClipRect.y) if (pcmd->ElemCount == 0 || pcmd->ClipRect.z <= pcmd->ClipRect.x || pcmd->ClipRect.w <= pcmd->ClipRect.y)
continue; continue;
SetScissor(static_cast<s32>(pcmd->ClipRect.x), static_cast<s32>(pcmd->ClipRect.y), if (flip)
static_cast<s32>(pcmd->ClipRect.z - pcmd->ClipRect.x), {
static_cast<s32>(pcmd->ClipRect.w - pcmd->ClipRect.y)); const s32 height = static_cast<s32>(pcmd->ClipRect.w - pcmd->ClipRect.y);
const s32 flipped_y =
static_cast<s32>(m_window_info.surface_height) - static_cast<s32>(pcmd->ClipRect.y) - height;
SetScissor(static_cast<s32>(pcmd->ClipRect.x), flipped_y, static_cast<s32>(pcmd->ClipRect.z - pcmd->ClipRect.x),
flipped_y + height);
}
else
{
SetScissor(static_cast<s32>(pcmd->ClipRect.x), static_cast<s32>(pcmd->ClipRect.y),
static_cast<s32>(pcmd->ClipRect.z - pcmd->ClipRect.x),
static_cast<s32>(pcmd->ClipRect.w - pcmd->ClipRect.y));
}
SetTextureSampler(0, reinterpret_cast<GPUTexture*>(pcmd->TextureId), m_linear_sampler.get()); SetTextureSampler(0, reinterpret_cast<GPUTexture*>(pcmd->TextureId), m_linear_sampler.get());
DrawIndexed(pcmd->ElemCount, base_index + pcmd->IdxOffset, base_vertex + pcmd->VtxOffset); DrawIndexed(pcmd->ElemCount, base_index + pcmd->IdxOffset, base_vertex + pcmd->VtxOffset);
} }
@ -743,6 +756,13 @@ bool GPUDevice::UsesLowerLeftOrigin() const
return (api == RenderAPI::OpenGL || api == RenderAPI::OpenGLES); return (api == RenderAPI::OpenGL || api == RenderAPI::OpenGLES);
} }
Common::Rectangle<s32> GPUDevice::FlipToLowerLeft(const Common::Rectangle<s32>& rc, s32 target_height)
{
const s32 height = rc.GetHeight();
const s32 flipped_y = target_height - rc.top - height;
return Common::Rectangle<s32>(rc.left, flipped_y, rc.right, flipped_y + height);
}
std::unique_ptr<GPUTexture> GPUDevice::FetchTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, std::unique_ptr<GPUTexture> GPUDevice::FetchTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
GPUTexture::Type type, GPUTexture::Format format, GPUTexture::Type type, GPUTexture::Format format,
const void* data /*= nullptr*/, u32 data_stride /*= 0*/) const void* data /*= nullptr*/, u32 data_stride /*= 0*/)

View file

@ -630,6 +630,7 @@ public:
bool UpdateImGuiFontTexture(); bool UpdateImGuiFontTexture();
bool UsesLowerLeftOrigin() const; bool UsesLowerLeftOrigin() const;
static Common::Rectangle<s32> FlipToLowerLeft(const Common::Rectangle<s32>& rc, s32 target_height);
void SetDisplayMaxFPS(float max_fps); void SetDisplayMaxFPS(float max_fps);
bool ShouldSkipDisplayingFrame(); bool ShouldSkipDisplayingFrame();
void ThrottlePresentation(); void ThrottlePresentation();

View file

@ -1193,38 +1193,12 @@ void OpenGLDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
UpdateScissor(); UpdateScissor();
} }
std::tuple<s32, s32, s32, s32> OpenGLDevice::GetFlippedViewportScissor(const Common::Rectangle<s32>& rc) const
{
// Only when rendering to window framebuffer.
// We draw everything else upside-down.
s32 x, y, width, height;
if (m_current_fbo == 0)
{
const s32 sh = static_cast<s32>(m_window_info.surface_height);
const s32 rh = rc.GetHeight();
x = rc.left;
y = sh - rc.top - rh;
width = rc.GetWidth();
height = rh;
}
else
{
x = rc.left;
y = rc.top;
width = rc.GetWidth();
height = rc.GetHeight();
}
return std::tie(x, y, width, height);
}
void OpenGLDevice::UpdateViewport() void OpenGLDevice::UpdateViewport()
{ {
const auto& [x, y, width, height] = GetFlippedViewportScissor(m_last_viewport); glViewport(m_last_viewport.left, m_last_viewport.top, m_last_viewport.GetWidth(), m_last_viewport.GetHeight());
glViewport(x, y, width, height);
} }
void OpenGLDevice::UpdateScissor() void OpenGLDevice::UpdateScissor()
{ {
const auto& [x, y, width, height] = GetFlippedViewportScissor(m_last_scissor); glScissor(m_last_scissor.left, m_last_scissor.top, m_last_scissor.GetWidth(), m_last_scissor.GetHeight());
glScissor(x, y, width, height);
} }

View file

@ -147,7 +147,6 @@ private:
static GLuint CreateFramebuffer(GPUTexture* const* rts, u32 num_rts, GPUTexture* ds, u32 flags); static GLuint CreateFramebuffer(GPUTexture* const* rts, u32 num_rts, GPUTexture* ds, u32 flags);
static void DestroyFramebuffer(GLuint fbo); static void DestroyFramebuffer(GLuint fbo);
std::tuple<s32, s32, s32, s32> GetFlippedViewportScissor(const Common::Rectangle<s32>& rc) const;
void UpdateViewport(); void UpdateViewport();
void UpdateScissor(); void UpdateScissor();