From 6a3250cad28b7c5825f0b9fb1e8616ae165907a5 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sat, 25 Apr 2015 20:23:26 +0200 Subject: [PATCH] gsdx-ogl: fix logz management (FFXII) The issue is that z+1 overflow if z is UINT max log2(z) overflow if z is 0 So let's use an or 1 to avoid both overflow --- plugins/GSdx/res/glsl/tfx_vgs.glsl | 11 +++++++++-- plugins/GSdx/res/glsl_source.h | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/plugins/GSdx/res/glsl/tfx_vgs.glsl b/plugins/GSdx/res/glsl/tfx_vgs.glsl index ae9d78d048..3a92a20165 100644 --- a/plugins/GSdx/res/glsl/tfx_vgs.glsl +++ b/plugins/GSdx/res/glsl/tfx_vgs.glsl @@ -116,6 +116,13 @@ void vs_main() else z = i_z; + if(VS_LOGZ == 1) { + // FIXME some games (FFX12 intro) uses MAX_INT as depth parameter. So I replace the +1 with an OR + // Initially a +1 was done to avoid log2(0) (If I'm correct) + // The or mask won't create any overflow + z |= 1u; + } + // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go) // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel @@ -127,13 +134,13 @@ void vs_main() p.w = 1.0f; #ifdef ZERO_TO_ONE_DEPTH if(VS_LOGZ == 1) { - p.z = log2(float(1u+z)) / 32.0f; + p.z = log2(float(z)) / 32.0f; } else { p.z = float(z) * exp_min32; } #else if(VS_LOGZ == 1) { - p.z = log2(float(1u+z)) / 31.0f - 1.0f; + p.z = log2(float(z)) / 31.0f - 1.0f; } else { p.z = float(z) * exp_min31 - 1.0f; } diff --git a/plugins/GSdx/res/glsl_source.h b/plugins/GSdx/res/glsl_source.h index 335fa60315..45284af96a 100644 --- a/plugins/GSdx/res/glsl_source.h +++ b/plugins/GSdx/res/glsl_source.h @@ -567,6 +567,13 @@ static const char* tfx_vgs_glsl = " else\n" " z = i_z;\n" "\n" + " if(VS_LOGZ == 1) {\n" + " // FIXME some games (FFX12 intro) uses MAX_INT as depth parameter. So I replace the +1 with an OR\n" + " // Initially a +1 was done to avoid log2(0) (If I'm correct)\n" + " // The or mask won't create any overflow\n" + " z |= 1u;\n" + " }\n" + "\n" " // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go)\n" " // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty\n" " // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel\n" @@ -578,13 +585,13 @@ static const char* tfx_vgs_glsl = " p.w = 1.0f;\n" "#ifdef ZERO_TO_ONE_DEPTH\n" " if(VS_LOGZ == 1) {\n" - " p.z = log2(float(1u+z)) / 32.0f;\n" + " p.z = log2(float(z)) / 32.0f;\n" " } else {\n" " p.z = float(z) * exp_min32;\n" " }\n" "#else\n" " if(VS_LOGZ == 1) {\n" - " p.z = log2(float(1u+z)) / 31.0f - 1.0f;\n" + " p.z = log2(float(z)) / 31.0f - 1.0f;\n" " } else {\n" " p.z = float(z) * exp_min31 - 1.0f;\n" " }\n"