diff --git a/plugins/GSdx/GLState.cpp b/plugins/GSdx/GLState.cpp index 4ac79dd3bf..83e6329d27 100644 --- a/plugins/GSdx/GLState.cpp +++ b/plugins/GSdx/GLState.cpp @@ -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; diff --git a/plugins/GSdx/GLState.h b/plugins/GSdx/GLState.h index b377cbd293..c946202c42 100644 --- a/plugins/GSdx/GLState.h +++ b/plugins/GSdx/GLState.h @@ -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; diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 472fa47b81..e9217be21b 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -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 ! diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 56aee67efe..077a3fc088 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -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); diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 2a5124ae20..c83d2d1fd5 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -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(); diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index a1acc9a6d7..ae0901e295 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -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; }