gsdx ogl: rework atst handling

* Move the rounding operation in the constant buffer
* Merge less with less equal. And merge greater with greater equal

Need test
This commit is contained in:
Gregory Hainaut 2016-06-11 01:08:50 +02:00
parent 9a188a87c2
commit 74822d6ba3
5 changed files with 118 additions and 75 deletions

View File

@ -41,7 +41,6 @@ GSRendererOGL::GSRendererOGL()
UserHacks_merge_sprite = theApp.GetConfigB("UserHacks_merge_pp_sprite"); UserHacks_merge_sprite = theApp.GetConfigB("UserHacks_merge_pp_sprite");
m_prim_overlap = PRIM_OVERLAP_UNKNOW; m_prim_overlap = PRIM_OVERLAP_UNKNOW;
m_pass1_atst = 0;
ResetStates(); ResetStates();
if (!theApp.GetConfigB("UserHacks")) { if (!theApp.GetConfigB("UserHacks")) {
@ -171,29 +170,48 @@ void GSRendererOGL::SetupIA()
void GSRendererOGL::EmulateAtst(const int pass, const GSTextureCache::Source* tex) void GSRendererOGL::EmulateAtst(const int pass, const GSTextureCache::Source* tex)
{ {
if (pass == 1) { 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) int atst = (pass == 2) ? inverted_atst[m_context->TEST.ATST] : m_context->TEST.ATST;
m_pass1_atst = m_context->TEST.ATST;
else
m_pass1_atst = ATST_ALWAYS;
if (m_context->TEST.ATE && m_context->TEST.ATST > 1) if (!m_context->TEST.ATE) return;
switch (atst) {
case ATST_LESS:
if (tex && tex->m_spritehack_t) {
m_ps_sel.atst = 0;
} else {
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; 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;
if (tex && tex->m_spritehack_t && (m_pass1_atst == 2)) { case ATST_NEVER: // Draw won't be done so no need to implement it in shader
m_ps_sel.atst = 1; case ATST_ALWAYS:
} else { default:
m_ps_sel.atst = m_pass1_atst; m_ps_sel.atst = 0;
} break;
} else if (pass == 2) {
static const uint32 iatst[] = {1, 0, 5, 6, 7, 2, 3, 4};
m_ps_sel.atst = iatst[m_pass1_atst];
if (tex && tex->m_spritehack_t && (m_ps_sel.atst == 2)) {
m_ps_sel.atst = 1;
}
} }
} }
@ -786,10 +804,6 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
// Setup Texture ressources // Setup Texture ressources
dev->SetupSampler(m_ps_ssel); dev->SetupSampler(m_ps_ssel);
dev->PSSetShaderResources(tex->m_texture, tex->m_palette); dev->PSSetShaderResources(tex->m_texture, tex->m_palette);
if (tex->m_spritehack_t && (m_ps_sel.atst == 2)) {
m_ps_sel.atst = 1;
}
} }
GSRendererOGL::PRIM_OVERLAP GSRendererOGL::PrimitiveOverlap() GSRendererOGL::PRIM_OVERLAP GSRendererOGL::PrimitiveOverlap()
@ -1361,6 +1375,9 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
EmulateAtst(2, tex); EmulateAtst(2, tex);
// Potentially AREF was updated (hope perf impact will be limited)
dev->SetupCB(&vs_cb, &ps_cb);
dev->SetupPipeline(m_vs_sel, m_gs_sel, m_ps_sel); dev->SetupPipeline(m_vs_sel, m_gs_sel, m_ps_sel);
bool z = m_om_dssel.zwe; bool z = m_om_dssel.zwe;

View File

@ -71,8 +71,6 @@ class GSRendererOGL final : public GSRendererHW
GSDeviceOGL::OMColorMaskSelector m_om_csel; GSDeviceOGL::OMColorMaskSelector m_om_csel;
GSDeviceOGL::OMDepthStencilSelector m_om_dssel; GSDeviceOGL::OMDepthStencilSelector m_om_dssel;
int m_pass1_atst;
private: private:
inline void ResetStates(); inline void ResetStates();
inline void Lines2Sprites(); inline void Lines2Sprites();

View File

@ -72,7 +72,8 @@ layout(std140, binding = 21) uniform cb21
vec4 WH; vec4 WH;
vec2 TA; vec2 TA;
float _pad0; //float _pad0;
int Uber_ATST;
float Af; float Af;
uvec4 MskFix; uvec4 MskFix;

View File

