Skip to content

Commit

Permalink
Merge pull request #16242 from unknownbrackets/logic-op
Browse files Browse the repository at this point in the history
GPU: Replace logic ops with blend for simple cases
  • Loading branch information
hrydgard authored Oct 17, 2022
2 parents 51c359c + 162b27e commit c5bdc61
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion GPU/Common/GPUStateUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,9 +858,12 @@ static inline bool blendColorSimilar(uint32_t a, uint32_t b, int margin = 25) {
// The shader might also need modification, the below function SimulateLogicOpShaderTypeIfNeeded
// takes care of that.
static bool SimulateLogicOpIfNeeded(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &blendEq) {
if (!gstate.isLogicOpEnabled())
return false;

// 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) && gstate.isLogicOpEnabled()) {
if (!gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
switch (gstate.getLogicOp()) {
case GE_LOGIC_CLEAR:
srcBlend = BlendFactor::ZERO;
Expand Down Expand Up @@ -916,6 +919,25 @@ static bool SimulateLogicOpIfNeeded(BlendFactor &srcBlend, BlendFactor &dstBlend
WARN_LOG_REPORT_ONCE(d3dLogicOpSet, G3D, "Attempted set for logic op: %x", gstate.getLogicOp());
return true;
}
} else {
// Even if we support hardware logic ops, alpha is handled wrong.
// It's better to override blending for the simple cases.
switch (gstate.getLogicOp()) {
case GE_LOGIC_CLEAR:
srcBlend = BlendFactor::ZERO;
dstBlend = BlendFactor::ZERO;
blendEq = BlendEq::ADD;
return true;
case GE_LOGIC_NOOP:
srcBlend = BlendFactor::ZERO;
dstBlend = BlendFactor::ONE;
blendEq = BlendEq::ADD;
return true;

default:
// Let's hope hardware gets it right.
return false;
}
}
return false;
}
Expand Down Expand Up @@ -1598,5 +1620,7 @@ void GenericLogicState::ApplyToBlendState(GenericBlendState &blendState) {
blendState.dstAlpha = BlendFactor::ZERO;
blendState.eqAlpha = BlendEq::ADD;
}
logicOpEnabled = false;
logicOp = GE_LOGIC_COPY;
}
}

0 comments on commit c5bdc61

Please sign in to comment.