OGL: Use VideoCommon blend state for framebuffer configuration.
This commit is contained in:
parent
3df828463d
commit
23b0faeba5
|
@ -39,6 +39,7 @@
|
|||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/PixelEngine.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/RenderState.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
|
@ -63,8 +64,6 @@ static int s_last_multisamples = 1;
|
|||
static bool s_last_stereo_mode = false;
|
||||
static bool s_last_xfb_mode = false;
|
||||
|
||||
static u32 s_blendMode;
|
||||
|
||||
static bool s_vsync;
|
||||
|
||||
// EFB cache related
|
||||
|
@ -328,8 +327,6 @@ static void InitDriverInfo()
|
|||
// Init functions
|
||||
Renderer::Renderer()
|
||||
{
|
||||
s_blendMode = 0;
|
||||
|
||||
bool bSuccess = true;
|
||||
|
||||
// Init extension support.
|
||||
|
@ -832,20 +829,6 @@ void Renderer::SetScissorRect(const EFBRectangle& rc)
|
|||
glScissor(trc.left, trc.bottom, trc.GetWidth(), trc.GetHeight());
|
||||
}
|
||||
|
||||
void Renderer::SetColorMask()
|
||||
{
|
||||
// Only enable alpha channel if it's supported by the current EFB format
|
||||
GLenum ColorMask = GL_FALSE, AlphaMask = GL_FALSE;
|
||||
if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL)
|
||||
{
|
||||
if (bpmem.blendmode.colorupdate)
|
||||
ColorMask = GL_TRUE;
|
||||
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24))
|
||||
AlphaMask = GL_TRUE;
|
||||
}
|
||||
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
|
||||
}
|
||||
|
||||
void ClearEFBCache()
|
||||
{
|
||||
if (!s_efbCacheIsCleared)
|
||||
|
@ -1224,111 +1207,72 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
|
|||
|
||||
void Renderer::SetBlendMode(bool forceUpdate)
|
||||
{
|
||||
// Our render target always uses an alpha channel, so we need to override the blend functions to
|
||||
// assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
|
||||
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel
|
||||
// is assumed to always be 1.
|
||||
bool target_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
||||
BlendingState state;
|
||||
state.Generate(bpmem);
|
||||
|
||||
bool useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha;
|
||||
bool useDualSource = g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
|
||||
bool useDualSource =
|
||||
g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
|
||||
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha);
|
||||
|
||||
// Only use dual-source blending when required on drivers that don't support it very well.
|
||||
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) && !useDstAlpha)
|
||||
useDualSource = false;
|
||||
|
||||
const GLenum glSrcFactors[8] = {
|
||||
const GLenum src_factors[8] = {
|
||||
GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_DST_COLOR,
|
||||
GL_ONE_MINUS_DST_COLOR,
|
||||
(useDualSource) ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||
(useDualSource) ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||
(target_has_alpha) ? GL_DST_ALPHA : (GLenum)GL_ONE,
|
||||
(target_has_alpha) ? GL_ONE_MINUS_DST_ALPHA : (GLenum)GL_ZERO};
|
||||
const GLenum glDestFactors[8] = {
|
||||
useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||
useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||
GL_DST_ALPHA,
|
||||
GL_ONE_MINUS_DST_ALPHA};
|
||||
const GLenum dst_factors[8] = {
|
||||
GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_SRC_COLOR,
|
||||
GL_ONE_MINUS_SRC_COLOR,
|
||||
(useDualSource) ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||
(useDualSource) ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||
(target_has_alpha) ? GL_DST_ALPHA : (GLenum)GL_ONE,
|
||||
(target_has_alpha) ? GL_ONE_MINUS_DST_ALPHA : (GLenum)GL_ZERO};
|
||||
useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||
useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||
GL_DST_ALPHA,
|
||||
GL_ONE_MINUS_DST_ALPHA};
|
||||
|
||||
// blend mode bit mask
|
||||
// 0 - blend enable
|
||||
// 1 - dst alpha enabled
|
||||
// 2 - reverse subtract enable (else add)
|
||||
// 3-5 - srcRGB function
|
||||
// 6-8 - dstRGB function
|
||||
|
||||
u32 newval = useDstAlpha << 1;
|
||||
newval |= bpmem.blendmode.subtract << 2;
|
||||
|
||||
if (bpmem.blendmode.subtract)
|
||||
if (state.blendenable)
|
||||
{
|
||||
newval |= 0x0049; // enable blending src 1 dst 1
|
||||
}
|
||||
else if (bpmem.blendmode.blendenable)
|
||||
{
|
||||
newval |= 1; // enable blending
|
||||
newval |= bpmem.blendmode.srcfactor << 3;
|
||||
newval |= bpmem.blendmode.dstfactor << 6;
|
||||
}
|
||||
|
||||
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
|
||||
|
||||
if (changes & 1)
|
||||
{
|
||||
// blend enable change
|
||||
(newval & 1) ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if (changes & 4)
|
||||
{
|
||||
// subtract enable change
|
||||
GLenum equation = newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||
GLenum equationAlpha = useDstAlpha ? GL_FUNC_ADD : equation;
|
||||
GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||
GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquationSeparate(equation, equationAlpha);
|
||||
glBlendFuncSeparate(src_factors[state.srcfactor], dst_factors[state.dstfactor],
|
||||
src_factors[state.srcfactoralpha], dst_factors[state.dstfactoralpha]);
|
||||
}
|
||||
|
||||
if (changes & 0x1FA)
|
||||
else
|
||||
{
|
||||
u32 srcidx = (newval >> 3) & 7;
|
||||
u32 dstidx = (newval >> 6) & 7;
|
||||
GLenum srcFactor = glSrcFactors[srcidx];
|
||||
GLenum dstFactor = glDestFactors[dstidx];
|
||||
|
||||
// adjust alpha factors
|
||||
if (useDstAlpha)
|
||||
{
|
||||
srcidx = BlendMode::ONE;
|
||||
dstidx = BlendMode::ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we can't use GL_DST_COLOR or GL_ONE_MINUS_DST_COLOR for source in alpha channel so use
|
||||
// their alpha equivalent instead
|
||||
if (srcidx == BlendMode::DSTCLR)
|
||||
srcidx = BlendMode::DSTALPHA;
|
||||
else if (srcidx == BlendMode::INVDSTCLR)
|
||||
srcidx = BlendMode::INVDSTALPHA;
|
||||
|
||||
// we can't use GL_SRC_COLOR or GL_ONE_MINUS_SRC_COLOR for destination in alpha channel so use
|
||||
// their alpha equivalent instead
|
||||
if (dstidx == BlendMode::SRCCLR)
|
||||
dstidx = BlendMode::SRCALPHA;
|
||||
else if (dstidx == BlendMode::INVSRCCLR)
|
||||
dstidx = BlendMode::INVSRCALPHA;
|
||||
}
|
||||
GLenum srcFactorAlpha = glSrcFactors[srcidx];
|
||||
GLenum dstFactorAlpha = glDestFactors[dstidx];
|
||||
// blend RGB change
|
||||
glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
s_blendMode = newval;
|
||||
|
||||
const GLenum logic_op_codes[16] = {
|
||||
GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP,
|
||||
GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE,
|
||||
GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET};
|
||||
|
||||
if (GLInterface->GetMode() != GLInterfaceMode::MODE_OPENGL)
|
||||
{
|
||||
// Logic ops aren't available in GLES3
|
||||
}
|
||||
else if (state.logicopenable)
|
||||
{
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(logic_op_codes[state.logicmode]);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
}
|
||||
|
||||
if (state.dither)
|
||||
glEnable(GL_DITHER);
|
||||
else
|
||||
glDisable(GL_DITHER);
|
||||
|
||||
glColorMask(state.colorupdate, state.colorupdate, state.colorupdate, state.alphaupdate);
|
||||
}
|
||||
|
||||
// This function has the final picture. We adjust the aspect ratio here.
|
||||
|
@ -1783,10 +1727,8 @@ void Renderer::RestoreAPIState()
|
|||
}
|
||||
SetGenerationMode();
|
||||
BPFunctions::SetScissor();
|
||||
SetColorMask();
|
||||
SetDepthMode();
|
||||
SetBlendMode(true);
|
||||
SetLogicOpMode();
|
||||
SetViewport();
|
||||
|
||||
const VertexManager* const vm = static_cast<VertexManager*>(g_vertex_manager.get());
|
||||
|
@ -1833,35 +1775,6 @@ void Renderer::SetDepthMode()
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer::SetLogicOpMode()
|
||||
{
|
||||
if (GLInterface->GetMode() != GLInterfaceMode::MODE_OPENGL)
|
||||
return;
|
||||
// Logic ops aren't available in GLES3/GLES2
|
||||
const GLenum glLogicOpCodes[16] = {
|
||||
GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP,
|
||||
GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE,
|
||||
GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET};
|
||||
|
||||
if (bpmem.blendmode.logicopenable && !bpmem.blendmode.blendenable)
|
||||
{
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(glLogicOpCodes[bpmem.blendmode.logicmode]);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::SetDitherMode()
|
||||
{
|
||||
if (bpmem.blendmode.dither)
|
||||
glEnable(GL_DITHER);
|
||||
else
|
||||
glDisable(GL_DITHER);
|
||||
}
|
||||
|
||||
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
||||
{
|
||||
auto const& tex = bpmem.tex[texindex];
|
||||
|
|
|
@ -72,13 +72,10 @@ public:
|
|||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
void SetColorMask() override;
|
||||
void SetBlendMode(bool forceUpdate) override;
|
||||
void SetScissorRect(const EFBRectangle& rc) override;
|
||||
void SetGenerationMode() override;
|
||||
void SetDepthMode() override;
|
||||
void SetLogicOpMode() override;
|
||||
void SetDitherMode() override;
|
||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||
void SetInterlacingMode() override;
|
||||
void SetViewport() override;
|
||||
|
|
|
@ -142,6 +142,10 @@ static void BPWritten(const BPCmd& bp)
|
|||
(int)bpmem.blendmode.dstfactor, (int)bpmem.blendmode.srcfactor,
|
||||
(int)bpmem.blendmode.subtract, (int)bpmem.blendmode.logicmode);
|
||||
|
||||
// Set Blending Mode
|
||||
if (bp.changes)
|
||||
SetBlendMode();
|
||||
|
||||
// Set LogicOp Blending Mode
|
||||
if (bp.changes & 0xF002) // logicopenable | logicmode
|
||||
SetLogicOpMode();
|
||||
|
@ -150,10 +154,6 @@ static void BPWritten(const BPCmd& bp)
|
|||
if (bp.changes & 4) // dither
|
||||
SetDitherMode();
|
||||
|
||||
// Set Blending Mode
|
||||
if (bp.changes & 0xFF1) // blendenable | alphaupdate | dstfactor | srcfactor | subtract
|
||||
SetBlendMode();
|
||||
|
||||
// Set Color Mask
|
||||
if (bp.changes & 0x18) // colorupdate | alphaupdate
|
||||
SetColorMask();
|
||||
|
@ -316,7 +316,10 @@ static void BPWritten(const BPCmd& bp)
|
|||
if (bp.changes & 0xFFFF)
|
||||
PixelShaderManager::SetAlpha();
|
||||
if (bp.changes)
|
||||
{
|
||||
g_renderer->SetColorMask();
|
||||
SetBlendMode();
|
||||
}
|
||||
return;
|
||||
case BPMEM_BIAS: // BIAS
|
||||
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
|
||||
|
|
Loading…
Reference in New Issue