diff --git a/Source/Core/VideoCommon/AbstractGfx.cpp b/Source/Core/VideoCommon/AbstractGfx.cpp index 0e7e05e0f00..3e31468f783 100644 --- a/Source/Core/VideoCommon/AbstractGfx.cpp +++ b/Source/Core/VideoCommon/AbstractGfx.cpp @@ -34,10 +34,15 @@ void AbstractGfx::BeginUtilityDrawing() void AbstractGfx::EndUtilityDrawing() { - // Reset framebuffer/scissor/viewport. Pipeline will be reset at next draw. + // Reset framebuffer. Pipeline will be reset at next draw. g_framebuffer_manager->BindEFBFramebuffer(); - BPFunctions::SetScissorAndViewport(g_framebuffer_manager.get(), bpmem.scissorTL, bpmem.scissorBR, - bpmem.scissorOffset, xfmem.viewport); + + // Reset our viewport and scissor to the last stored value + SetViewport(m_viewport_and_scissor.viewport_x, m_viewport_and_scissor.viewport_y, + m_viewport_and_scissor.viewport_width, m_viewport_and_scissor.viewport_height, + m_viewport_and_scissor.viewport_near_depth, + m_viewport_and_scissor.viewport_far_depth); + SetScissorRect(m_viewport_and_scissor.scissor_rect); } void AbstractGfx::SetFramebuffer(AbstractFramebuffer* framebuffer) @@ -87,6 +92,11 @@ void AbstractGfx::ClearRegion(const MathUtil::Rectangle& target_rc, bool co EndUtilityDrawing(); } +void AbstractGfx::StoreViewportAndScissor(const ViewportAndScissor& viewport_and_scissor) +{ + m_viewport_and_scissor = viewport_and_scissor; +} + void AbstractGfx::SetViewportAndScissor(const MathUtil::Rectangle& rect, float min_depth, float max_depth) { diff --git a/Source/Core/VideoCommon/AbstractGfx.h b/Source/Core/VideoCommon/AbstractGfx.h index d9d14e1a120..b1528b3bb12 100644 --- a/Source/Core/VideoCommon/AbstractGfx.h +++ b/Source/Core/VideoCommon/AbstractGfx.h @@ -126,6 +126,20 @@ public: AbstractFramebuffer* GetCurrentFramebuffer() const { return m_current_framebuffer; } + struct ViewportAndScissor + { + MathUtil::Rectangle scissor_rect; + float viewport_x; + float viewport_y; + float viewport_width; + float viewport_height; + float viewport_near_depth; + float viewport_far_depth; + }; + + // Stores the last viewport and scissor, the stored data is restored in 'EndUtilityDrawing' + void StoreViewportAndScissor(const ViewportAndScissor& viewport_and_scissor); + // Sets viewport and scissor to the specified rectangle. rect is assumed to be in framebuffer // coordinates, i.e. lower-left origin in OpenGL. void SetViewportAndScissor(const MathUtil::Rectangle& rect, float min_depth = 0.0f, @@ -177,6 +191,7 @@ protected: private: Common::EventHook m_config_changed; + ViewportAndScissor m_viewport_and_scissor; }; extern std::unique_ptr g_gfx; diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index 660d85c5989..134a14f8d47 100644 --- a/Source/Core/VideoCommon/BPFunctions.cpp +++ b/Source/Core/VideoCommon/BPFunctions.cpp @@ -265,6 +265,14 @@ void SetScissorAndViewport(FramebufferManager* frame_buffer_manager, ScissorPos y = static_cast(g_gfx->GetCurrentFramebuffer()->GetHeight()) - y - height; g_gfx->SetViewport(x, y, width, height, near_depth, far_depth); + + g_gfx->StoreViewportAndScissor(AbstractGfx::ViewportAndScissor{.scissor_rect = converted_rc, + .viewport_x = x, + .viewport_y = y, + .viewport_width = width, + .viewport_height = height, + .viewport_near_depth = near_depth, + .viewport_far_depth = far_depth}); } void SetDepthMode()