gsdx-ogl: separate color mask state from the blending state

Unlike DX they're uncorrelated.
This commit is contained in:
Gregory Hainaut 2015-05-05 10:26:01 +02:00
parent 7bfee7e377
commit 8032e2c369
6 changed files with 58 additions and 56 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 !

View File

@ -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);

View File

@ -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();

View File

@ -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;
}