diff --git a/plugins/GSdx/GLLoader.cpp b/plugins/GSdx/GLLoader.cpp index e16d2a206c..388367c4b3 100644 --- a/plugins/GSdx/GLLoader.cpp +++ b/plugins/GSdx/GLLoader.cpp @@ -505,10 +505,8 @@ namespace GLLoader { } if (!found_GL_ARB_texture_barrier) { - fprintf(stderr, "Error GL_ARB_texture_barrier is not supported by your driver. Accurate options will be disabled! Sorry!\n"); - theApp.SetConfig("accurate_blend", 0); - theApp.SetConfig("accurate_colclip", 0); - theApp.SetConfig("accurate_fbmask", 0); + fprintf(stderr, "Error GL_ARB_texture_barrier is not supported by your driver. You can't emulate correctly the GS blending unit! Sorry!\n"); + theApp.SetConfig("accurate_blending_unit", 0); } fprintf(stderr, "\n"); diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 7ad2e11078..1a6fbe8fca 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -372,11 +372,6 @@ void GSRendererHW::Draw() if(PRIM->TME) { -#ifdef ENABLE_OGL_DEBUG - if ((context->FRAME.Block() == context->TEX0.TBP0) && (m_vertex.next > 2)) { - GL_INS("ERROR: Source and Target are the same!"); - } -#endif /* // m_tc->LookupSource will mess with the palette, should not, but we do this after, until it is sorted out diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index e35d4ebc4c..86f21eb42f 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -29,10 +29,9 @@ GSRendererOGL::GSRendererOGL() { m_pixelcenter = GSVector2(-0.5f, -0.5f); - m_accurate_blend = theApp.GetConfig("accurate_blend", 1); m_accurate_date = theApp.GetConfig("accurate_date", 0); - m_accurate_colclip = theApp.GetConfig("accurate_colclip", 0); - m_accurate_fbmask = theApp.GetConfig("accurate_fbmask", 0); + + m_sw_blending = theApp.GetConfig("accurate_blending_unit", 1); UserHacks_TCOffset = theApp.GetConfig("UserHacks_TCOffset", 0); UserHacks_TCO_x = (UserHacks_TCOffset & 0xFFFF) / -1000.0f; @@ -248,7 +247,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour GSDeviceOGL::OMColorMaskSelector om_csel; GSDeviceOGL::OMDepthStencilSelector om_dssel; - if (GLLoader::found_GL_ARB_texture_barrier && (m_vt.m_primclass == GS_SPRITE_CLASS)) { + if (GLLoader::found_GL_ARB_texture_barrier && (m_vt.m_primclass == GS_SPRITE_CLASS) && tex) { // Except 2D games, sprites are often use for special post-processing effect m_prim_overlap = PrimitiveOverlap(); #ifdef ENABLE_OGL_DEBUG @@ -367,7 +366,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour ps_sel.fbmask = 1; } - ps_sel.fbmask &= m_accurate_fbmask; + ps_sel.fbmask &= m_sw_blending; if (ps_sel.fbmask) { GL_INS("FBMASK SW emulated fb_mask:%x on tex shuffle", fbmask); ps_cb.FbMask.r = rg_mask; @@ -402,7 +401,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour ps_sel.fbmask = 1; } - ps_sel.fbmask &= m_accurate_fbmask; + ps_sel.fbmask &= m_sw_blending; if (ps_sel.fbmask) { GL_INS("FBMASK SW emulated fb_mask:%x on %d bits format", context->FRAME.FBMSK, (GSLocalMemory::m_psm[context->FRAME.PSM].fmt == 2) ? 16 : 32); @@ -614,19 +613,20 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour om_dssel.date = 1; } - bool colclip_wrap = env.COLCLAMP.CLAMP == 0 && !tex && PRIM->PRIM != GS_POINTLIST && !m_accurate_colclip; - bool acc_colclip_wrap = env.COLCLAMP.CLAMP == 0 && m_accurate_colclip; + bool colclip_wrap = env.COLCLAMP.CLAMP == 0 && !tex && PRIM->PRIM != GS_POINTLIST; + bool acc_colclip_wrap = env.COLCLAMP.CLAMP == 0 && (m_sw_blending >= ACC_BLEND_CCLIP || (m_prim_overlap == PRIM_OVERLAP_NO)); if ((ALPHA.A == ALPHA.B) || !om_bsel.abe) { // Optimize-away colclip // No addition neither substraction so no risk of overflow the [0:255] range. colclip_wrap = false; acc_colclip_wrap = false; } - if (colclip_wrap) { - ps_sel.colclip = 1; - GL_INS("COLCLIP ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D); - } else if (acc_colclip_wrap) { + if (acc_colclip_wrap) { + colclip_wrap = false; ps_sel.colclip = 3; GL_INS("COLCLIP SW ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D); + } else if (colclip_wrap) { + ps_sel.colclip = 1; + GL_INS("COLCLIP ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D); } ps_sel.fba = context->FBA.FBA; @@ -766,12 +766,15 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour // SW Blending // Compute the blending equation to detect special case - int blend_sel = ((om_bsel.a * 3 + om_bsel.b) * 3 + om_bsel.c) * 3 + om_bsel.d; - int bogus_blend = GSDeviceOGL::m_blendMapD3D9[blend_sel].bogus; - bool all_sw = !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) ) && (m_accurate_blend > 1); + int blend_sel = ((om_bsel.a * 3 + om_bsel.b) * 3 + om_bsel.c) * 3 + om_bsel.d; + int blend_flag = GSDeviceOGL::m_blendMapD3D9[blend_sel].bogus; + bool impossible_blend = m_sw_blending && (blend_flag & A_MAX); + + bool all_blend_sw = (m_sw_blending >= ACC_BLEND_ULTRA) + || (m_sw_blending >= ACC_BLEND_FULL && !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) )); bool sw_blending = (m_prim_overlap == PRIM_OVERLAP_NO) // Free case - || (m_accurate_blend && (bogus_blend & A_MAX)) || all_sw // Impossible blend or all + || impossible_blend || all_blend_sw // Impossible blend or all || acc_colclip_wrap // accurate colclip || ps_sel.fbmask; // accurate fbmask // GL42 interact very badly with sw blending. GL42 uses the primitiveID to find the primitive @@ -781,8 +784,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour sw_blending &= !DATE_GL42; if (sw_blending && om_bsel.abe && rt) { - //GL_INS("!!! SW blending effect used (0x%x from sel %d) !!!", bogus_blend, blend_sel); - // select a shader that support blending ps_sel.blend_a = om_bsel.a; ps_sel.blend_b = om_bsel.b; @@ -797,7 +798,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour } // No need to flush for every primitive - require_barrier |= !(bogus_blend & NO_BAR); + require_barrier |= !(blend_flag & NO_BAR); } else { ps_sel.clr1 = om_bsel.IsCLR1(); } diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index 984949f943..9688c54912 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -35,12 +35,18 @@ class GSRendererOGL : public GSRendererHW PRIM_OVERLAP_NO }; + enum ACC_BLEND { + ACC_BLEND_NONE = 0, + ACC_BLEND_FREE = 1, + ACC_BLEND_CCLIP = 2, + ACC_BLEND_FULL = 3, + ACC_BLEND_ULTRA = 4 + }; + private: GSVector2 m_pixelcenter; - int m_accurate_blend; bool m_accurate_date; - bool m_accurate_colclip; - bool m_accurate_fbmask; + int m_sw_blending; unsigned int UserHacks_TCOffset; float UserHacks_TCO_x, UserHacks_TCO_y; diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index 052fe57aee..f307381ac2 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -107,7 +107,7 @@ GSBlendStateOGL* GSDeviceOGL::CreateBlend(OMBlendSelector bsel, float afix) bs->SetRGB(m_blendMapD3D9[i].op, m_blendMapD3D9[i].src, m_blendMapD3D9[i].dst); if (m_blendMapD3D9[i].bogus & A_MAX) { - if (!theApp.GetConfig("accurate_blend", 1)) { + if (!theApp.GetConfig("accurate_blending_unit", 1)) { bs->EnableBlend(); if (bsel.a == 0) bs->SetRGB(m_blendMapD3D9[i].op, GL_ONE, m_blendMapD3D9[i].dst);