Logic op fix, min filter fix. Also remove some unnecessary indentation. Fixes the water on Adreno (no logic)

This commit is contained in:
Henrik Rydgård 2022-09-16 12:34:27 +02:00
parent ca2962beab
commit 9ec35d1464
2 changed files with 65 additions and 59 deletions

View file

@ -859,66 +859,63 @@ static inline bool blendColorSimilar(uint32_t a, uint32_t b, int margin = 25) {
static bool SimulateLogicOpIfNeeded(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &blendEq) { static bool SimulateLogicOpIfNeeded(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &blendEq) {
// Note: our shader solution applies logic ops BEFORE blending, not correctly after. // 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. // This is however fine for the most common ones, like CLEAR/NOOP/SET, etc.
if (!gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) { if (!gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP) && gstate.isLogicOpEnabled()) {
if (gstate.isLogicOpEnabled()) { switch (gstate.getLogicOp()) {
switch (gstate.getLogicOp()) { case GE_LOGIC_CLEAR:
case GE_LOGIC_CLEAR: srcBlend = BlendFactor::ZERO;
srcBlend = BlendFactor::ZERO; dstBlend = BlendFactor::ZERO;
dstBlend = BlendFactor::ZERO; blendEq = BlendEq::ADD;
blendEq = BlendEq::ADD; return true;
return true; case GE_LOGIC_AND:
case GE_LOGIC_AND: case GE_LOGIC_AND_REVERSE:
case GE_LOGIC_AND_REVERSE: WARN_LOG_REPORT_ONCE(d3dLogicOpAnd, G3D, "Unsupported AND logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpAnd, G3D, "Unsupported AND logic op: %x", gstate.getLogicOp()); break;
break; case GE_LOGIC_COPY:
case GE_LOGIC_COPY: // This is the same as off.
// This is the same as off. break;
break; case GE_LOGIC_COPY_INVERTED:
case GE_LOGIC_COPY_INVERTED: // Handled in the shader.
// Handled in the shader. break;
break; case GE_LOGIC_AND_INVERTED:
case GE_LOGIC_AND_INVERTED: case GE_LOGIC_NOR:
case GE_LOGIC_NOR: case GE_LOGIC_NAND:
case GE_LOGIC_NAND: case GE_LOGIC_EQUIV:
case GE_LOGIC_EQUIV: // Handled in the shader.
// Handled in the shader. WARN_LOG_REPORT_ONCE(d3dLogicOpAndInverted, G3D, "Attempted invert for logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpAndInverted, G3D, "Attempted invert for logic op: %x", gstate.getLogicOp()); break;
break; case GE_LOGIC_INVERTED:
case GE_LOGIC_INVERTED: srcBlend = BlendFactor::ONE;
srcBlend = BlendFactor::ONE; dstBlend = BlendFactor::ONE;
dstBlend = BlendFactor::ONE; blendEq = BlendEq::SUBTRACT;
blendEq = BlendEq::SUBTRACT; WARN_LOG_REPORT_ONCE(d3dLogicOpInverted, G3D, "Attempted inverse for logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpInverted, G3D, "Attempted inverse for logic op: %x", gstate.getLogicOp()); return true;
return true; case GE_LOGIC_NOOP:
case GE_LOGIC_NOOP: srcBlend = BlendFactor::ZERO;
srcBlend = BlendFactor::ZERO; dstBlend = BlendFactor::ONE;
dstBlend = BlendFactor::ONE; blendEq = BlendEq::ADD;
blendEq = BlendEq::ADD; return true;
return true; case GE_LOGIC_XOR:
case GE_LOGIC_XOR: WARN_LOG_REPORT_ONCE(d3dLogicOpOrXor, G3D, "Unsupported XOR logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpOrXor, G3D, "Unsupported XOR logic op: %x", gstate.getLogicOp()); break;
break; case GE_LOGIC_OR:
case GE_LOGIC_OR: case GE_LOGIC_OR_INVERTED:
case GE_LOGIC_OR_INVERTED: // Inverted in shader.
// Inverted in shader. srcBlend = BlendFactor::ONE;
srcBlend = BlendFactor::ONE; dstBlend = BlendFactor::ONE;
dstBlend = BlendFactor::ONE; blendEq = BlendEq::ADD;
blendEq = BlendEq::ADD; WARN_LOG_REPORT_ONCE(d3dLogicOpOr, G3D, "Attempted or for logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpOr, G3D, "Attempted or for logic op: %x", gstate.getLogicOp()); return true;
return true; case GE_LOGIC_OR_REVERSE:
case GE_LOGIC_OR_REVERSE: WARN_LOG_REPORT_ONCE(d3dLogicOpOrReverse, G3D, "Unsupported OR REVERSE logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpOrReverse, G3D, "Unsupported OR REVERSE logic op: %x", gstate.getLogicOp()); break;
break; case GE_LOGIC_SET:
case GE_LOGIC_SET: srcBlend = BlendFactor::ONE;
srcBlend = BlendFactor::ONE; dstBlend = BlendFactor::ONE;
dstBlend = BlendFactor::ONE; blendEq = BlendEq::ADD;
blendEq = BlendEq::ADD; WARN_LOG_REPORT_ONCE(d3dLogicOpSet, G3D, "Attempted set for logic op: %x", gstate.getLogicOp());
WARN_LOG_REPORT_ONCE(d3dLogicOpSet, G3D, "Attempted set for logic op: %x", gstate.getLogicOp()); return true;
return true;
}
} }
} }
return false; return false;
} }
@ -1080,6 +1077,12 @@ static void ConvertBlendState(GenericBlendState &blendState, bool forceReplaceBl
case REPLACE_BLEND_NO: case REPLACE_BLEND_NO:
// We may still want to do something about stencil -> alpha. // We may still want to do something about stencil -> alpha.
ApplyStencilReplaceAndLogicOpIgnoreBlend(replaceAlphaWithStencil, blendState); ApplyStencilReplaceAndLogicOpIgnoreBlend(replaceAlphaWithStencil, blendState);
if (forceReplaceBlend) {
// If this is true, the logic and mask replacements will be applied, at least. In that case,
// we should not apply any logic op simulation.
blendState.simulateLogicOpType = LOGICOPTYPE_NORMAL;
}
return; return;
case REPLACE_BLEND_BLUE_TO_ALPHA: case REPLACE_BLEND_BLUE_TO_ALPHA:

View file

@ -292,11 +292,14 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac
SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
SamplerCacheKey key = GetSamplingParams(0, nullptr); SamplerCacheKey key = GetSamplingParams(0, nullptr);
// Kill any mipmapping settings. // Kill any mipmapping settings, and reset min filtering.
int minFilt = gstate.texfilter & 0x7;
key.minFilt = minFilt & 1;
key.mipEnable = false; key.mipEnable = false;
key.mipFilt = false; key.mipFilt = false;
key.aniso = 0.0; key.aniso = 0.0;
key.maxLevel = 0.0f; key.maxLevel = 0.0f;
key.lodBias = 0.0f;
// Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case.
int w = gstate.getTextureWidth(0); int w = gstate.getTextureWidth(0);