diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index bc09e3293..4719bb989 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -1722,6 +1722,8 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle& 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 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& 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 { diff --git a/src/util/gpu_device.cpp b/src/util/gpu_device.cpp index 5ec980b23..1ec903191 100644 --- a/src/util/gpu_device.cpp +++ b/src/util/gpu_device.cpp @@ -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(pcmd->ClipRect.x), static_cast(pcmd->ClipRect.y), - static_cast(pcmd->ClipRect.z - pcmd->ClipRect.x), - static_cast(pcmd->ClipRect.w - pcmd->ClipRect.y)); + if (flip) + { + const s32 height = static_cast(pcmd->ClipRect.w - pcmd->ClipRect.y); + const s32 flipped_y = + static_cast(m_window_info.surface_height) - static_cast(pcmd->ClipRect.y) - height; + SetScissor(static_cast(pcmd->ClipRect.x), flipped_y, static_cast(pcmd->ClipRect.z - pcmd->ClipRect.x), + flipped_y + height); + } + else + { + SetScissor(static_cast(pcmd->ClipRect.x), static_cast(pcmd->ClipRect.y), + static_cast(pcmd->ClipRect.z - pcmd->ClipRect.x), + static_cast(pcmd->ClipRect.w - pcmd->ClipRect.y)); + } + SetTextureSampler(0, reinterpret_cast(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 GPUDevice::FlipToLowerLeft(const Common::Rectangle& rc, s32 target_height) +{ + const s32 height = rc.GetHeight(); + const s32 flipped_y = target_height - rc.top - height; + return Common::Rectangle(rc.left, flipped_y, rc.right, flipped_y + height); +} + std::unique_ptr 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*/) diff --git a/src/util/gpu_device.h b/src/util/gpu_device.h index 6af36d9b6..6c032d4c8 100644 --- a/src/util/gpu_device.h +++ b/src/util/gpu_device.h @@ -630,6 +630,7 @@ public: bool UpdateImGuiFontTexture(); bool UsesLowerLeftOrigin() const; + static Common::Rectangle FlipToLowerLeft(const Common::Rectangle& rc, s32 target_height); void SetDisplayMaxFPS(float max_fps); bool ShouldSkipDisplayingFrame(); void ThrottlePresentation(); diff --git a/src/util/opengl_device.cpp b/src/util/opengl_device.cpp index 7a408db78..1fd9eb380 100644 --- a/src/util/opengl_device.cpp +++ b/src/util/opengl_device.cpp @@ -1193,38 +1193,12 @@ void OpenGLDevice::SetScissor(s32 x, s32 y, s32 width, s32 height) UpdateScissor(); } -std::tuple OpenGLDevice::GetFlippedViewportScissor(const Common::Rectangle& 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(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()); } diff --git a/src/util/opengl_device.h b/src/util/opengl_device.h index 47b2d73e4..ef1abb1a4 100644 --- a/src/util/opengl_device.h +++ b/src/util/opengl_device.h @@ -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 GetFlippedViewportScissor(const Common::Rectangle& rc) const; void UpdateViewport(); void UpdateScissor();