From 53aa2cc596075aef1c171e6d0db9ef453d811d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 12 Jun 2023 11:49:44 +0200 Subject: [PATCH] Apply stencil writemask when clearing properly again, see #17478 Also renames vpAndScissor to vpAndScissor_ for consistency. --- GPU/GLES/DrawEngineGLES.cpp | 6 +++--- GPU/GLES/DrawEngineGLES.h | 4 +++- GPU/GLES/StateMappingGLES.cpp | 28 +++++++++++++--------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 1f55ad16d33e..ee626ac81e26 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -378,8 +378,8 @@ void DrawEngineGLES::DoFlush() { ConvertViewportAndScissor(framebufferManager_->UseBufferedRendering(), framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(), framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(), - vpAndScissor); - UpdateCachedViewportState(vpAndScissor); + vpAndScissor_); + UpdateCachedViewportState(vpAndScissor_); } int maxIndex = indexGen.MaxIndex(); @@ -455,7 +455,7 @@ void DrawEngineGLES::DoFlush() { if (alphaMask) target |= GL_STENCIL_BUFFER_BIT; if (depthMask) target |= GL_DEPTH_BUFFER_BIT; - render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask, vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH); + render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask, vpAndScissor_.scissorX, vpAndScissor_.scissorY, vpAndScissor_.scissorW, vpAndScissor_.scissorH); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); if (gstate_c.Use(GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate_c.framebufFormat == GE_FORMAT_565)) { diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 149c5c6e82ca..81bc0d496764 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -141,7 +141,9 @@ class DrawEngineGLES : public DrawEngineCommon { Draw::DrawContext *draw_; // Need to preserve the scissor for use when clearing. - ViewportAndScissor vpAndScissor; + ViewportAndScissor vpAndScissor_{}; + // Need to preserve writemask, easiest way. + GenericStencilFuncState stencilState_{}; int bufferDecimationCounter_ = 0; int lastRenderStepId_ = -1; diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 7d16448ec40f..7a846711f38b 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -242,14 +242,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) { } if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) { - GenericStencilFuncState stencilState; - ConvertStencilFuncState(stencilState); + ConvertStencilFuncState(stencilState_); if (gstate.isModeClear()) { - // Depth Test renderManager->SetStencil( gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF, - stencilState.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE); + stencilState_.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE); renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); } else { // Depth Test @@ -259,15 +257,15 @@ void DrawEngineGLES::ApplyDrawState(int prim) { UpdateEverUsedEqualDepth(gstate.getDepthTestFunction()); // Stencil Test - if (stencilState.enabled) { + if (stencilState_.enabled) { renderManager->SetStencil( - stencilState.enabled, compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask, - stencilState.writeMask, stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]); + stencilState_.enabled, compareOps[stencilState_.testFunc], stencilState_.testRef, stencilState_.testMask, + stencilState_.writeMask, stencilOps[stencilState_.sFail], stencilOps[stencilState_.zFail], stencilOps[stencilState_.zPass]); // Nasty special case for Spongebob and similar where it tries to write zeros to alpha/stencil during // depth-fail. We can't write to alpha then because the pixel is killed. However, we can invert the depth // test and modify the alpha function... - if (SpongebobDepthInverseConditions(stencilState)) { + if (SpongebobDepthInverseConditions(stencilState_)) { renderManager->SetBlendAndMask(0x8, true, GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO, GL_FUNC_ADD, GL_FUNC_ADD); renderManager->SetDepth(true, false, GL_LESS); renderManager->SetStencil(true, GL_ALWAYS, 0xFF, 0xFF, 0xFF, GL_ZERO, GL_KEEP, GL_ZERO); @@ -285,14 +283,14 @@ void DrawEngineGLES::ApplyDrawState(int prim) { ConvertViewportAndScissor(useBufferedRendering, framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(), framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(), - vpAndScissor); - UpdateCachedViewportState(vpAndScissor); + vpAndScissor_); + UpdateCachedViewportState(vpAndScissor_); - renderManager->SetScissor(GLRect2D{ vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH }); + renderManager->SetScissor(GLRect2D{ vpAndScissor_.scissorX, vpAndScissor_.scissorY, vpAndScissor_.scissorW, vpAndScissor_.scissorH }); renderManager->SetViewport({ - vpAndScissor.viewportX, vpAndScissor.viewportY, - vpAndScissor.viewportW, vpAndScissor.viewportH, - vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax }); + vpAndScissor_.viewportX, vpAndScissor_.viewportY, + vpAndScissor_.viewportW, vpAndScissor_.viewportH, + vpAndScissor_.depthRangeMin, vpAndScissor_.depthRangeMax }); } gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE); @@ -302,7 +300,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { void DrawEngineGLES::ApplyDrawStateLate(bool setStencilValue, int stencilValue) { if (setStencilValue) { - render_->SetStencil(true, GL_ALWAYS, stencilValue, 255, 0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); + render_->SetStencil(stencilState_.writeMask, GL_ALWAYS, stencilValue, 255, 0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); gstate_c.Dirty(DIRTY_DEPTHSTENCIL_STATE); // For the next time. }