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 bool really_postfx = (postfx && HasDisplayTexture() && PostProcessing::IsActive() &&
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)
{
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;
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);
if (really_postfx)
{
return PostProcessing::Apply(target, draw_rect.left, draw_rect.top, draw_rect.GetWidth(), draw_rect.GetHeight(),
m_display_texture_view_width, m_display_texture_view_height);
return PostProcessing::Apply(target, real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
real_draw_rect.GetHeight(), m_display_texture_view_width,
m_display_texture_view_height);
}
else
{

View file

@ -529,6 +529,7 @@ void GPUDevice::RenderImGui()
PushUniformBuffer(ortho_projection, sizeof(ortho_projection));
// Render command lists
const bool flip = UsesLowerLeftOrigin();
for (int n = 0; n < draw_data->CmdListsCount; 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)
continue;
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));
if (flip)
{
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());
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);
}
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,
GPUTexture::Type type, GPUTexture::Format format,
const void* data /*= nullptr*/, u32 data_stride /*= 0*/)

View file

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

View file

@ -1193,38 +1193,12 @@ void OpenGLDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
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()
{
const auto& [x, y, width, height] = GetFlippedViewportScissor(m_last_viewport);
glViewport(x, y, width, height);
glViewport(m_last_viewport.left, m_last_viewport.top, m_last_viewport.GetWidth(), m_last_viewport.GetHeight());
}
void OpenGLDevice::UpdateScissor()
{
const auto& [x, y, width, height] = GetFlippedViewportScissor(m_last_scissor);
glScissor(x, y, width, height);
glScissor(m_last_scissor.left, m_last_scissor.top, m_last_scissor.GetWidth(), m_last_scissor.GetHeight());
}

View file

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