Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
VideoCommon: Assembly blending state in a shared state object.
- Loading branch information
Showing
5 changed files
with
161 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Copyright 2016 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#include "VideoCommon/RenderState.h" | ||
|
||
// If the framebuffer format has no alpha channel, it is assumed to | ||
// ONE on blending. As the backends may emulate this framebuffer | ||
// configuration with an alpha channel, we just drop all references | ||
// to the destination alpha channel. | ||
static BlendMode::BlendFactor RemoveDstAlphaUsage(BlendMode::BlendFactor factor) | ||
{ | ||
switch (factor) | ||
{ | ||
case BlendMode::DSTALPHA: | ||
return BlendMode::ONE; | ||
case BlendMode::INVDSTALPHA: | ||
return BlendMode::ZERO; | ||
default: | ||
return factor; | ||
} | ||
} | ||
|
||
// We separate the blending parameter for rgb and alpha. For blending | ||
// the alpha component, CLR and ALPHA are indentical. So just always | ||
// use ALPHA as this makes it easier for the backends to use the second | ||
// alpha value of dual source blending. | ||
static BlendMode::BlendFactor RemoveSrcColorUsage(BlendMode::BlendFactor factor) | ||
{ | ||
switch (factor) | ||
{ | ||
case BlendMode::SRCCLR: | ||
return BlendMode::SRCALPHA; | ||
case BlendMode::INVSRCCLR: | ||
return BlendMode::INVSRCALPHA; | ||
default: | ||
return factor; | ||
} | ||
} | ||
|
||
// Same as RemoveSrcColorUsage, but because of the overlapping enum, | ||
// this must be written as another function. | ||
static BlendMode::BlendFactor RemoveDstColorUsage(BlendMode::BlendFactor factor) | ||
{ | ||
switch (factor) | ||
{ | ||
case BlendMode::DSTCLR: | ||
return BlendMode::DSTALPHA; | ||
case BlendMode::INVDSTCLR: | ||
return BlendMode::INVDSTALPHA; | ||
default: | ||
return factor; | ||
} | ||
} | ||
|
||
void BlendingState::Generate(const BPMemory& bp) | ||
{ | ||
// Start with everything disabled. | ||
hex = 0; | ||
|
||
bool target_has_alpha = bp.zcontrol.pixel_format == PEControl::RGBA6_Z24; | ||
bool alpha_test_may_success = bp.alpha_test.TestResult() != AlphaTest::FAIL; | ||
|
||
dither = bp.blendmode.dither; | ||
colorupdate = bp.blendmode.colorupdate && alpha_test_may_success; | ||
alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_success; | ||
dstalpha = bp.dstalpha.enable && alphaupdate; | ||
|
||
// The subtract bit has the highest priority | ||
if (bp.blendmode.subtract) | ||
{ | ||
blendenable = true; | ||
subtractAlpha = subtract = true; | ||
srcfactoralpha = srcfactor = BlendMode::ONE; | ||
dstfactoralpha = dstfactor = BlendMode::ONE; | ||
|
||
if (dstalpha) | ||
{ | ||
subtractAlpha = false; | ||
srcfactoralpha = BlendMode::ONE; | ||
dstfactoralpha = BlendMode::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 | ||
srcfactoralpha = RemoveSrcColorUsage(srcfactor); | ||
dstfactoralpha = RemoveDstColorUsage(dstfactor); | ||
|
||
if (dstalpha) | ||
{ | ||
srcfactoralpha = BlendMode::ONE; | ||
dstfactoralpha = BlendMode::ZERO; | ||
} | ||
} | ||
|
||
// The logicop bit has the lowest priority | ||
else if (bp.blendmode.logicopenable) | ||
{ | ||
logicopenable = true; | ||
logicmode = bp.blendmode.logicmode; | ||
|
||
if (dstalpha) | ||
{ | ||
// TODO: Not supported by backends. | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright 2016 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#pragma once | ||
|
||
#include "Common/BitField.h" | ||
|
||
#include "VideoCommon/BPMemory.h" | ||
#include "VideoCommon/BPStructs.h" | ||
|
||
union BlendingState | ||
{ | ||
void Generate(const BPMemory& bp); | ||
|
||
BitField<0, 1, u32> blendenable; | ||
BitField<1, 1, u32> logicopenable; | ||
BitField<2, 1, u32> dstalpha; | ||
BitField<3, 1, u32> dither; | ||
BitField<4, 1, u32> colorupdate; | ||
BitField<5, 1, u32> alphaupdate; | ||
BitField<6, 1, u32> subtract; | ||
BitField<7, 1, u32> subtractAlpha; | ||
BitField<8, 3, BlendMode::BlendFactor> dstfactor; | ||
BitField<11, 3, BlendMode::BlendFactor> srcfactor; | ||
BitField<14, 3, BlendMode::BlendFactor> dstfactoralpha; | ||
BitField<17, 3, BlendMode::BlendFactor> srcfactoralpha; | ||
BitField<20, 4, BlendMode::LogicOp> logicmode; | ||
|
||
u32 hex; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters