From 5ff3e6a5e7399303dad26f52fbcd2f89720e6b9c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 3 Nov 2015 22:37:19 -0800 Subject: [PATCH] Avoid polluting glstate in GetTempFBO(). Since we do this "late", we might overwrite important settings, such as stencil, color masks, etc. This affects both depal and fbo shader blending. Didn't do it for all ClearBuffer()s, since I'm worried some might be intentionally resetting state. --- GPU/Common/FramebufferCommon.h | 2 +- GPU/Directx9/FramebufferDX9.cpp | 29 ++++++++++++++++++++++------- GPU/Directx9/FramebufferDX9.h | 2 +- GPU/GLES/Framebuffer.cpp | 29 ++++++++++++++++++++++------- GPU/GLES/Framebuffer.h | 2 +- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index f57c5a0413..e4722f891a 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -214,7 +214,7 @@ protected: void UpdateSize(); virtual void DisableState() = 0; - virtual void ClearBuffer() = 0; + virtual void ClearBuffer(bool keepState = false) = 0; virtual void ClearDepthBuffer() = 0; virtual void FlushBeforeCopy() = 0; virtual void DecimateFBOs() = 0; diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index d330537e48..7bd9c518d1 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -44,13 +44,28 @@ void ShowScreenResolution(); namespace DX9 { static void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format); - void FramebufferManagerDX9::ClearBuffer() { - dxstate.scissorTest.disable(); - dxstate.depthWrite.set(TRUE); - dxstate.colorMask.set(true, true, true, true); - dxstate.stencilFunc.set(D3DCMP_ALWAYS, 0, 0); - dxstate.stencilMask.set(0xFF); + void FramebufferManagerDX9::ClearBuffer(bool keepState) { + if (keepState) { + dxstate.scissorTest.force(false); + dxstate.depthWrite.force(TRUE); + dxstate.colorMask.force(true, true, true, true); + dxstate.stencilFunc.force(D3DCMP_ALWAYS, 0, 0); + dxstate.stencilMask.force(0xFF); + } else { + dxstate.scissorTest.disable(); + dxstate.depthWrite.set(TRUE); + dxstate.colorMask.set(true, true, true, true); + dxstate.stencilFunc.set(D3DCMP_ALWAYS, 0, 0); + dxstate.stencilMask.set(0xFF); + } pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 0, 0); + if (keepState) { + dxstate.scissorTest.restore(); + dxstate.depthWrite.restore(); + dxstate.colorMask.restore(); + dxstate.stencilFunc.restore(); + dxstate.stencilMask.restore(); + } } void FramebufferManagerDX9::ClearDepthBuffer() { @@ -577,7 +592,7 @@ namespace DX9 { if (!fbo) return fbo; fbo_bind_as_render_target(fbo); - ClearBuffer(); + ClearBuffer(true); const TempFBO info = {fbo, gpuStats.numFlips}; tempFBOs_[key] = info; return fbo; diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index 2fef208fa6..96605e358a 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -94,7 +94,7 @@ public: protected: virtual void DisableState() override; - virtual void ClearBuffer() override; + virtual void ClearBuffer(bool keepState = false) override; virtual void ClearDepthBuffer() override; virtual void FlushBeforeCopy() override; virtual void DecimateFBOs() override; diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 0e21a406d5..c0447ddbab 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -86,12 +86,20 @@ static const char color_vs[] = void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format); -void FramebufferManager::ClearBuffer() { - glstate.scissorTest.disable(); - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glstate.stencilFunc.set(GL_ALWAYS, 0, 0); - glstate.stencilMask.set(0xFF); +void FramebufferManager::ClearBuffer(bool keepState) { + if (keepState) { + glstate.scissorTest.force(false); + glstate.depthWrite.force(GL_TRUE); + glstate.colorMask.force(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glstate.stencilFunc.force(GL_ALWAYS, 0, 0); + glstate.stencilMask.force(0xFF); + } else { + glstate.scissorTest.disable(); + glstate.depthWrite.set(GL_TRUE); + glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glstate.stencilFunc.set(GL_ALWAYS, 0, 0); + glstate.stencilMask.set(0xFF); + } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearStencil(0); #ifdef USING_GLES2 @@ -100,6 +108,13 @@ void FramebufferManager::ClearBuffer() { glClearDepth(0.0); #endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + if (keepState) { + glstate.scissorTest.restore(); + glstate.depthWrite.restore(); + glstate.colorMask.restore(); + glstate.stencilFunc.restore(); + glstate.stencilMask.restore(); + } } void FramebufferManager::ClearDepthBuffer() { @@ -859,7 +874,7 @@ FBO *FramebufferManager::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) { if (!fbo) return fbo; fbo_bind_as_render_target(fbo); - ClearBuffer(); + ClearBuffer(true); const TempFBO info = {fbo, gpuStats.numFlips}; tempFBOs_[key] = info; return fbo; diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 4acc4c884c..455831cf26 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -124,7 +124,7 @@ public: protected: virtual void DisableState() override; - virtual void ClearBuffer() override; + virtual void ClearBuffer(bool keepState = false) override; virtual void ClearDepthBuffer() override; virtual void FlushBeforeCopy() override; virtual void DecimateFBOs() override;