Merge pull request #893 from PCSX2/accurate-date-regression

gsdx-ogl: accurate date regression. Bad interaction between depth & DATE
This commit is contained in:
Gregory Hainaut 2015-10-22 12:34:00 +02:00
commit 56f2e74ff4
3 changed files with 42 additions and 12 deletions

View File

@ -613,6 +613,10 @@ void GSDeviceOGL::InitPrimDateTexture(GSTexture* rt)
ClearRenderTarget_i(m_date.t, 0x7FFFFFFF); ClearRenderTarget_i(m_date.t, 0x7FFFFFFF);
glBindImageTexture(2, m_date.t->GetID(), 0, false, 0, GL_READ_WRITE, GL_R32I); glBindImageTexture(2, m_date.t->GetID(), 0, false, 0, GL_READ_WRITE, GL_R32I);
#ifdef ENABLE_OGL_DEBUG
// Help to see the texture in apitrace
PSSetShaderResource(2, m_date.t);
#endif
} }
void GSDeviceOGL::RecycleDateTexture() void GSDeviceOGL::RecycleDateTexture()

View File

@ -48,10 +48,23 @@ layout(binding = 3) uniform sampler2D RtSampler; // note 2 already use by the im
#ifndef DISABLE_GL42_image #ifndef DISABLE_GL42_image
#if PS_DATE > 0 #if PS_DATE > 0
// FIXME how to declare memory access // FIXME how to declare memory access
layout(r32i, binding = 2) coherent uniform iimage2D img_prim_min; layout(r32i, binding = 2) uniform iimage2D img_prim_min;
// Don't enable it. Discard fragment can still write in the depth buffer // WARNING:
// it breaks shadow in Shin Megami Tensei Nocturne // You can't enable it if you discard the fragment. The depth is still
//layout(early_fragment_tests) in; // updated (shadow in Shin Megami Tensei Nocturne)
//
// early_fragment_tests must still be enabled in the first pass of the 2 passes algo
// First pass search the first primitive that will write the bad alpha value. Value
// won't be written if the fragment fails the depth test.
//
// In theory the best solution will be do
// 1/ copy the depth buffer
// 2/ do the full depth (current depth writes are disabled)
// 3/ restore the depth buffer for 2nd pass
// Of course, it is likely too costly.
#if PS_DATE == 1 || PS_DATE == 2
layout(early_fragment_tests) in;
#endif
// I don't remember why I set this parameter but it is surely useless // I don't remember why I set this parameter but it is surely useless
//layout(pixel_center_integer) in vec4 gl_FragCoord; //layout(pixel_center_integer) in vec4 gl_FragCoord;
@ -564,15 +577,15 @@ void ps_main()
// Pixel with alpha equal to 1 will failed (128-255) // Pixel with alpha equal to 1 will failed (128-255)
if (C.a > 127.5f) { if (C.a > 127.5f) {
imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID); imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);
return;
} }
return;
#elif PS_DATE == 2 && !defined(DISABLE_GL42_image) #elif PS_DATE == 2 && !defined(DISABLE_GL42_image)
// DATM == 1 // DATM == 1
// Pixel with alpha equal to 0 will failed (0-127) // Pixel with alpha equal to 0 will failed (0-127)
if (C.a < 127.5f) { if (C.a < 127.5f) {
imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID); imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);
return;
} }
return;
#endif #endif
ps_blend(C, alpha_blend); ps_blend(C, alpha_blend);

View File

@ -952,10 +952,23 @@ static const char* tfx_fs_all_glsl =
"#ifndef DISABLE_GL42_image\n" "#ifndef DISABLE_GL42_image\n"
"#if PS_DATE > 0\n" "#if PS_DATE > 0\n"
"// FIXME how to declare memory access\n" "// FIXME how to declare memory access\n"
"layout(r32i, binding = 2) coherent uniform iimage2D img_prim_min;\n" "layout(r32i, binding = 2) uniform iimage2D img_prim_min;\n"
"// Don't enable it. Discard fragment can still write in the depth buffer\n" "// WARNING:\n"
"// it breaks shadow in Shin Megami Tensei Nocturne\n" "// You can't enable it if you discard the fragment. The depth is still\n"
"//layout(early_fragment_tests) in;\n" "// updated (shadow in Shin Megami Tensei Nocturne)\n"
"//\n"
"// early_fragment_tests must still be enabled in the first pass of the 2 passes algo\n"
"// First pass search the first primitive that will write the bad alpha value. Value\n"
"// won't be written if the fragment fails the depth test.\n"
"// \n"
"// In theory the best solution will be do \n"
"// 1/ copy the depth buffer\n"
"// 2/ do the full depth (current depth writes are disabled)\n"
"// 3/ restore the depth buffer for 2nd pass\n"
"// Of course, it is likely too costly.\n"
"#if PS_DATE == 1 || PS_DATE == 2\n"
"layout(early_fragment_tests) in;\n"
"#endif\n"
"\n" "\n"
"// I don't remember why I set this parameter but it is surely useless\n" "// I don't remember why I set this parameter but it is surely useless\n"
"//layout(pixel_center_integer) in vec4 gl_FragCoord;\n" "//layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
@ -1468,15 +1481,15 @@ static const char* tfx_fs_all_glsl =
" // Pixel with alpha equal to 1 will failed (128-255)\n" " // Pixel with alpha equal to 1 will failed (128-255)\n"
" if (C.a > 127.5f) {\n" " if (C.a > 127.5f) {\n"
" imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);\n" " imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);\n"
" return;\n"
" }\n" " }\n"
" return;\n"
"#elif PS_DATE == 2 && !defined(DISABLE_GL42_image)\n" "#elif PS_DATE == 2 && !defined(DISABLE_GL42_image)\n"
" // DATM == 1\n" " // DATM == 1\n"
" // Pixel with alpha equal to 0 will failed (0-127)\n" " // Pixel with alpha equal to 0 will failed (0-127)\n"
" if (C.a < 127.5f) {\n" " if (C.a < 127.5f) {\n"
" imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);\n" " imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);\n"
" return;\n"
" }\n" " }\n"
" return;\n"
"#endif\n" "#endif\n"
"\n" "\n"
" ps_blend(C, alpha_blend);\n" " ps_blend(C, alpha_blend);\n"