From cb38c43d7ed6a4bd73bd9dfb3d19b1cb44aa136d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 16 May 2023 21:49:18 +0200 Subject: [PATCH] GL render manager: Merge the two stencil commands, for more compact command lists --- Common/GPU/OpenGL/GLQueueRunner.cpp | 12 +++++------ Common/GPU/OpenGL/GLQueueRunner.h | 7 ++----- Common/GPU/OpenGL/GLRenderManager.h | 31 +++++++++++------------------ Common/GPU/OpenGL/thin3d_gl.cpp | 10 +++++----- GPU/GLES/StateMappingGLES.cpp | 17 ++++++++-------- 5 files changed, 33 insertions(+), 44 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 457f5d98e1..08af252ffd 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -862,23 +862,21 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last depthEnabled = false; } break; - case GLRRenderCommand::STENCILFUNC: - if (c.stencilFunc.enabled) { + case GLRRenderCommand::STENCIL: + if (c.stencil.enabled) { if (!stencilEnabled) { glEnable(GL_STENCIL_TEST); stencilEnabled = true; } - glStencilFunc(c.stencilFunc.func, c.stencilFunc.ref, c.stencilFunc.compareMask); + glStencilFunc(c.stencil.func, c.stencil.ref, c.stencil.compareMask); + glStencilOp(c.stencil.sFail, c.stencil.zFail, c.stencil.pass); + glStencilMask(c.stencil.writeMask); } else if (/* !c.stencilFunc.enabled && */stencilEnabled) { glDisable(GL_STENCIL_TEST); stencilEnabled = false; } CHECK_GL_ERROR_IF_DEBUG(); break; - case GLRRenderCommand::STENCILOP: - glStencilOp(c.stencilOp.sFail, c.stencilOp.zFail, c.stencilOp.pass); - glStencilMask(c.stencilOp.writeMask); - break; case GLRRenderCommand::BLEND: if (c.blend.enabled) { if (!blendEnabled) { diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index 11d6e1acac..621b82f9a3 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -40,8 +40,7 @@ class GLRInputLayout; enum class GLRRenderCommand : uint8_t { DEPTH, - STENCILFUNC, - STENCILOP, + STENCIL, BLEND, BLENDCOLOR, LOGICOP, @@ -100,13 +99,11 @@ struct GLRRenderData { GLenum func; uint8_t ref; uint8_t compareMask; - } stencilFunc; - struct { GLenum sFail; GLenum zFail; GLenum pass; uint8_t writeMask; - } stencilOp; // also write mask + } stencil; struct { GLRInputLayout *inputLayout; GLRBuffer *buffer; diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index fcf0bfe7a5..3a07bebb82 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -664,32 +664,25 @@ public: } #endif - void SetStencilFunc(bool enabled, GLenum func, uint8_t refValue, uint8_t compareMask) { + void SetStencil(bool enabled, GLenum func, uint8_t refValue, uint8_t compareMask, uint8_t writeMask, GLenum sFail, GLenum zFail, GLenum pass) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData &data = curRenderStep_->commands.push_uninitialized(); - data.cmd = GLRRenderCommand::STENCILFUNC; - data.stencilFunc.enabled = enabled; - data.stencilFunc.func = func; - data.stencilFunc.ref = refValue; - data.stencilFunc.compareMask = compareMask; - } - - void SetStencilOp(uint8_t writeMask, GLenum sFail, GLenum zFail, GLenum pass) { - _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); - GLRRenderData &data = curRenderStep_->commands.push_uninitialized(); - data.cmd = GLRRenderCommand::STENCILOP; - data.stencilOp.writeMask = writeMask; - data.stencilOp.sFail = sFail; - data.stencilOp.zFail = zFail; - data.stencilOp.pass = pass; + data.cmd = GLRRenderCommand::STENCIL; + data.stencil.enabled = enabled; + data.stencil.func = func; + data.stencil.ref = refValue; + data.stencil.compareMask = compareMask; + data.stencil.writeMask = writeMask; + data.stencil.sFail = sFail; + data.stencil.zFail = zFail; + data.stencil.pass = pass; } void SetStencilDisabled() { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData &data = curRenderStep_->commands.push_uninitialized(); - data.cmd = GLRRenderCommand::STENCILFUNC; - data.stencilFunc.enabled = false; - // When enabled = false, the others aren't read so we don't zero-initialize them. + data.cmd = GLRRenderCommand::STENCIL; + data.stencil.enabled = false; } void SetBlendFactor(const float color[4]) { diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 646dcff91e..e25a95c1e8 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -180,8 +180,9 @@ public: void Apply(GLRenderManager *render, uint8_t stencilRef, uint8_t stencilWriteMask, uint8_t stencilCompareMask) { render->SetDepth(depthTestEnabled, depthWriteEnabled, depthComp); - render->SetStencilFunc(stencilEnabled, stencilCompareOp, stencilRef, stencilCompareMask); - render->SetStencilOp(stencilWriteMask, stencilFail, stencilZFail, stencilPass); + render->SetStencil( + stencilEnabled, stencilCompareOp, stencilRef, stencilCompareMask, + stencilWriteMask, stencilFail, stencilZFail, stencilPass); } }; @@ -407,12 +408,11 @@ public: stencilWriteMask_ = writeMask; stencilCompareMask_ = compareMask; // Do we need to update on the fly here? - renderManager_.SetStencilFunc( + renderManager_.SetStencil( curPipeline_->depthStencil->stencilEnabled, curPipeline_->depthStencil->stencilCompareOp, refValue, - compareMask); - renderManager_.SetStencilOp( + compareMask, writeMask, curPipeline_->depthStencil->stencilFail, curPipeline_->depthStencil->stencilZFail, diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index af4b89903e..7d16448ec4 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -247,8 +247,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (gstate.isModeClear()) { // Depth Test - renderManager->SetStencilFunc(gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF); - renderManager->SetStencilOp(stencilState.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE); + renderManager->SetStencil( + gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF, + stencilState.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE); renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); } else { // Depth Test @@ -259,8 +260,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) { // Stencil Test if (stencilState.enabled) { - renderManager->SetStencilFunc(stencilState.enabled, compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask); - renderManager->SetStencilOp(stencilState.writeMask, stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]); + renderManager->SetStencil( + 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 @@ -268,8 +270,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { 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->SetStencilFunc(true, GL_ALWAYS, 0xFF, 0xFF); - renderManager->SetStencilOp(0xFF, GL_ZERO, GL_KEEP, GL_ZERO); + renderManager->SetStencil(true, GL_ALWAYS, 0xFF, 0xFF, 0xFF, GL_ZERO, GL_KEEP, GL_ZERO); dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE; gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); @@ -301,8 +302,8 @@ void DrawEngineGLES::ApplyDrawState(int prim) { void DrawEngineGLES::ApplyDrawStateLate(bool setStencilValue, int stencilValue) { if (setStencilValue) { - render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, stencilValue, 255); - render_->SetStencilOp(0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); + render_->SetStencil(true, GL_ALWAYS, stencilValue, 255, 0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); + gstate_c.Dirty(DIRTY_DEPTHSTENCIL_STATE); // For the next time. } // At this point, we know if the vertices are full alpha or not.