From 92a18eed01988db7ea6a55f1549fc919476f0524 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 1 Mar 2023 22:03:56 -0800 Subject: [PATCH] GPU: Discard framebuffer copy when clearing. This avoids retaining the framebuffer copy any longer than the current framebuffer target. --- GPU/Common/DepthBufferCommon.cpp | 2 +- GPU/Common/FramebufferManagerCommon.cpp | 6 ++++++ GPU/Common/FramebufferManagerCommon.h | 2 ++ GPU/GLES/StencilBufferGLES.cpp | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/GPU/Common/DepthBufferCommon.cpp b/GPU/Common/DepthBufferCommon.cpp index 46a2ecfb6fcb..a29c99577575 100644 --- a/GPU/Common/DepthBufferCommon.cpp +++ b/GPU/Common/DepthBufferCommon.cpp @@ -204,7 +204,7 @@ bool FramebufferManagerCommon::ReadbackDepthbuffer(Draw::Framebuffer *fbo, int x } shaderManager_->DirtyLastShader(); - auto *blitFBO = GetTempFBO(TempFBO::COPY, fbo->Width() * scaleX, fbo->Height() * scaleY); + auto *blitFBO = GetTempFBO(TempFBO::Z_COPY, fbo->Width() * scaleX, fbo->Height() * scaleY); draw_->BindFramebufferAsRenderTarget(blitFBO, { RPAction::DONT_CARE, RPAction::DONT_CARE, RPAction::DONT_CARE }, "ReadbackDepthbufferSync"); Draw::Viewport viewport = { 0.0f, 0.0f, (float)destW, (float)destH, 0.0f, 1.0f }; draw_->SetViewport(viewport); diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index e4f3bc0d94c5..e21bc35e9378 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -932,6 +932,7 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { } // Wipe some pointers + DiscardFramebufferCopy(); if (currentRenderVfb_ == v) currentRenderVfb_ = nullptr; if (displayFramebuf_ == v) @@ -1450,6 +1451,7 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, int // PresentationCommon sets all kinds of state, we can't rely on anything. gstate_c.Dirty(DIRTY_ALL); + DiscardFramebufferCopy(); currentRenderVfb_ = nullptr; } @@ -1607,10 +1609,12 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { // This may get called mid-draw if the game uses an immediate flip. // PresentationCommon sets all kinds of state, we can't rely on anything. gstate_c.Dirty(DIRTY_ALL); + DiscardFramebufferCopy(); currentRenderVfb_ = nullptr; } void FramebufferManagerCommon::DecimateFBOs() { + DiscardFramebufferCopy(); currentRenderVfb_ = nullptr; for (auto iter : fbosToDelete_) { @@ -1767,6 +1771,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); } + DiscardFramebufferCopy(); currentRenderVfb_ = vfb; if (!vfb->fbo) { @@ -2568,6 +2573,7 @@ void FramebufferManagerCommon::NotifyConfigChanged() { } void FramebufferManagerCommon::DestroyAllFBOs() { + DiscardFramebufferCopy(); currentRenderVfb_ = nullptr; displayFramebuf_ = nullptr; prevDisplayFramebuf_ = nullptr; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 394e5d0593a1..d0c83b4d6c11 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -217,6 +217,8 @@ enum class TempFBO { BLIT, // For copies of framebuffers (e.g. shader blending.) COPY, + // Used for copies when setting color to depth. + Z_COPY, // Used to copy stencil data, means we need a stencil backing. STENCIL, }; diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 763e5a95fe76..845cd2b3ac76 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -130,7 +130,7 @@ bool FramebufferManagerGLES::ReadbackStencilbuffer(Draw::Framebuffer *fbo, int x } shaderManager_->DirtyLastShader(); - auto *blitFBO = GetTempFBO(TempFBO::COPY, fbo->Width(), fbo->Height()); + auto *blitFBO = GetTempFBO(TempFBO::Z_COPY, fbo->Width(), fbo->Height()); draw_->BindFramebufferAsRenderTarget(blitFBO, { RPAction::DONT_CARE, RPAction::DONT_CARE, RPAction::DONT_CARE }, "ReadbackStencilbufferSync"); Draw::Viewport viewport = { 0.0f, 0.0f, (float)fbo->Width(), (float)fbo->Height(), 0.0f, 1.0f }; draw_->SetViewport(viewport);