From 632aa95c2dbe2b0845893e449ebf308b041f8a70 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 9 Jul 2019 15:25:15 +0200 Subject: [PATCH] gl4: depth test issue in non-autosort mode Depth testing is done in the fragment shader so it shouldn't be done in the a-buffer shader for the first pixel, or until the depth is updated. Fixes flashlight and lightstorm effects in Alone in the Dark --- core/rend/gl4/abuffer.cpp | 65 ++++++++++++++++++++++----------------- core/rend/gl4/gldraw.cpp | 33 ++++++++++---------- core/rend/gles/gldraw.cpp | 3 +- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index f0e9bb0f4..470309fba 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -72,46 +72,53 @@ vec4 resolveAlphaBlend(ivec2 coords) { \n\ vec4 secondaryBuffer = vec4(0.0); // Secondary accumulation buffer \n\ float depth = 1.0; \n\ \n\ + bool do_depth_test = false; \n\ for (int i = 0; i < num_frag; i++) \n\ { \n\ const Pixel pixel = pixels[pixel_list[i]]; \n\ const PolyParam pp = tr_poly_params[getPolyNumber(pixel)]; \n\ #if DEPTH_SORTED != 1 \n\ const float frag_depth = pixel.depth; \n\ - switch (getDepthFunc(pp)) \n\ + if (do_depth_test) \n\ { \n\ - case 0: // Never \n\ - continue; \n\ - case 1: // Greater \n\ - if (frag_depth <= depth) \n\ + switch (getDepthFunc(pp)) \n\ + { \n\ + case 0: // Never \n\ continue; \n\ - break; \n\ - case 2: // Equal \n\ - if (frag_depth != depth) \n\ - continue; \n\ - break; \n\ - case 3: // Greater or equal \n\ - if (frag_depth < depth) \n\ - continue; \n\ - break; \n\ - case 4: // Less \n\ - if (frag_depth >= depth) \n\ - continue; \n\ - break; \n\ - case 5: // Not equal \n\ - if (frag_depth == depth) \n\ - continue; \n\ - break; \n\ - case 6: // Less or equal \n\ - if (frag_depth > depth) \n\ - continue; \n\ - break; \n\ - case 7: // Always \n\ - break; \n\ + case 1: // Greater \n\ + if (frag_depth <= depth) \n\ + continue; \n\ + break; \n\ + case 2: // Equal \n\ + if (frag_depth != depth) \n\ + continue; \n\ + break; \n\ + case 3: // Greater or equal \n\ + if (frag_depth < depth) \n\ + continue; \n\ + break; \n\ + case 4: // Less \n\ + if (frag_depth >= depth) \n\ + continue; \n\ + break; \n\ + case 5: // Not equal \n\ + if (frag_depth == depth) \n\ + continue; \n\ + break; \n\ + case 6: // Less or equal \n\ + if (frag_depth > depth) \n\ + continue; \n\ + break; \n\ + case 7: // Always \n\ + break; \n\ + } \n\ } \n\ \n\ if (getDepthMask(pp)) \n\ + { \n\ depth = frag_depth; \n\ + do_depth_test = true; \n\ + } \n\ #endif \n\ bool area1 = false; \n\ bool shadowed = false; \n\ @@ -207,7 +214,7 @@ void main(void) \n\ ivec2 coords = ivec2(gl_FragCoord.xy); \n\ // Compute and output final color for the frame buffer \n\ // Visualize the number of layers in use \n\ - //FragColor = vec4(float(fillFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT, 0, 0, 1); \n\ + //FragColor = vec4(float(fillAndSortFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT * 4, 0, 0, 1); \n\ FragColor = resolveAlphaBlend(coords); \n\ } \n\ "; diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index d6e5a5f78..ac207c6ad 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -103,7 +103,7 @@ static void SetTextureRepeatMode(int index, GLuint dir, u32 clamp, u32 mirror) } template - static void SetGPState(const PolyParam* gp, int pass, u32 cflip=0) + static void SetGPState(PolyParam* gp, int pass) { if (gp->pcw.Texture && gp->tsp.FilterMode > 1) { @@ -231,14 +231,14 @@ template //set cull mode ! //cflip is required when exploding triangles for triangle sorting //gcflip is global clip flip, needed for when rendering to texture due to mirrored Y direction - SetCull(gp->isp.CullMode^cflip^gcflip); + SetCull(gp->isp.CullMode ^ gcflip); //set Z mode, only if required - if (Type == ListType_Punch_Through || (Type == ListType_Translucent && SortingEnabled)) + if (Type == ListType_Punch_Through) { glcache.DepthFunc(Zfunction[6]); // Greater or equal } - else + else if (Type == ListType_Opaque) { glcache.DepthFunc(Zfunction[gp->isp.DepthMode]); } @@ -246,7 +246,8 @@ template // Depth buffer is updated in pass 0 (and also in pass 1 for OP PT) if (pass < 2) { - // Ignore ZWriteDis for punch-through? fixes Worms World Party + // Z Write Disable seems to be ignored for punch-through polys + // Fixes Worms World Party, Bust-a-Move 4 and Re-Volt if (Type == ListType_Punch_Through) glcache.DepthMask(GL_TRUE); else @@ -256,7 +257,7 @@ template glcache.DepthMask(GL_FALSE); } -template +template static void DrawList(const List& gply, int first, int count, int pass) { PolyParam* params = &gply.head()[first]; @@ -279,7 +280,7 @@ static void DrawList(const List& gply, int first, int count, int pass continue; } } - if (pass == 0 && Type == ListType_Translucent && (params->isp.DepthMode != 7 || params->isp.ZWriteDis)) + if (OnlyAlwaysDepth && (params->isp.DepthMode != 7 || params->isp.ZWriteDis)) { params++; continue; @@ -534,8 +535,8 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glcache.Enable(GL_STENCIL_TEST); glcache.StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 0); - DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 0); + DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 0); + DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 0); // Modifier volumes if (settings.rend.ModifierVolumes) @@ -570,10 +571,10 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glCheck(); //Opaque - DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 1); + DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 1); //Alpha tested - DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 1); + DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 1); // Unbind stencil glActiveTexture(GL_TEXTURE3); @@ -597,7 +598,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glcache.Enable(GL_DEPTH_TEST); glcache.DepthMask(GL_TRUE); - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); } // // PASS 3: Render TR to a-buffers @@ -611,9 +612,9 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) //Alpha blended if (current_pass.autosort) - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more else - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more glCheck(); // Translucent modifier volumes @@ -632,9 +633,9 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glcache.Enable(GL_DEPTH_TEST); if (current_pass.autosort) - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); else - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); // // PASS 3c: Render a-buffer to temporary texture diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 4f0c746ce..51c1a2ca8 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -264,7 +264,8 @@ __forceinline glcache.DepthMask(GL_FALSE); else { - // Ignore ZWriteDis for punch-through? fixes Worms World Party + // Z Write Disable seems to be ignored for punch-through. + // Fixes Worms World Party, Bust-a-Move 4 and Re-Volt if (Type == ListType_Punch_Through) glcache.DepthMask(GL_TRUE); else