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/OnScreenDisplay.h"
|
||||||
#include "VideoCommon/PixelEngine.h"
|
#include "VideoCommon/PixelEngine.h"
|
||||||
#include "VideoCommon/PixelShaderManager.h"
|
#include "VideoCommon/PixelShaderManager.h"
|
||||||
|
#include "VideoCommon/RenderState.h"
|
||||||
#include "VideoCommon/VertexShaderManager.h"
|
#include "VideoCommon/VertexShaderManager.h"
|
||||||
#include "VideoCommon/VideoConfig.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_stereo_mode = false;
|
||||||
static bool s_last_xfb_mode = false;
|
static bool s_last_xfb_mode = false;
|
||||||
|
|
||||||
static u32 s_blendMode;
|
|
||||||
|
|
||||||
static bool s_vsync;
|
static bool s_vsync;
|
||||||
|
|
||||||
// EFB cache related
|
// EFB cache related
|
||||||
|
@ -328,8 +327,6 @@ static void InitDriverInfo()
|
||||||
// Init functions
|
// Init functions
|
||||||
Renderer::Renderer()
|
Renderer::Renderer()
|
||||||
{
|
{
|
||||||
s_blendMode = 0;
|
|
||||||
|
|
||||||
bool bSuccess = true;
|
bool bSuccess = true;
|
||||||
|
|
||||||
// Init extension support.
|
// Init extension support.
|
||||||
|
@ -832,20 +829,6 @@ void Renderer::SetScissorRect(const EFBRectangle& rc)
|
||||||
glScissor(trc.left, trc.bottom, trc.GetWidth(), trc.GetHeight());
|
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()
|
void ClearEFBCache()
|
||||||
{
|
{
|
||||||
if (!s_efbCacheIsCleared)
|
if (!s_efbCacheIsCleared)
|
||||||
|
@ -1224,111 +1207,72 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
|
||||||
|
|
||||||
void Renderer::SetBlendMode(bool forceUpdate)
|
void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
{
|
{
|
||||||
// Our render target always uses an alpha channel, so we need to override the blend functions to
|
BlendingState state;
|
||||||
// assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
|
state.Generate(bpmem);
|
||||||
// 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;
|
|
||||||
|
|
||||||
bool useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha;
|
bool useDualSource =
|
||||||
bool useDualSource = g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
|
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.
|
const GLenum src_factors[8] = {
|
||||||
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) && !useDstAlpha)
|
|
||||||
useDualSource = false;
|
|
||||||
|
|
||||||
const GLenum glSrcFactors[8] = {
|
|
||||||
GL_ZERO,
|
GL_ZERO,
|
||||||
GL_ONE,
|
GL_ONE,
|
||||||
GL_DST_COLOR,
|
GL_DST_COLOR,
|
||||||
GL_ONE_MINUS_DST_COLOR,
|
GL_ONE_MINUS_DST_COLOR,
|
||||||
(useDualSource) ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||||
(useDualSource) ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||||
(target_has_alpha) ? GL_DST_ALPHA : (GLenum)GL_ONE,
|
GL_DST_ALPHA,
|
||||||
(target_has_alpha) ? GL_ONE_MINUS_DST_ALPHA : (GLenum)GL_ZERO};
|
GL_ONE_MINUS_DST_ALPHA};
|
||||||
const GLenum glDestFactors[8] = {
|
const GLenum dst_factors[8] = {
|
||||||
GL_ZERO,
|
GL_ZERO,
|
||||||
GL_ONE,
|
GL_ONE,
|
||||||
GL_SRC_COLOR,
|
GL_SRC_COLOR,
|
||||||
GL_ONE_MINUS_SRC_COLOR,
|
GL_ONE_MINUS_SRC_COLOR,
|
||||||
(useDualSource) ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
|
||||||
(useDualSource) ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : (GLenum)GL_ONE_MINUS_SRC_ALPHA,
|
||||||
(target_has_alpha) ? GL_DST_ALPHA : (GLenum)GL_ONE,
|
GL_DST_ALPHA,
|
||||||
(target_has_alpha) ? GL_ONE_MINUS_DST_ALPHA : (GLenum)GL_ZERO};
|
GL_ONE_MINUS_DST_ALPHA};
|
||||||
|
|
||||||
// blend mode bit mask
|
if (state.blendenable)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
newval |= 0x0049; // enable blending src 1 dst 1
|
GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||||
}
|
GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
|
||||||
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;
|
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
glBlendEquationSeparate(equation, equationAlpha);
|
glBlendEquationSeparate(equation, equationAlpha);
|
||||||
}
|
glBlendFuncSeparate(src_factors[state.srcfactor], dst_factors[state.dstfactor],
|
||||||
|
src_factors[state.srcfactoralpha], dst_factors[state.dstfactoralpha]);
|
||||||
if (changes & 0x1FA)
|
|
||||||
{
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
// we can't use GL_DST_COLOR or GL_ONE_MINUS_DST_COLOR for source in alpha channel so use
|
glDisable(GL_BLEND);
|
||||||
// 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
|
const GLenum logic_op_codes[16] = {
|
||||||
// their alpha equivalent instead
|
GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP,
|
||||||
if (dstidx == BlendMode::SRCCLR)
|
GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE,
|
||||||
dstidx = BlendMode::SRCALPHA;
|
GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET};
|
||||||
else if (dstidx == BlendMode::INVSRCCLR)
|
|
||||||
dstidx = BlendMode::INVSRCALPHA;
|
if (GLInterface->GetMode() != GLInterfaceMode::MODE_OPENGL)
|
||||||
|
{
|
||||||
|
// Logic ops aren't available in GLES3
|
||||||
}
|
}
|
||||||
GLenum srcFactorAlpha = glSrcFactors[srcidx];
|
else if (state.logicopenable)
|
||||||
GLenum dstFactorAlpha = glDestFactors[dstidx];
|
{
|
||||||
// blend RGB change
|
glEnable(GL_COLOR_LOGIC_OP);
|
||||||
glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha);
|
glLogicOp(logic_op_codes[state.logicmode]);
|
||||||
}
|
}
|
||||||
s_blendMode = newval;
|
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.
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
|
@ -1783,10 +1727,8 @@ void Renderer::RestoreAPIState()
|
||||||
}
|
}
|
||||||
SetGenerationMode();
|
SetGenerationMode();
|
||||||
BPFunctions::SetScissor();
|
BPFunctions::SetScissor();
|
||||||
SetColorMask();
|
|
||||||
SetDepthMode();
|
SetDepthMode();
|
||||||
SetBlendMode(true);
|
SetBlendMode(true);
|
||||||
SetLogicOpMode();
|
|
||||||
SetViewport();
|
SetViewport();
|
||||||
|
|
||||||
const VertexManager* const vm = static_cast<VertexManager*>(g_vertex_manager.get());
|
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)
|
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
||||||
{
|
{
|
||||||
auto const& tex = bpmem.tex[texindex];
|
auto const& tex = bpmem.tex[texindex];
|
||||||
|
|
|
@ -72,13 +72,10 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
void SetColorMask() override;
|
|
||||||
void SetBlendMode(bool forceUpdate) override;
|
void SetBlendMode(bool forceUpdate) override;
|
||||||
void SetScissorRect(const EFBRectangle& rc) override;
|
void SetScissorRect(const EFBRectangle& rc) override;
|
||||||
void SetGenerationMode() override;
|
void SetGenerationMode() override;
|
||||||
void SetDepthMode() override;
|
void SetDepthMode() override;
|
||||||
void SetLogicOpMode() override;
|
|
||||||
void SetDitherMode() override;
|
|
||||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||||
void SetInterlacingMode() override;
|
void SetInterlacingMode() override;
|
||||||
void SetViewport() 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.dstfactor, (int)bpmem.blendmode.srcfactor,
|
||||||
(int)bpmem.blendmode.subtract, (int)bpmem.blendmode.logicmode);
|
(int)bpmem.blendmode.subtract, (int)bpmem.blendmode.logicmode);
|
||||||
|
|
||||||
|
// Set Blending Mode
|
||||||
|
if (bp.changes)
|
||||||
|
SetBlendMode();
|
||||||
|
|
||||||
// Set LogicOp Blending Mode
|
// Set LogicOp Blending Mode
|
||||||
if (bp.changes & 0xF002) // logicopenable | logicmode
|
if (bp.changes & 0xF002) // logicopenable | logicmode
|
||||||
SetLogicOpMode();
|
SetLogicOpMode();
|
||||||
|
@ -150,10 +154,6 @@ static void BPWritten(const BPCmd& bp)
|
||||||
if (bp.changes & 4) // dither
|
if (bp.changes & 4) // dither
|
||||||
SetDitherMode();
|
SetDitherMode();
|
||||||
|
|
||||||
// Set Blending Mode
|
|
||||||
if (bp.changes & 0xFF1) // blendenable | alphaupdate | dstfactor | srcfactor | subtract
|
|
||||||
SetBlendMode();
|
|
||||||
|
|
||||||
// Set Color Mask
|
// Set Color Mask
|
||||||
if (bp.changes & 0x18) // colorupdate | alphaupdate
|
if (bp.changes & 0x18) // colorupdate | alphaupdate
|
||||||
SetColorMask();
|
SetColorMask();
|
||||||
|
@ -316,7 +316,10 @@ static void BPWritten(const BPCmd& bp)
|
||||||
if (bp.changes & 0xFFFF)
|
if (bp.changes & 0xFFFF)
|
||||||
PixelShaderManager::SetAlpha();
|
PixelShaderManager::SetAlpha();
|
||||||
if (bp.changes)
|
if (bp.changes)
|
||||||
|
{
|
||||||
g_renderer->SetColorMask();
|
g_renderer->SetColorMask();
|
||||||
|
SetBlendMode();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case BPMEM_BIAS: // BIAS
|
case BPMEM_BIAS: // BIAS
|
||||||
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
|
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
|
||||||
|
|
Loading…
Reference in New Issue