From 6d3c34ecd590dba4ae336d9615eb5a7ca652438b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 12 Dec 2023 18:48:22 +0100 Subject: [PATCH] Eliminate inf values resulting from depth range computation. Fixes #17981 --- Common/Math/math_util.h | 4 ++++ GPU/Common/ShaderUniforms.cpp | 5 +++-- GPU/Directx9/ShaderManagerDX9.cpp | 4 ++-- GPU/GLES/ShaderManagerGLES.cpp | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Common/Math/math_util.h b/Common/Math/math_util.h index a821be5fe4a4..aa56b5307377 100644 --- a/Common/Math/math_util.h +++ b/Common/Math/math_util.h @@ -124,6 +124,10 @@ inline bool my_isnanorinf(float f) { return ((f2u.u & 0x7F800000) == 0x7F800000); } +inline float InfToZero(float f) { + return my_isinf(f) ? 0.0f : f; +} + inline int is_even(float d) { float int_part; modff(d / 2.0f, &int_part); diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 5da2b65fad84..4acf2e5245fd 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -248,8 +248,9 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView float vpZCenter = gstate.getViewportZCenter(); // These are just the reverse of the formulas in GPUStateUtils. - float halfActualZRange = gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f; - float inverseDepthScale = gstate_c.vpDepthScale != 0.0f ? 1.0f / gstate_c.vpDepthScale : 0.0f; + float halfActualZRange = InfToZero(gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f); + float inverseDepthScale = InfToZero(gstate_c.vpDepthScale != 0.0f ? 1.0f / gstate_c.vpDepthScale : 0.0f); + float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange; float viewZScale = halfActualZRange * 2.0f; float viewZCenter = minz; diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 21dccf7479bc..8d5f4fb9c1f3 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -460,11 +460,11 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) { float vpZCenter = gstate.getViewportZCenter(); // These are just the reverse of the formulas in GPUStateUtils. - float halfActualZRange = gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f; + float halfActualZRange = InfToZero(gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f); float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange; float viewZScale = halfActualZRange * 2.0f; float viewZCenter = minz; - float reverseScale = gstate_c.vpDepthScale != 0.0f ? 2.0f * (1.0f / gstate_c.vpDepthScale) : 0.0f; + float reverseScale = InfToZero(gstate_c.vpDepthScale != 0.0f ? 2.0f * (1.0f / gstate_c.vpDepthScale) : 0.0f); float reverseTranslate = gstate_c.vpZOffset * 0.5f + 0.5f; float data[4] = { viewZScale, viewZCenter, reverseTranslate, reverseScale }; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 052a99bfca02..a684e7a6beb7 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -591,8 +591,8 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin float vpZCenter = gstate.getViewportZCenter(); // These are just the reverse of the formulas in GPUStateUtils. - float halfActualZRange = gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f; - float inverseDepthScale = gstate_c.vpDepthScale != 0.0f ? 1.0f / gstate_c.vpDepthScale : 0.0f; + float halfActualZRange = InfToZero(gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f); + float inverseDepthScale = InfToZero(gstate_c.vpDepthScale != 0.0f ? 1.0f / gstate_c.vpDepthScale : 0.0f); float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange; float viewZScale = halfActualZRange; float viewZCenter = minz + halfActualZRange;