diff options
| author | TellowKrinkle <tellowkrinkle@gmail.com> | 2022-07-13 03:56:33 -0500 |
|---|---|---|
| committer | TellowKrinkle <tellowkrinkle@gmail.com> | 2023-01-30 14:04:37 -0600 |
| commit | 600ad5f49832a69efe0ebd5ca7a19d3a82f7a319 (patch) | |
| tree | 2f5568e49c52891274850bf28a37c815fb9f1fad /Source/Core/VideoCommon/RenderState.cpp | |
| parent | d380d43209ce046d30af398ca3ecfc6fdd5a47d1 (diff) | |
VideoCommon: Better logic op invert approximation
Diffstat (limited to 'Source/Core/VideoCommon/RenderState.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/RenderState.cpp | 83 |
1 files changed, 61 insertions, 22 deletions
diff --git a/Source/Core/VideoCommon/RenderState.cpp b/Source/Core/VideoCommon/RenderState.cpp index 85e9adee15..d04733349f 100644 --- a/Source/Core/VideoCommon/RenderState.cpp +++ b/Source/Core/VideoCommon/RenderState.cpp @@ -185,6 +185,7 @@ void BlendingState::ApproximateLogicOpWithBlending() { struct LogicOpApproximation { + bool blendEnable; bool subtract; SrcBlendFactor srcfactor; DstBlendFactor dstfactor; @@ -193,31 +194,69 @@ void BlendingState::ApproximateLogicOpWithBlending() // but INVSRCCLR and INVDSTCLR were also aliased and were mixed. // Thus, NOR, EQUIV, INVERT, COPY_INVERTED, and OR_INVERTED duplicate(d) other values. static constexpr std::array<LogicOpApproximation, 16> approximations = {{ - {false, SrcBlendFactor::Zero, DstBlendFactor::Zero}, // CLEAR - {false, SrcBlendFactor::DstClr, DstBlendFactor::Zero}, // AND - {true, SrcBlendFactor::One, DstBlendFactor::InvSrcClr}, // AND_REVERSE - {false, SrcBlendFactor::One, DstBlendFactor::Zero}, // COPY - {true, SrcBlendFactor::DstClr, DstBlendFactor::One}, // AND_INVERTED - {false, SrcBlendFactor::Zero, DstBlendFactor::One}, // NOOP - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // XOR - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NOR - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::Zero}, // EQUIV - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // INVERT - {false, SrcBlendFactor::One, DstBlendFactor::InvDstAlpha}, // OR_REVERSE - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // COPY_INVERTED - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR_INVERTED - {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NAND - {false, SrcBlendFactor::One, DstBlendFactor::One}, // SET + // clang-format off + {false, false, SrcBlendFactor::One, DstBlendFactor::Zero}, // CLEAR (Shader outputs 0) + {true, false, SrcBlendFactor::DstClr, DstBlendFactor::Zero}, // AND + {true, true, SrcBlendFactor::One, DstBlendFactor::InvSrcClr}, // AND_REVERSE + {false, false, SrcBlendFactor::One, DstBlendFactor::Zero}, // COPY + {true, true, SrcBlendFactor::DstClr, DstBlendFactor::One}, // AND_INVERTED + {true, false, SrcBlendFactor::Zero, DstBlendFactor::One}, // NOOP + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // XOR + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NOR + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::Zero}, // EQUIV + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::Zero}, // INVERT (Shader outputs 255) + {true, false, SrcBlendFactor::One, DstBlendFactor::InvDstAlpha}, // OR_REVERSE + {false, false, SrcBlendFactor::One, DstBlendFactor::Zero}, // COPY_INVERTED (Shader inverts) + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR_INVERTED + {true, false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NAND + {false, false, SrcBlendFactor::One, DstBlendFactor::Zero}, // SET (Shader outputs 255) + // clang-format on }}; logicopenable = false; - blendenable = true; - subtract = approximations[u32(logicmode.Value())].subtract; - srcfactor = approximations[u32(logicmode.Value())].srcfactor; - srcfactoralpha = approximations[u32(logicmode.Value())].srcfactor; - dstfactor = approximations[u32(logicmode.Value())].dstfactor; - dstfactoralpha = approximations[u32(logicmode.Value())].dstfactor; + usedualsrc = false; + const LogicOpApproximation& approximation = approximations[static_cast<u32>(logicmode.Value())]; + if (approximation.blendEnable) + { + blendenable = true; + subtract = approximation.subtract; + srcfactor = approximation.srcfactor; + srcfactoralpha = approximation.srcfactor; + dstfactor = approximation.dstfactor; + dstfactoralpha = approximation.dstfactor; + } +} + +bool BlendingState::LogicOpApproximationIsExact() +{ + switch (logicmode.Value()) + { + case LogicOp::Clear: + case LogicOp::Set: + case LogicOp::NoOp: + case LogicOp::Invert: + case LogicOp::CopyInverted: + case LogicOp::Copy: + return true; + default: + return false; + } +} + +bool BlendingState::LogicOpApproximationWantsShaderHelp() +{ + switch (logicmode.Value()) + { + case LogicOp::Clear: + case LogicOp::Set: + case LogicOp::NoOp: + case LogicOp::Invert: + case LogicOp::CopyInverted: + return true; + default: + return false; + } } void SamplerState::Generate(const BPMemory& bp, u32 index) |
