mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
GPU: Avoid stencil emulation if possible.
This reduces use of replaceAlpha, and reduces use of more complicated blend states. This simplifies fragment shaders a little.
This commit is contained in:
parent
d8c80afe59
commit
5932cbabc3
6 changed files with 19 additions and 7 deletions
|
@ -40,6 +40,17 @@ bool CanUseHardwareTransform(int prim) {
|
||||||
return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
|
return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsStencilTestOutputDisabled() {
|
||||||
|
// The mask applies on all stencil ops.
|
||||||
|
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF) {
|
||||||
|
if (gstate.FrameBufFormat() == GE_FORMAT_565) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return gstate.getStencilOpZPass() == GE_STENCILOP_KEEP && gstate.getStencilOpZFail() == GE_STENCILOP_KEEP && gstate.getStencilOpSFail() == GE_STENCILOP_KEEP;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool NeedsTestDiscard() {
|
bool NeedsTestDiscard() {
|
||||||
// We assume this is called only when enabled and not trivially true (may also be for color testing.)
|
// We assume this is called only when enabled and not trivially true (may also be for color testing.)
|
||||||
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF)
|
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF)
|
||||||
|
@ -169,7 +180,7 @@ const bool nonAlphaDestFactors[16] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend) {
|
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend) {
|
||||||
if (!gstate.isStencilTestEnabled() || gstate.isModeClear()) {
|
if (IsStencilTestOutputDisabled() || gstate.isModeClear()) {
|
||||||
return REPLACE_ALPHA_NO;
|
return REPLACE_ALPHA_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,7 +1006,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
|
||||||
|
|
||||||
int constantAlpha = 255;
|
int constantAlpha = 255;
|
||||||
BlendFactor constantAlphaGL = BlendFactor::ONE;
|
BlendFactor constantAlphaGL = BlendFactor::ONE;
|
||||||
if (gstate.isStencilTestEnabled() && replaceAlphaWithStencil == REPLACE_ALPHA_NO) {
|
if (!IsStencilTestOutputDisabled() && replaceAlphaWithStencil == REPLACE_ALPHA_NO) {
|
||||||
switch (ReplaceAlphaWithStencilType()) {
|
switch (ReplaceAlphaWithStencilType()) {
|
||||||
case STENCIL_VALUE_UNIFORM:
|
case STENCIL_VALUE_UNIFORM:
|
||||||
constantAlpha = gstate.getStencilTestRef();
|
constantAlpha = gstate.getStencilTestRef();
|
||||||
|
@ -1163,7 +1174,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
|
||||||
blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ONE, BlendFactor::ZERO);
|
blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ONE, BlendFactor::ZERO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (gstate.isStencilTestEnabled()) {
|
} else if (!IsStencilTestOutputDisabled()) {
|
||||||
switch (ReplaceAlphaWithStencilType()) {
|
switch (ReplaceAlphaWithStencilType()) {
|
||||||
case STENCIL_VALUE_KEEP:
|
case STENCIL_VALUE_KEEP:
|
||||||
blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ZERO, BlendFactor::ONE);
|
blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ZERO, BlendFactor::ONE);
|
||||||
|
|
|
@ -45,6 +45,7 @@ bool IsColorTestAgainstZero();
|
||||||
bool IsColorTestTriviallyTrue();
|
bool IsColorTestTriviallyTrue();
|
||||||
bool IsAlphaTestAgainstZero();
|
bool IsAlphaTestAgainstZero();
|
||||||
bool NeedsTestDiscard();
|
bool NeedsTestDiscard();
|
||||||
|
bool IsStencilTestOutputDisabled();
|
||||||
|
|
||||||
StencilValueType ReplaceAlphaWithStencilType();
|
StencilValueType ReplaceAlphaWithStencilType();
|
||||||
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend);
|
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend);
|
||||||
|
|
|
@ -223,7 +223,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Let's not write to alpha if stencil isn't enabled.
|
// Let's not write to alpha if stencil isn't enabled.
|
||||||
if (!gstate.isStencilTestEnabled()) {
|
if (IsStencilTestOutputDisabled()) {
|
||||||
amask = false;
|
amask = false;
|
||||||
} else {
|
} else {
|
||||||
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
||||||
|
|
|
@ -181,7 +181,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Let's not write to alpha if stencil isn't enabled.
|
// Let's not write to alpha if stencil isn't enabled.
|
||||||
if (!gstate.isStencilTestEnabled()) {
|
if (IsStencilTestOutputDisabled()) {
|
||||||
amask = false;
|
amask = false;
|
||||||
} else {
|
} else {
|
||||||
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
||||||
|
|
|
@ -143,7 +143,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||||
// amask is needed for both stencil and blend state so we keep it outside for now
|
// amask is needed for both stencil and blend state so we keep it outside for now
|
||||||
bool amask = (gstate.pmska & 0xFF) < 128;
|
bool amask = (gstate.pmska & 0xFF) < 128;
|
||||||
// Let's not write to alpha if stencil isn't enabled.
|
// Let's not write to alpha if stencil isn't enabled.
|
||||||
if (!gstate.isStencilTestEnabled()) {
|
if (IsStencilTestOutputDisabled()) {
|
||||||
amask = false;
|
amask = false;
|
||||||
} else {
|
} else {
|
||||||
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
||||||
|
|
|
@ -225,7 +225,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Let's not write to alpha if stencil isn't enabled.
|
// Let's not write to alpha if stencil isn't enabled.
|
||||||
if (!gstate.isStencilTestEnabled()) {
|
if (IsStencilTestOutputDisabled()) {
|
||||||
amask = false;
|
amask = false;
|
||||||
} else {
|
} else {
|
||||||
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
|
||||||
|
|
Loading…
Add table
Reference in a new issue