From f6f9dc0cacb0dcbbd09d31acbb6e3a3ece764541 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 2 Aug 2019 19:20:36 +1000 Subject: RenderState: Approximate logic op with blending if unsupported This is a giant hack which was previously removed because it causes broken rendering. However, it seems that some devices still do not support logical operations (looking at you, Adreno/Mali). Therefore, for a handful of cases where the hack actually makes things slightly better, we can use it. ... but not without spamming the log with warnings. With my warning message PR, we can inform the users before emulation starts anyway. --- Source/Core/VideoCommon/RenderState.cpp | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'Source/Core/VideoCommon/RenderState.cpp') diff --git a/Source/Core/VideoCommon/RenderState.cpp b/Source/Core/VideoCommon/RenderState.cpp index 04d8804f0c..6d6f892979 100644 --- a/Source/Core/VideoCommon/RenderState.cpp +++ b/Source/Core/VideoCommon/RenderState.cpp @@ -167,6 +167,42 @@ void BlendingState::Generate(const BPMemory& bp) } } +void BlendingState::ApproximateLogicOpWithBlending() +{ + // Any of these which use SRC as srcFactor or DST as dstFactor won't be correct. + // This is because the two are aliased to one another (see the enum). + struct LogicOpApproximation + { + bool subtract; + BlendMode::BlendFactor srcfactor; + BlendMode::BlendFactor dstfactor; + }; + static constexpr std::array approximations = {{ + {false, BlendMode::ZERO, BlendMode::ZERO}, // CLEAR + {false, BlendMode::DSTCLR, BlendMode::ZERO}, // AND + {true, BlendMode::ONE, BlendMode::INVSRCCLR}, // AND_REVERSE + {false, BlendMode::ONE, BlendMode::ZERO}, // COPY + {true, BlendMode::DSTCLR, BlendMode::ONE}, // AND_INVERTED + {false, BlendMode::ZERO, BlendMode::ONE}, // NOOP + {false, BlendMode::INVDSTCLR, BlendMode::INVSRCCLR}, // XOR + {false, BlendMode::INVDSTCLR, BlendMode::ONE}, // OR + {false, BlendMode::INVSRCCLR, BlendMode::INVDSTCLR}, // NOR + {false, BlendMode::INVSRCCLR, BlendMode::ZERO}, // EQUIV + {false, BlendMode::INVDSTCLR, BlendMode::INVDSTCLR}, // INVERT + {false, BlendMode::ONE, BlendMode::INVDSTALPHA}, // OR_REVERSE + {false, BlendMode::INVSRCCLR, BlendMode::INVSRCCLR}, // COPY_INVERTED + {false, BlendMode::INVSRCCLR, BlendMode::ONE}, // OR_INVERTED + {false, BlendMode::INVDSTCLR, BlendMode::INVSRCCLR}, // NAND + {false, BlendMode::ONE, BlendMode::ONE}, // SET + }}; + + logicopenable = false; + blendenable = true; + subtract = approximations[logicmode].subtract; + srcfactor = approximations[logicmode].srcfactor; + dstfactor = approximations[logicmode].dstfactor; +} + BlendingState& BlendingState::operator=(const BlendingState& rhs) { hex = rhs.hex; -- cgit v1.2.3