mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: separate color mask state from the blending state
Unlike DX they're uncorrelated.
This commit is contained in:
parent
7bfee7e377
commit
8032e2c369
|
@ -34,10 +34,8 @@ namespace GLState {
|
|||
GLenum f_dRGB;
|
||||
GLenum f_sA;
|
||||
GLenum f_dA;
|
||||
bool r_msk;
|
||||
bool g_msk;
|
||||
bool b_msk;
|
||||
bool a_msk;
|
||||
uint32 wrgba;
|
||||
|
||||
float bf;
|
||||
|
||||
bool depth;
|
||||
|
@ -86,10 +84,7 @@ namespace GLState {
|
|||
f_dRGB = 0;
|
||||
f_sA = 0;
|
||||
f_dA = 0;
|
||||
r_msk = true;
|
||||
g_msk = true;
|
||||
b_msk = true;
|
||||
a_msk = true;
|
||||
wrgba = 0xF;
|
||||
bf = 0.0;
|
||||
|
||||
depth = false;
|
||||
|
|
|
@ -36,10 +36,7 @@ namespace GLState {
|
|||
extern GLenum f_dRGB;
|
||||
extern GLenum f_sA;
|
||||
extern GLenum f_dA;
|
||||
extern bool r_msk;
|
||||
extern bool g_msk;
|
||||
extern bool b_msk;
|
||||
extern bool a_msk;
|
||||
extern uint32 wrgba;
|
||||
extern float bf;
|
||||
|
||||
extern bool depth;
|
||||
|
|
|
@ -709,6 +709,7 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
|
|||
OMSetDepthStencilState(m_convert.dss, 0);
|
||||
OMSetBlendState(bs, 0);
|
||||
OMSetRenderTargets(dt, NULL);
|
||||
OMSetColorMaskState();
|
||||
|
||||
// ************************************
|
||||
// ia
|
||||
|
@ -909,6 +910,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
|||
OMSetBlendState(m_date.bs, 0);
|
||||
// normally ok without any RT if GL_ARB_framebuffer_no_attachments is supported (minus driver bug)
|
||||
OMSetRenderTargets(t, ds, &GLState::scissor);
|
||||
OMSetColorMaskState(); // TODO: likely useless
|
||||
|
||||
// ia
|
||||
|
||||
|
@ -1017,6 +1019,15 @@ void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
|||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::OMSetColorMaskState(OMColorMaskSelector sel)
|
||||
{
|
||||
if (sel.wrgba != GLState::wrgba) {
|
||||
GLState::wrgba = sel.wrgba;
|
||||
|
||||
gl_ColorMaski(0, sel.wr, sel.wg, sel.wb, sel.wa);
|
||||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
||||
{
|
||||
// State is checkd inside the object but worst case is 15 comparaisons !
|
||||
|
|
|
@ -45,10 +45,6 @@ class GSBlendStateOGL {
|
|||
GLenum m_func_dRGB;
|
||||
GLenum m_func_sA;
|
||||
GLenum m_func_dA;
|
||||
bool m_r_msk;
|
||||
bool m_b_msk;
|
||||
bool m_g_msk;
|
||||
bool m_a_msk;
|
||||
bool constant_factor;
|
||||
|
||||
public:
|
||||
|
@ -60,10 +56,6 @@ public:
|
|||
, m_func_dRGB(0)
|
||||
, m_func_sA(GL_ONE)
|
||||
, m_func_dA(GL_ZERO)
|
||||
, m_r_msk(GL_TRUE)
|
||||
, m_b_msk(GL_TRUE)
|
||||
, m_g_msk(GL_TRUE)
|
||||
, m_a_msk(GL_TRUE)
|
||||
, constant_factor(false)
|
||||
{}
|
||||
|
||||
|
@ -82,8 +74,6 @@ public:
|
|||
m_func_dA = dst;
|
||||
}
|
||||
|
||||
void SetMask(bool r, bool g, bool b, bool a) { m_r_msk = r; m_g_msk = g; m_b_msk = b; m_a_msk = a; }
|
||||
|
||||
void RevertOp()
|
||||
{
|
||||
if(m_equation_RGB == GL_FUNC_ADD)
|
||||
|
@ -98,23 +88,8 @@ public:
|
|||
|
||||
bool HasConstantFactor() { return constant_factor; }
|
||||
|
||||
void SetupColorMask()
|
||||
{
|
||||
// FIXME align then SSE
|
||||
if (GLState::r_msk != m_r_msk || GLState::g_msk != m_g_msk || GLState::b_msk != m_b_msk || GLState::a_msk != m_a_msk) {
|
||||
GLState::r_msk = m_r_msk;
|
||||
GLState::g_msk = m_g_msk;
|
||||
GLState::b_msk = m_b_msk;
|
||||
GLState::a_msk = m_a_msk;
|
||||
|
||||
gl_ColorMaski(0, m_r_msk, m_g_msk, m_b_msk, m_a_msk);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupBlend(float factor)
|
||||
{
|
||||
SetupColorMask();
|
||||
|
||||
if (GLState::blend != m_enable) {
|
||||
GLState::blend = m_enable;
|
||||
if (m_enable)
|
||||
|
@ -429,6 +404,31 @@ class GSDeviceOGL : public GSDevice
|
|||
static uint32 size() { return 1 << 6; }
|
||||
};
|
||||
|
||||
struct OMColorMaskSelector
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32 wr:1;
|
||||
uint32 wg:1;
|
||||
uint32 wb:1;
|
||||
uint32 wa:1;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 wrgba:4;
|
||||
};
|
||||
|
||||
uint32 key;
|
||||
};
|
||||
|
||||
operator uint32() {return key & 0xf;}
|
||||
|
||||
OMColorMaskSelector() : key(0xF) {}
|
||||
};
|
||||
|
||||
struct OMBlendSelector
|
||||
{
|
||||
union
|
||||
|
@ -440,18 +440,14 @@ class GSDeviceOGL : public GSDevice
|
|||
uint32 b:2;
|
||||
uint32 c:2;
|
||||
uint32 d:2;
|
||||
uint32 wr:1;
|
||||
uint32 wg:1;
|
||||
uint32 wb:1;
|
||||
uint32 wa:1;
|
||||
uint32 negative:1;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 _pad:1;
|
||||
uint32 _abe:1;
|
||||
uint32 abcd:8;
|
||||
uint32 wrgba:4;
|
||||
uint32 _negative:1;
|
||||
};
|
||||
|
||||
uint32 key;
|
||||
|
@ -622,6 +618,8 @@ class GSDeviceOGL : public GSDevice
|
|||
void OMSetBlendState(GSBlendStateOGL* bs, float bf);
|
||||
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
|
||||
void OMSetWriteBuffer(GLenum buffer = GL_COLOR_ATTACHMENT0);
|
||||
void OMSetColorMaskState(OMColorMaskSelector sel = OMColorMaskSelector());
|
||||
|
||||
|
||||
void CreateTextureFX();
|
||||
GLuint CompileVS(VSSelector sel, int logz);
|
||||
|
|
|
@ -202,6 +202,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
GSDeviceOGL::PSSamplerSelector ps_ssel;
|
||||
|
||||
GSDeviceOGL::OMBlendSelector om_bsel;
|
||||
GSDeviceOGL::OMColorMaskSelector om_csel;
|
||||
GSDeviceOGL::OMDepthStencilSelector om_dssel;
|
||||
|
||||
// Blend
|
||||
|
@ -232,13 +233,13 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
}
|
||||
}
|
||||
|
||||
om_bsel.wrgba = ~GSVector4i::load((int)context->FRAME.FBMSK).eq8(GSVector4i::xffffffff()).mask();
|
||||
om_csel.wrgba = ~GSVector4i::load((int)context->FRAME.FBMSK).eq8(GSVector4i::xffffffff()).mask();
|
||||
|
||||
if (DATE) {
|
||||
if (GLLoader::found_GL_ARB_texture_barrier && !PrimitiveOverlap()) {
|
||||
DATE_GL45 = true;
|
||||
DATE = false;
|
||||
} else if (om_bsel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS)) {
|
||||
} else if (om_csel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS)) {
|
||||
DATE_GL42 = GLLoader::found_GL_ARB_shader_image_load_store && !UserHacks_AlphaStencil;
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +420,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
// to only draw pixels which would cause the destination alpha test to fail in the future once.
|
||||
// Unfortunately this also means only drawing those pixels at all, which is why this is a hack.
|
||||
// The interaction with FBA in D3D9 is probably less than ideal.
|
||||
if (UserHacks_AlphaStencil && DATE && dev->HasStencil() && om_bsel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS))
|
||||
if (UserHacks_AlphaStencil && DATE && dev->HasStencil() && om_csel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS))
|
||||
{
|
||||
if (!context->FBA.FBA)
|
||||
{
|
||||
|
@ -524,6 +525,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
SetupIA();
|
||||
|
||||
dev->OMSetColorMaskState(om_csel);
|
||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||
dev->SetupCB(&vs_cb, &ps_cb, ps_sel.sprite ? &gs_cb : NULL);
|
||||
|
||||
|
@ -585,10 +587,10 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
dev->SetupPS(ps_sel);
|
||||
|
||||
bool z = om_dssel.zwe;
|
||||
bool r = om_bsel.wr;
|
||||
bool g = om_bsel.wg;
|
||||
bool b = om_bsel.wb;
|
||||
bool a = om_bsel.wa;
|
||||
bool r = om_csel.wr;
|
||||
bool g = om_csel.wg;
|
||||
bool b = om_csel.wb;
|
||||
bool a = om_csel.wa;
|
||||
|
||||
switch(context->TEST.AFAIL)
|
||||
{
|
||||
|
@ -602,11 +604,12 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
if(z || r || g || b || a)
|
||||
{
|
||||
om_dssel.zwe = z;
|
||||
om_bsel.wr = r;
|
||||
om_bsel.wg = g;
|
||||
om_bsel.wb = b;
|
||||
om_bsel.wa = a;
|
||||
om_csel.wr = r;
|
||||
om_csel.wg = g;
|
||||
om_csel.wb = b;
|
||||
om_csel.wa = a;
|
||||
|
||||
dev->OMSetColorMaskState(om_csel);
|
||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||
|
||||
dev->DrawIndexedPrimitive();
|
||||
|
|
|
@ -126,8 +126,6 @@ GSBlendStateOGL* GSDeviceOGL::CreateBlend(OMBlendSelector bsel, uint8 afix)
|
|||
if(bsel.negative) bs->RevertOp();
|
||||
}
|
||||
|
||||
bs->SetMask(bsel.wr, bsel.wg, bsel.wb, bsel.wa);
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue