GL render manager: Merge the two stencil commands, for more compact command lists

This commit is contained in:
Henrik Rydgård 2023-05-16 21:49:18 +02:00
parent 470ebbfe73
commit cb38c43d7e
5 changed files with 33 additions and 44 deletions

View file

@ -862,23 +862,21 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last
depthEnabled = false; depthEnabled = false;
} }
break; break;
case GLRRenderCommand::STENCILFUNC: case GLRRenderCommand::STENCIL:
if (c.stencilFunc.enabled) { if (c.stencil.enabled) {
if (!stencilEnabled) { if (!stencilEnabled) {
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
stencilEnabled = true; 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) { } else if (/* !c.stencilFunc.enabled && */stencilEnabled) {
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
stencilEnabled = false; stencilEnabled = false;
} }
CHECK_GL_ERROR_IF_DEBUG(); CHECK_GL_ERROR_IF_DEBUG();
break; break;
case GLRRenderCommand::STENCILOP:
glStencilOp(c.stencilOp.sFail, c.stencilOp.zFail, c.stencilOp.pass);
glStencilMask(c.stencilOp.writeMask);
break;
case GLRRenderCommand::BLEND: case GLRRenderCommand::BLEND:
if (c.blend.enabled) { if (c.blend.enabled) {
if (!blendEnabled) { if (!blendEnabled) {

View file

@ -40,8 +40,7 @@ class GLRInputLayout;
enum class GLRRenderCommand : uint8_t { enum class GLRRenderCommand : uint8_t {
DEPTH, DEPTH,
STENCILFUNC, STENCIL,
STENCILOP,
BLEND, BLEND,
BLENDCOLOR, BLENDCOLOR,
LOGICOP, LOGICOP,
@ -100,13 +99,11 @@ struct GLRRenderData {
GLenum func; GLenum func;
uint8_t ref; uint8_t ref;
uint8_t compareMask; uint8_t compareMask;
} stencilFunc;
struct {
GLenum sFail; GLenum sFail;
GLenum zFail; GLenum zFail;
GLenum pass; GLenum pass;
uint8_t writeMask; uint8_t writeMask;
} stencilOp; // also write mask } stencil;
struct { struct {
GLRInputLayout *inputLayout; GLRInputLayout *inputLayout;
GLRBuffer *buffer; GLRBuffer *buffer;

View file

@ -664,32 +664,25 @@ public:
} }
#endif #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); _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
GLRRenderData &data = curRenderStep_->commands.push_uninitialized(); GLRRenderData &data = curRenderStep_->commands.push_uninitialized();
data.cmd = GLRRenderCommand::STENCILFUNC; data.cmd = GLRRenderCommand::STENCIL;
data.stencilFunc.enabled = enabled; data.stencil.enabled = enabled;
data.stencilFunc.func = func; data.stencil.func = func;
data.stencilFunc.ref = refValue; data.stencil.ref = refValue;
data.stencilFunc.compareMask = compareMask; data.stencil.compareMask = compareMask;
} data.stencil.writeMask = writeMask;
data.stencil.sFail = sFail;
void SetStencilOp(uint8_t writeMask, GLenum sFail, GLenum zFail, GLenum pass) { data.stencil.zFail = zFail;
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); data.stencil.pass = pass;
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;
} }
void SetStencilDisabled() { void SetStencilDisabled() {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
GLRRenderData &data = curRenderStep_->commands.push_uninitialized(); GLRRenderData &data = curRenderStep_->commands.push_uninitialized();
data.cmd = GLRRenderCommand::STENCILFUNC; data.cmd = GLRRenderCommand::STENCIL;
data.stencilFunc.enabled = false; data.stencil.enabled = false;
// When enabled = false, the others aren't read so we don't zero-initialize them.
} }
void SetBlendFactor(const float color[4]) { void SetBlendFactor(const float color[4]) {

View file

@ -180,8 +180,9 @@ public:
void Apply(GLRenderManager *render, uint8_t stencilRef, uint8_t stencilWriteMask, uint8_t stencilCompareMask) { void Apply(GLRenderManager *render, uint8_t stencilRef, uint8_t stencilWriteMask, uint8_t stencilCompareMask) {
render->SetDepth(depthTestEnabled, depthWriteEnabled, depthComp); render->SetDepth(depthTestEnabled, depthWriteEnabled, depthComp);
render->SetStencilFunc(stencilEnabled, stencilCompareOp, stencilRef, stencilCompareMask); render->SetStencil(
render->SetStencilOp(stencilWriteMask, stencilFail, stencilZFail, stencilPass); stencilEnabled, stencilCompareOp, stencilRef, stencilCompareMask,
stencilWriteMask, stencilFail, stencilZFail, stencilPass);
} }
}; };
@ -407,12 +408,11 @@ public:
stencilWriteMask_ = writeMask; stencilWriteMask_ = writeMask;
stencilCompareMask_ = compareMask; stencilCompareMask_ = compareMask;
// Do we need to update on the fly here? // Do we need to update on the fly here?
renderManager_.SetStencilFunc( renderManager_.SetStencil(
curPipeline_->depthStencil->stencilEnabled, curPipeline_->depthStencil->stencilEnabled,
curPipeline_->depthStencil->stencilCompareOp, curPipeline_->depthStencil->stencilCompareOp,
refValue, refValue,
compareMask); compareMask,
renderManager_.SetStencilOp(
writeMask, writeMask,
curPipeline_->depthStencil->stencilFail, curPipeline_->depthStencil->stencilFail,
curPipeline_->depthStencil->stencilZFail, curPipeline_->depthStencil->stencilZFail,

View file

@ -247,8 +247,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
if (gstate.isModeClear()) { if (gstate.isModeClear()) {
// Depth Test // Depth Test
renderManager->SetStencilFunc(gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF); renderManager->SetStencil(
renderManager->SetStencilOp(stencilState.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE); gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF,
stencilState.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE);
renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS);
} else { } else {
// Depth Test // Depth Test
@ -259,8 +260,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
// Stencil Test // Stencil Test
if (stencilState.enabled) { if (stencilState.enabled) {
renderManager->SetStencilFunc(stencilState.enabled, compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask); renderManager->SetStencil(
renderManager->SetStencilOp(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 // 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 // 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)) { if (SpongebobDepthInverseConditions(stencilState)) {
renderManager->SetBlendAndMask(0x8, true, GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO, GL_FUNC_ADD, GL_FUNC_ADD); 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->SetDepth(true, false, GL_LESS);
renderManager->SetStencilFunc(true, GL_ALWAYS, 0xFF, 0xFF); renderManager->SetStencil(true, GL_ALWAYS, 0xFF, 0xFF, 0xFF, GL_ZERO, GL_KEEP, GL_ZERO);
renderManager->SetStencilOp(0xFF, GL_ZERO, GL_KEEP, GL_ZERO);
dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE; dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE;
gstate_c.Dirty(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) { void DrawEngineGLES::ApplyDrawStateLate(bool setStencilValue, int stencilValue) {
if (setStencilValue) { if (setStencilValue) {
render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, stencilValue, 255); render_->SetStencil(true, GL_ALWAYS, stencilValue, 255, 0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE);
render_->SetStencilOp(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. // At this point, we know if the vertices are full alpha or not.