diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp index 8f75272880..89f826e76f 100644 --- a/plugins/GSdx/GSRendererDX.cpp +++ b/plugins/GSdx/GSRendererDX.cpp @@ -438,25 +438,44 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc // Depth test is always true so it can be executed in 2 passes (no order required) unlike color. // The idea is to compute first the color which is independent of the alpha test. And then do a 2nd // pass to handle the depth based on the alpha test. - bool complex_ate = ate_first_pass & ate_second_pass; - bool ate_all_color_then_depth = complex_ate & (m_context->TEST.AFAIL == AFAIL_FB_ONLY) & (om_dssel.ztst == ZTST_ALWAYS); - // In FB_ONLY mode, only the z buffer is impacted by the alpha test. No depth => useless alpha test - bool ate_skip = complex_ate & (m_context->TEST.AFAIL == AFAIL_FB_ONLY) & (ds == nullptr); + bool ate_RGBA_then_Z = false; + bool ate_RGB_then_ZA = false; + bool ate_skip = false; + if (ate_first_pass & ate_second_pass) { +#ifdef _DEBUG + fprintf(stdout, "Complex Alpha Test\n"); +#endif + bool commutative_depth = (om_dssel.ztst == ZTST_GEQUAL && (m_vt.m_eq.xyzf & 0x4)) || (om_dssel.ztst == ZTST_ALWAYS); + bool commutative_alpha = (m_context->ALPHA.C != 1); // when either Alpha Src or a constant + + ate_RGBA_then_Z = (m_context->TEST.AFAIL == AFAIL_FB_ONLY) & commutative_depth; + ate_RGB_then_ZA = (m_context->TEST.AFAIL == AFAIL_RGB_ONLY) & commutative_depth & commutative_alpha; + + // In FB_ONLY mode, only the z buffer is impacted by the alpha test. No depth => useless alpha test + ate_skip = (m_context->TEST.AFAIL == AFAIL_FB_ONLY) & (ds == nullptr); + } if (ate_skip) { #ifdef _DEBUG fprintf(stdout, "Alternate ATE handling: ate_skip\n"); #endif ate_second_pass = false; - } else if (ate_all_color_then_depth) { + } else if (ate_RGBA_then_Z) { #ifdef _DEBUG - fprintf(stdout, "Alternate ATE handling: ate_all_color_then_depth\n"); + fprintf(stdout, "Alternate ATE handling: ate_RGBA_then_Z\n"); #endif // Render all color but don't update depth // ATE is disabled here om_dssel.zwe = false; - } - else { + } else if (ate_RGB_then_ZA) { +#ifdef _DEBUG + fprintf(stdout, "Alternate ATE handling: ate_RGB_then_ZA\n"); +#endif + // Render RGB color but don't update depth/alpha + // ATE is disabled here + om_dssel.zwe = false; + om_bsel.wa = false; + } else { EmulateAtst(1, tex); } @@ -567,7 +586,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc { ASSERT(!m_env.PABE.PABE); - if (ate_all_color_then_depth) { + if (ate_RGBA_then_Z | ate_RGB_then_ZA) { // Enable ATE as first pass to update the depth // of pixels that passed the alpha test EmulateAtst(1, tex); @@ -595,9 +614,13 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc default: __assume(0); } - if (ate_all_color_then_depth) { + if (ate_RGBA_then_Z) { z = true; r = g = b = a = false; + } else if (ate_RGB_then_ZA) { + z = true; + a = !!(m_context->FRAME.FBMSK & 0xFF000000); + r = g = b = false; } if(z || r || g || b || a)