@ -478,32 +478,45 @@ vec4 tfx(vec4 T, vec4 C)
void atst(vec4 C) void atst(vec4 C)
{ {
// FIXME use integer cmp
float a = C.a; float a = C.a;
#if (PS_ATST == 0) // never #if 0
discard; switch(Uber_ATST) {
#elif (PS_ATST == 1) // always case 0:
// nothing to do break;
#elif (PS_ATST == 2) // l case 1:
if ((AREF - a - 0.5f) < 0.0f) if (a > AREF) discard;
discard; break;
#elif (PS_ATST == 3 ) // le case 2:
if ((AREF - a + 0.5f) < 0.0f) if (a < AREF) discard;
discard; break;
#elif (PS_ATST == 4) // e case 3:
if ((0.5f - abs(a - AREF)) < 0.0f) if (abs(a - AREF) > 0.5f) discard;
discard; break;
#elif (PS_ATST == 5) // ge case 4:
if ((a-AREF + 0.5f) < 0.0f) if (abs(a - AREF) < 0.5f) discard;
discard; break;
#elif (PS_ATST == 6) // g }
if ((a-AREF - 0.5f) < 0.0f)
discard;
#elif (PS_ATST == 7) // ne
if ((abs(a - AREF) - 0.5f) < 0.0f)
discard;
#endif #endif
#if 1
#if (PS_ATST == 0)
// nothing to do
#elif (PS_ATST == 1)
if (a > AREF) discard;
#elif (PS_ATST == 2)
if (a < AREF) discard;
#elif (PS_ATST == 3)
if (abs(a - AREF) > 0.5f) discard;
#elif (PS_ATST == 4)
if (abs(a - AREF) < 0.5f) discard;
#endif
#endif
} }
void fog(inout vec4 C, float f) void fog(inout vec4 C, float f)

View File

@ -97,7 +97,8 @@ static const char* const common_header_glsl =
" vec4 WH;\n" " vec4 WH;\n"
"\n" "\n"
" vec2 TA;\n" " vec2 TA;\n"
" float _pad0;\n" " //float _pad0;\n"
" int Uber_ATST;\n"
" float Af;\n" " float Af;\n"
"\n" "\n"
" uvec4 MskFix;\n" " uvec4 MskFix;\n"
@ -1321,32 +1322,45 @@ static const char* const tfx_fs_all_glsl =
"\n" "\n"
"void atst(vec4 C)\n" "void atst(vec4 C)\n"
"{\n" "{\n"
" // FIXME use integer cmp\n"
" float a = C.a;\n" " float a = C.a;\n"
"\n" "\n"
"#if (PS_ATST == 0) // never\n" "#if 0\n"
" discard;\n" " switch(Uber_ATST) {\n"
"#elif (PS_ATST == 1) // always\n" " case 0:\n"
" // nothing to do\n" " break;\n"
"#elif (PS_ATST == 2) // l\n" " case 1:\n"
" if ((AREF - a - 0.5f) < 0.0f)\n" " if (a > AREF) discard;\n"
" discard;\n" " break;\n"
"#elif (PS_ATST == 3 ) // le\n" " case 2:\n"
" if ((AREF - a + 0.5f) < 0.0f)\n" " if (a < AREF) discard;\n"
" discard;\n" " break;\n"
"#elif (PS_ATST == 4) // e\n" " case 3:\n"
" if ((0.5f - abs(a - AREF)) < 0.0f)\n" " if (abs(a - AREF) > 0.5f) discard;\n"
" discard;\n" " break;\n"
"#elif (PS_ATST == 5) // ge\n" " case 4:\n"
" if ((a-AREF + 0.5f) < 0.0f)\n" " if (abs(a - AREF) < 0.5f) discard;\n"
" discard;\n" " break;\n"
"#elif (PS_ATST == 6) // g\n" " }\n"
" if ((a-AREF - 0.5f) < 0.0f)\n" "\n"
" discard;\n" "\n"
"#elif (PS_ATST == 7) // ne\n"
" if ((abs(a - AREF) - 0.5f) < 0.0f)\n"
" discard;\n"
"#endif\n" "#endif\n"
"\n"
"#if 1\n"
"\n"
"#if (PS_ATST == 0)\n"
" // nothing to do\n"
"#elif (PS_ATST == 1)\n"
" if (a > AREF) discard;\n"
"#elif (PS_ATST == 2)\n"
" if (a < AREF) discard;\n"
"#elif (PS_ATST == 3)\n"
" if (abs(a - AREF) > 0.5f) discard;\n"
"#elif (PS_ATST == 4)\n"
" if (abs(a - AREF) < 0.5f) discard;\n"
"#endif\n"
"\n"
"#endif\n"
"\n"
"}\n" "}\n"
"\n" "\n"
"void fog(inout vec4 C, float f)\n" "void fog(inout vec4 C, float f)\n"