VideoCommon: copy software renderer logic for blend mode priorities

I've not tested this on hardware, but it fixes issue 12271 (shadow
people in Deal or No Deal - Special Edition).
This commit is contained in:
Tillmann Karras 2023-11-12 05:47:22 +00:00
parent f35ee22755
commit ac9079f2ca
2 changed files with 37 additions and 39 deletions

View File

@ -11,8 +11,8 @@ BPMemory bpmem;
bool BlendMode::UseLogicOp() const bool BlendMode::UseLogicOp() const
{ {
// Logicop bit has lowest priority. // Blending overrides the logicop bit.
if (subtract || blendenable || !logicopenable) if (blendenable || !logicopenable)
return false; return false;
// Fast path for Kirby's Return to Dreamland, they use it with dstAlpha. // Fast path for Kirby's Return to Dreamland, they use it with dstAlpha.

View File

@ -120,47 +120,45 @@ void BlendingState::Generate(const BPMemory& bp)
const bool dstalpha = bp.dstalpha.enable && alphaupdate; const bool dstalpha = bp.dstalpha.enable && alphaupdate;
usedualsrc = true; usedualsrc = true;
// The subtract bit has the highest priority if (bp.blendmode.blendenable)
if (bp.blendmode.subtract)
{ {
blendenable = true; if (bp.blendmode.subtract)
subtractAlpha = subtract = true;
srcfactoralpha = srcfactor = SrcBlendFactor::One;
dstfactoralpha = dstfactor = DstBlendFactor::One;
if (dstalpha)
{ {
subtractAlpha = false; blendenable = true;
srcfactoralpha = SrcBlendFactor::One; subtractAlpha = subtract = true;
dstfactoralpha = DstBlendFactor::Zero; srcfactoralpha = srcfactor = SrcBlendFactor::One;
dstfactoralpha = dstfactor = DstBlendFactor::One;
if (dstalpha)
{
subtractAlpha = false;
srcfactoralpha = SrcBlendFactor::One;
dstfactoralpha = DstBlendFactor::Zero;
}
}
else
{
blendenable = true;
srcfactor = bp.blendmode.srcfactor;
dstfactor = bp.blendmode.dstfactor;
if (!target_has_alpha)
{
// uses ONE instead of DSTALPHA
srcfactor = RemoveDstAlphaUsage(srcfactor);
dstfactor = RemoveDstAlphaUsage(dstfactor);
}
// replaces SrcClr with SrcAlpha and DstClr with DstAlpha, it is important to
// use the dst function for the src factor and vice versa
srcfactoralpha = RemoveDstColorUsage(srcfactor);
dstfactoralpha = RemoveSrcColorUsage(dstfactor);
if (dstalpha)
{
srcfactoralpha = SrcBlendFactor::One;
dstfactoralpha = DstBlendFactor::Zero;
}
} }
} }
// The blendenable bit has the middle priority
else if (bp.blendmode.blendenable)
{
blendenable = true;
srcfactor = bp.blendmode.srcfactor;
dstfactor = bp.blendmode.dstfactor;
if (!target_has_alpha)
{
// uses ONE instead of DSTALPHA
srcfactor = RemoveDstAlphaUsage(srcfactor);
dstfactor = RemoveDstAlphaUsage(dstfactor);
}
// replaces SrcClr with SrcAlpha and DstClr with DstAlpha, it is important to
// use the dst function for the src factor and vice versa
srcfactoralpha = RemoveDstColorUsage(srcfactor);
dstfactoralpha = RemoveSrcColorUsage(dstfactor);
if (dstalpha)
{
srcfactoralpha = SrcBlendFactor::One;
dstfactoralpha = DstBlendFactor::Zero;
}
}
// The logicop bit has the lowest priority
else if (bp.blendmode.logicopenable) else if (bp.blendmode.logicopenable)
{ {
if (bp.blendmode.logicmode == LogicOp::NoOp) if (bp.blendmode.logicmode == LogicOp::NoOp)