diff --git a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp index 87da1423cf..790587eb7d 100644 --- a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp @@ -113,50 +113,6 @@ void GSRendererDX11::SetupIA(const float& sx, const float& sy) dev->IASetPrimitiveTopology(t); } -void GSRendererDX11::EmulateAtst(const int pass, const GSTextureCache::Source* tex) -{ - static const uint32 inverted_atst[] = {ATST_ALWAYS, ATST_NEVER, ATST_GEQUAL, ATST_GREATER, ATST_NOTEQUAL, ATST_LESS, ATST_LEQUAL, ATST_EQUAL}; - int atst = (pass == 2) ? inverted_atst[m_context->TEST.ATST] : m_context->TEST.ATST; - - if (!m_context->TEST.ATE) return; - - switch (atst) - { - case ATST_LESS: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; - m_ps_sel.atst = 1; - break; - case ATST_LEQUAL: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; - m_ps_sel.atst = 1; - break; - case ATST_GEQUAL: - // Maybe a -1 trick multiplication factor could be used to merge with ATST_LEQUAL case - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; - m_ps_sel.atst = 2; - break; - case ATST_GREATER: - // Maybe a -1 trick multiplication factor could be used to merge with ATST_LESS case - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; - m_ps_sel.atst = 2; - break; - case ATST_EQUAL: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF; - m_ps_sel.atst = 3; - break; - case ATST_NOTEQUAL: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF; - m_ps_sel.atst = 4; - break; - - case ATST_NEVER: // Draw won't be done so no need to implement it in shader - case ATST_ALWAYS: - default: - m_ps_sel.atst = 0; - break; - } -} - void GSRendererDX11::EmulateZbuffer() { if (m_context->TEST.ZTE) @@ -1009,11 +965,12 @@ void GSRendererDX11::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou // pass to handle the depth based on the alpha test. bool ate_RGBA_then_Z = false; bool ate_RGB_then_ZA = false; + uint8 ps_atst = 0; if (ate_first_pass & ate_second_pass) { // fprintf(stdout, "%d: Complex Alpha Test\n", s_n); - bool commutative_depth = (m_om_dssel.ztst == ZTST_GEQUAL && m_vt.m_eq.z) || (m_om_dssel.ztst == ZTST_ALWAYS); - bool commutative_alpha = (m_context->ALPHA.C != 1); // when either Alpha Src or a constant + const bool commutative_depth = (m_om_dssel.ztst == ZTST_GEQUAL && m_vt.m_eq.z) || (m_om_dssel.ztst == ZTST_ALWAYS); + const 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; @@ -1036,7 +993,8 @@ void GSRendererDX11::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou } else { - EmulateAtst(1, tex); + EmulateAtst(tex, ps_cb.FogColor_AREF, ps_atst, false); + m_ps_sel.atst = ps_atst; } if (tex) @@ -1125,15 +1083,17 @@ void GSRendererDX11::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou { // Enable ATE as first pass to update the depth // of pixels that passed the alpha test - EmulateAtst(1, tex); + EmulateAtst(tex, ps_cb.FogColor_AREF, ps_atst, false); } else { // second pass will process the pixels that failed // the alpha test - EmulateAtst(2, tex); + EmulateAtst(tex, ps_cb.FogColor_AREF, ps_atst, true); } + m_ps_sel.atst = ps_atst; + dev->SetupPS(m_ps_sel, &ps_cb, m_ps_ssel); bool z = m_om_dssel.zwe; diff --git a/plugins/GSdx/Renderers/DX11/GSRendererDX11.h b/plugins/GSdx/Renderers/DX11/GSRendererDX11.h index 3ec9aff62c..c74fa700b0 100644 --- a/plugins/GSdx/Renderers/DX11/GSRendererDX11.h +++ b/plugins/GSdx/Renderers/DX11/GSRendererDX11.h @@ -40,7 +40,6 @@ private: private: inline void ResetStates(); inline void SetupIA(const float& sx, const float& sy); - inline void EmulateAtst(const int pass, const GSTextureCache::Source* tex); inline void EmulateZbuffer(); inline void EmulateBlending(); inline void EmulateTextureShuffleAndFbmask(); diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp index 93d005d16c..d650cd4b7b 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp @@ -438,6 +438,53 @@ void GSRendererHW::Lines2Sprites() } } +void GSRendererHW::EmulateAtst(const GSTextureCache::Source* tex, GSVector4& FogColor_AREF, uint8& ps_atst, const bool pass_2) +{ + static const uint32 inverted_atst[] = {ATST_ALWAYS, ATST_NEVER, ATST_GEQUAL, ATST_GREATER, ATST_NOTEQUAL, ATST_LESS, ATST_LEQUAL, ATST_EQUAL}; + + if (!m_context->TEST.ATE) + return; + + // Check for pass 2, otherwise do pass 1. + const int atst = pass_2 ? inverted_atst[m_context->TEST.ATST] : m_context->TEST.ATST; + + switch (atst) + { + case ATST_LESS: + FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; + ps_atst = 1; + break; + case ATST_LEQUAL: + FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; + ps_atst = 1; + break; + case ATST_GEQUAL: + // Maybe a -1 trick multiplication factor could be used to merge with ATST_LEQUAL case + FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; + ps_atst = 2; + break; + case ATST_GREATER: + // Maybe a -1 trick multiplication factor could be used to merge with ATST_LESS case + FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; + ps_atst = 2; + break; + case ATST_EQUAL: + FogColor_AREF.a = (float)m_context->TEST.AREF; + ps_atst = 3; + break; + case ATST_NOTEQUAL: + FogColor_AREF.a = (float)m_context->TEST.AREF; + ps_atst = 4; + break; + + case ATST_NEVER: // Draw won't be done so no need to implement it in shader + case ATST_ALWAYS: + default: + ps_atst = 0; + break; + } +} + // Fix the vertex position/tex_coordinate from 16 bits color to 32 bits color void GSRendererHW::ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba) { diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.h b/plugins/GSdx/Renderers/HW/GSRendererHW.h index 67e09e1a57..6af0c85f09 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.h +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.h @@ -175,6 +175,7 @@ public: GSVector2i GetCustomResolution(); void SetScaling(); void Lines2Sprites(); + void EmulateAtst(const GSTextureCache::Source* tex, GSVector4& FogColor_AREF, uint8& atst, const bool pass_2); void ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba); GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex); GSVector4i ComputeBoundingBox(const GSVector2& rtscale, const GSVector2i& rtsize); diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp index 0ec9ed54b8..f856238e41 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp @@ -119,49 +119,6 @@ void GSRendererOGL::SetupIA(const float& sx, const float& sy) dev->IASetPrimitiveTopology(t); } -void GSRendererOGL::EmulateAtst(const int pass, const GSTextureCache::Source* tex) -{ - static const uint32 inverted_atst[] = {ATST_ALWAYS, ATST_NEVER, ATST_GEQUAL, ATST_GREATER, ATST_NOTEQUAL, ATST_LESS, ATST_LEQUAL, ATST_EQUAL}; - int atst = (pass == 2) ? inverted_atst[m_context->TEST.ATST] : m_context->TEST.ATST; - - if (!m_context->TEST.ATE) return; - - switch (atst) { - case ATST_LESS: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; - m_ps_sel.atst = 1; - break; - case ATST_LEQUAL: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; - m_ps_sel.atst = 1; - break; - case ATST_GEQUAL: - // Maybe a -1 trick multiplication factor could be used to merge with ATST_LEQUAL case - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; - m_ps_sel.atst = 2; - break; - case ATST_GREATER: - // Maybe a -1 trick multiplication factor could be used to merge with ATST_LESS case - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; - m_ps_sel.atst = 2; - break; - case ATST_EQUAL: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF; - m_ps_sel.atst = 3; - break; - case ATST_NOTEQUAL: - ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF; - m_ps_sel.atst = 4; - break; - - case ATST_NEVER: // Draw won't be done so no need to implement it in shader - case ATST_ALWAYS: - default: - m_ps_sel.atst = 0; - break; - } -} - void GSRendererOGL::EmulateZbuffer() { if (m_context->TEST.ZTE) { @@ -1240,10 +1197,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour // pass to handle the depth based on the alpha test. bool ate_RGBA_then_Z = false; bool ate_RGB_then_ZA = false; + uint8 ps_atst = 0; if (ate_first_pass & ate_second_pass) { GL_DBG("Complex Alpha Test"); - bool commutative_depth = (m_om_dssel.ztst == ZTST_GEQUAL && m_vt.m_eq.z) || (m_om_dssel.ztst == ZTST_ALWAYS); - bool commutative_alpha = (m_context->ALPHA.C != 1); // when either Alpha Src or a constant + const bool commutative_depth = (m_om_dssel.ztst == ZTST_GEQUAL && m_vt.m_eq.z) || (m_om_dssel.ztst == ZTST_ALWAYS); + const 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; @@ -1261,7 +1219,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour m_om_dssel.zwe = false; m_om_csel.wa = false; } else { - EmulateAtst(1, tex); + EmulateAtst(tex, ps_cb.FogColor_AREF, ps_atst, false); + m_ps_sel.atst = ps_atst; } if (tex) { @@ -1373,16 +1332,21 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour { ASSERT(!m_env.PABE.PABE); - if (ate_RGBA_then_Z | ate_RGB_then_ZA) { + 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); - } else { + EmulateAtst(tex, ps_cb.FogColor_AREF, ps_atst, false); + } + else + { // second pass will process the pixels that failed // the alpha test - EmulateAtst(2, tex); + EmulateAtst(tex, ps_cb.FogColor_AREF, ps_atst, true); } + m_ps_sel.atst = ps_atst; + // Potentially AREF was updated (hope perf impact will be limited) dev->SetupCB(&vs_cb, &ps_cb); diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h index 77d70d3994..d5ba7343ae 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h @@ -75,7 +75,6 @@ class GSRendererOGL final : public GSRendererHW inline void EmulateChannelShuffle(GSTexture** rt, const GSTextureCache::Source* tex); inline void EmulateBlending(bool& DATE_GL42, bool& DATE_GL45); inline void EmulateTextureSampler(const GSTextureCache::Source* tex); - inline void EmulateAtst(const int pass, const GSTextureCache::Source* tex); inline void EmulateZbuffer(); public: