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;
}
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) {

View file

@ -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;

View file

@ -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]) {

View file

@ -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,

View file

@ -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.