Permalink
Browse files

GPU: Apply logic op in more cases.

It has well defined behavior with alpha blending, so let's apply it even
when we're blending.  Fixes #11316.
  • Loading branch information...
unknownbrackets committed Aug 25, 2018
1 parent 734db3d commit 5c01bf61e6203d60237b0739221303712f777bb1
Showing with 17 additions and 5 deletions.
  1. +17 −5 GPU/Common/GPUStateUtils.cpp
@@ -814,11 +814,15 @@ static inline bool blendColorSimilar(uint32_t a, uint32_t b, int margin = 25) {
// Try to simulate some common logic ops.
static void ApplyLogicOp(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &blendEq) {
// Note: our shader solution applies logic ops BEFORE blending, not correctly after.
// This is however fine for the most common ones, like CLEAR/NOOP/SET, etc.
if (!gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
if (gstate.isLogicOpEnabled()) {
switch (gstate.getLogicOp()) {
case GE_LOGIC_CLEAR:
srcBlend = BlendFactor::ZERO;
dstBlend = BlendFactor::ZERO;
blendEq = BlendEq::ADD;
break;
case GE_LOGIC_AND:
case GE_LOGIC_AND_REVERSE:
@@ -846,6 +850,7 @@ static void ApplyLogicOp(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &
case GE_LOGIC_NOOP:
srcBlend = BlendFactor::ZERO;
dstBlend = BlendFactor::ONE;
blendEq = BlendEq::ADD;
break;
case GE_LOGIC_XOR:
WARN_LOG_REPORT_ONCE(d3dLogicOpOrXor, G3D, "Unsupported XOR logic op: %x", gstate.getLogicOp());
@@ -860,7 +865,9 @@ static void ApplyLogicOp(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &
WARN_LOG_REPORT_ONCE(d3dLogicOpOrReverse, G3D, "Unsupported OR REVERSE logic op: %x", gstate.getLogicOp());
break;
case GE_LOGIC_SET:
srcBlend = BlendFactor::ONE;
dstBlend = BlendFactor::ONE;
blendEq = BlendEq::ADD;
WARN_LOG_REPORT_ONCE(d3dLogicOpSet, G3D, "Attempted set for logic op: %x", gstate.getLogicOp());
break;
}
@@ -1109,6 +1116,15 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
#endif
// At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set right somehow.
BlendEq colorEq;
if (gstate_c.Supports(GPU_SUPPORTS_BLEND_MINMAX)) {
colorEq = eqLookup[blendFuncEq];
} else {
colorEq = eqLookupNoMinMax[blendFuncEq];
}
// Attempt to apply the logic op, if any.
ApplyLogicOp(glBlendFuncA, glBlendFuncB, colorEq);
// The stencil-to-alpha in fragment shader doesn't apply here (blending is enabled), and we shouldn't
// do any blending in the alpha channel as that doesn't seem to happen on PSP. So, we attempt to
@@ -1178,11 +1194,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ZERO, BlendFactor::ONE);
}
if (gstate_c.Supports(GPU_SUPPORTS_BLEND_MINMAX)) {
blendState.setEquation(eqLookup[blendFuncEq], alphaEq);
} else {
blendState.setEquation(eqLookupNoMinMax[blendFuncEq], alphaEq);
}
blendState.setEquation(colorEq, alphaEq);
}
static void ConvertStencilFunc5551(GenericStencilFuncState &state) {

0 comments on commit 5c01bf6

Please sign in to comment.