mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
GL render manager: Merge the two stencil commands, for more compact command lists
This commit is contained in:
parent
470ebbfe73
commit
cb38c43d7e
5 changed files with 33 additions and 44 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Reference in a new issue