mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 05:40:01 -06:00
Merge pull request #8284 from stenzek/logic-op-hack
RenderState: Approximate logic op with blending if unsupported
This commit is contained in:
@ -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<LogicOpApproximation, 16> 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)
|
BlendingState& BlendingState::operator=(const BlendingState& rhs)
|
||||||
{
|
{
|
||||||
hex = rhs.hex;
|
hex = rhs.hex;
|
||||||
|
@ -68,6 +68,10 @@ union BlendingState
|
|||||||
{
|
{
|
||||||
void Generate(const BPMemory& bp);
|
void Generate(const BPMemory& bp);
|
||||||
|
|
||||||
|
// HACK: Replaces logical operations with blend operations.
|
||||||
|
// Will not be bit-correct, and in some cases not even remotely in the same ballpark.
|
||||||
|
void ApproximateLogicOpWithBlending();
|
||||||
|
|
||||||
BlendingState& operator=(const BlendingState& rhs);
|
BlendingState& operator=(const BlendingState& rhs);
|
||||||
|
|
||||||
bool operator==(const BlendingState& rhs) const { return hex == rhs.hex; }
|
bool operator==(const BlendingState& rhs) const { return hex == rhs.hex; }
|
||||||
|
@ -558,6 +558,13 @@ AbstractPipelineConfig ShaderCache::GetGXPipelineConfig(
|
|||||||
config.depth_state = depth_state;
|
config.depth_state = depth_state;
|
||||||
config.blending_state = blending_state;
|
config.blending_state = blending_state;
|
||||||
config.framebuffer_state = g_framebuffer_manager->GetEFBFramebufferState();
|
config.framebuffer_state = g_framebuffer_manager->GetEFBFramebufferState();
|
||||||
|
|
||||||
|
if (config.blending_state.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp)
|
||||||
|
{
|
||||||
|
WARN_LOG(VIDEO, "Approximating logic op with blending, this will produce incorrect rendering.");
|
||||||
|
config.blending_state.ApproximateLogicOpWithBlending();
|
||||||
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user