diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp index 0641afbf9f..1bc656449e 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp @@ -484,17 +484,20 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42) } // Compute the blending equation to detect special case - uint8 blend_index = uint8(((ALPHA.A * 3 + ALPHA.B) * 3 + ALPHA.C) * 3 + ALPHA.D); - int blend_flag = dev->GetBlendFlags(blend_index); + const uint8 blend_index = uint8(((ALPHA.A * 3 + ALPHA.B) * 3 + ALPHA.C) * 3 + ALPHA.D); + const int blend_flag = m_dev->GetBlendFlags(blend_index); // SW Blend is (nearly) free. Let's use it. - bool impossible_or_free_blend = (blend_flag & (BLEND_NO_BAR|BLEND_A_MAX|BLEND_ACCU)) // Blend doesn't requires the costly barrier - || (m_prim_overlap == PRIM_OVERLAP_NO) // Blend can be done in a single draw - || (m_require_full_barrier); // Another effect (for example fbmask) already requires a full barrier + const bool impossible_or_free_blend = (blend_flag & (BLEND_NO_BAR|BLEND_A_MAX|BLEND_ACCU)) // Blend doesn't requires the costly barrier + || (m_prim_overlap == PRIM_OVERLAP_NO) // Blend can be done in a single draw + || (m_require_full_barrier); // Another effect (for example fbmask) already requires a full barrier // Do the multiplication in shader for blending accumulation: Cs*As + Cd or Cs*Af + Cd bool accumulation_blend = !!(blend_flag & BLEND_ACCU); + // Blending doesn't require barrier + const bool no_barrier_blend = !!(blend_flag & BLEND_NO_BAR); + // Warning no break on purpose // Note: the "fall through" comments tell gcc not to complain about not having breaks. switch (m_sw_blending) { @@ -523,11 +526,16 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42) // Color clip if (m_env.COLCLAMP.CLAMP == 0) { - if (m_prim_overlap == PRIM_OVERLAP_NO) { + // Safe FBMASK, avoid hitting accumulation mode on 16bit, + // fixes shadows in Superman shadows of Apokolips. + const bool sw_fbmask_colclip = !m_require_one_barrier && m_ps_sel.fbmask; + const bool free_colclip = m_prim_overlap == PRIM_OVERLAP_NO || no_barrier_blend || sw_fbmask_colclip; + GL_INS("COLCLIP Info (Blending: %d/%d/%d/%d, SW FBMASK: %d, OVERLAP: %d)", + ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D, sw_fbmask_colclip, m_prim_overlap); + if (free_colclip) { // The fastest algo that requires a single pass GL_INS("COLCLIP Free mode ENABLED"); m_ps_sel.colclip = 1; - //ASSERT(sw_blending); sw_blending = true; accumulation_blend = false; // disable the HDR algo } else if (accumulation_blend) { @@ -537,11 +545,10 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42) sw_blending = true; // Enable sw blending for the HDR algo } else if (sw_blending) { // A slow algo that could requires several passes (barely used) - GL_INS("COLCLIP SW ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D); + GL_INS("COLCLIP SW mode ENABLED"); m_ps_sel.colclip = 1; } else { - // Speed hack skip previous slow algo - GL_INS("COLCLIP HDR Rare case ENABLED"); + GL_INS("COLCLIP HDR mode ENABLED"); m_ps_sel.hdr = 1; } } @@ -582,7 +589,7 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42) // Disable HW blending dev->OMSetBlendState(); - m_require_full_barrier |= !(blend_flag & BLEND_NO_BAR); + m_require_full_barrier |= !no_barrier_blend; } // Require the fix alpha vlaue @@ -593,7 +600,7 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42) m_ps_sel.clr1 = !!(blend_flag & BLEND_C_CLR); if (m_ps_sel.dfmt == 1 && ALPHA.C == 1) { // 24 bits doesn't have an alpha channel so use 1.0f fix factor as equivalent - uint8 hacked_blend_index = blend_index + 3; // +3 <=> +1 on C + const uint8 hacked_blend_index = blend_index + 3; // +3 <=> +1 on C dev->OMSetBlendState(hacked_blend_index, 128, true); } else { dev->OMSetBlendState(blend_index, ALPHA.FIX, (ALPHA.C == 2));