From c5931ea690c6f56805df2dae8ea8d3e6c25232a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 13 Jun 2026 00:08:04 +0200 Subject: [PATCH] Unify more shader uniform update code, fix bug in fallback for Uint8x3ToFloat4. --- Common/Data/Convert/SmallDataConvert.h | 2 +- Common/Render/DrawBuffer.h | 1 + GPU/Common/ShaderUniforms.cpp | 53 ++++++++------------------ GPU/Common/ShaderUniforms.h | 30 +++++++++++++++ GPU/GLES/ShaderManagerGLES.cpp | 39 ++----------------- 5 files changed, 51 insertions(+), 74 deletions(-) diff --git a/Common/Data/Convert/SmallDataConvert.h b/Common/Data/Convert/SmallDataConvert.h index f628534b73..d186c0f9a5 100644 --- a/Common/Data/Convert/SmallDataConvert.h +++ b/Common/Data/Convert/SmallDataConvert.h @@ -107,7 +107,7 @@ inline void Uint8x3ToFloat4(float f[4], uint32_t u) { f[0] = ((u >> 0) & 0xFF) * (1.0f / 255.0f); f[1] = ((u >> 8) & 0xFF) * (1.0f / 255.0f); f[2] = ((u >> 16) & 0xFF) * (1.0f / 255.0f); - f[3] = ((u >> 24) & 0xFF) * (1.0f / 255.0f); + f[3] = 0.0f; #endif } diff --git a/Common/Render/DrawBuffer.h b/Common/Render/DrawBuffer.h index 7cb5028f6f..6513bd3a0d 100644 --- a/Common/Render/DrawBuffer.h +++ b/Common/Render/DrawBuffer.h @@ -9,6 +9,7 @@ #include "Common/Render/TextureAtlas.h" #include "Common/Math/geom2d.h" #include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" #include "Common/GPU/thin3d.h" struct Atlas; diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 3c52d17e41..ddb505ad60 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -118,20 +118,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool useBuffe } if (dirtyUniforms & DIRTY_FOGCOEF) { - float fogcoef[2] = { - getFloat24(gstate.fog1), - getFloat24(gstate.fog2), - }; - // The PSP just ignores infnan here (ignoring IEEE), so take it down to a valid float. - // Workaround for https://github.com/hrydgard/ppsspp/issues/5384#issuecomment-38365988 - if (my_isnanorinf(fogcoef[0])) { - // Not really sure what a sensible value might be, but let's try 64k. - fogcoef[0] = std::signbit(fogcoef[0]) ? -65535.0f : 65535.0f; - } - if (my_isnanorinf(fogcoef[1])) { - fogcoef[1] = std::signbit(fogcoef[1]) ? -65535.0f : 65535.0f; - } - CopyFloat2(ub->fogCoef, fogcoef); + UpdateFogCoef(gstate, ub->fogCoef); } if (dirtyUniforms & DIRTY_TEX_ALPHA_MUL) { @@ -158,29 +145,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool useBuffe // Texturing if (dirtyUniforms & DIRTY_UVSCALEOFFSET) { - float widthFactor = 1.0f; - float heightFactor = 1.0f; - if (gstate_c.textureIsFramebuffer) { - const float invW = 1.0f / (float)gstate_c.curTextureWidth; - const float invH = 1.0f / (float)gstate_c.curTextureHeight; - const int w = gstate.getTextureWidth(0); - const int h = gstate.getTextureHeight(0); - widthFactor = (float)w * invW; - heightFactor = (float)h * invH; - } - if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) { - // When we are generating UV coordinates through the bezier/spline, we need to apply the scaling. - // However, this is missing a check that we're not getting our UV:s supplied for us in the vertices. - ub->uvScaleOffset[0] = gstate_c.uv.uScale * widthFactor; - ub->uvScaleOffset[1] = gstate_c.uv.vScale * heightFactor; - ub->uvScaleOffset[2] = gstate_c.uv.uOff * widthFactor; - ub->uvScaleOffset[3] = gstate_c.uv.vOff * heightFactor; - } else { - ub->uvScaleOffset[0] = widthFactor; - ub->uvScaleOffset[1] = heightFactor; - ub->uvScaleOffset[2] = 0.0f; - ub->uvScaleOffset[3] = 0.0f; - } + UpdateUVScaleOff(gstate, ub->uvScaleOffset); } if (dirtyUniforms & DIRTY_BEZIERSPLINE) { @@ -292,3 +257,17 @@ void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms) { } } } + +void UpdateFogCoef(const GPUgstate &state, float fogCoef[2]) { + fogCoef[0] = getFloat24(gstate.fog1); + fogCoef[1] = getFloat24(gstate.fog2); + // The PSP just ignores infnan here (ignoring IEEE), so take it down to a valid float. + // Workaround for https://github.com/hrydgard/ppsspp/issues/5384#issuecomment-38365988 + if (my_isnanorinf(fogCoef[0])) { + // Not really sure what a sensible value might be, but let's try 64k. + fogCoef[0] = std::signbit(fogCoef[0]) ? -65535.0f : 65535.0f; + } + if (my_isnanorinf(fogCoef[1])) { + fogCoef[1] = std::signbit(fogCoef[1]) ? -65535.0f : 65535.0f; + } +} diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index 37212a69e1..f6e072a919 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -3,6 +3,8 @@ #include #include "ShaderCommon.h" +#include "Common/Math/math_util.h" +#include "GPU/GPUState.h" // Used by the "modern" backends that use uniform buffers. They can share this without issue. @@ -120,3 +122,31 @@ void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms); uint32_t PackLightControlBits(); uint32_t PackDepalBits(); + +void UpdateFogCoef(const GPUgstate &state, float fogCoef[2]); + +// This happens so much that I want it inline. +inline void UpdateUVScaleOff(const GPUgstate &state, float uvScaleOff[4]) { + float widthFactor; + float heightFactor; + if (gstate_c.textureIsFramebuffer) { + widthFactor = (float)gstate.getTextureWidth(0) / (float)gstate_c.curTextureWidth; + heightFactor = (float)gstate.getTextureHeight(0) / (float)gstate_c.curTextureHeight; + } else { + widthFactor = 1.0f; + heightFactor = 1.0f; + } + if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) { + // When we are generating UV coordinates through the bezier/spline, we need to apply the scaling. + // However, this is missing a check that we're not getting our UV:s supplied for us in the vertices. + uvScaleOff[0] = gstate_c.uv.uScale * widthFactor; + uvScaleOff[1] = gstate_c.uv.vScale * heightFactor; + uvScaleOff[2] = gstate_c.uv.uOff * widthFactor; + uvScaleOff[3] = gstate_c.uv.vOff * heightFactor; + } else { + uvScaleOff[0] = widthFactor; + uvScaleOff[1] = heightFactor; + uvScaleOff[2] = 0.0f; + uvScaleOff[3] = 0.0f; + } +} diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 29f35ff225..b7752b447e 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -447,46 +447,13 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, const ShaderLanguageDesc } } if (dirty & DIRTY_FOGCOEF) { - float fogcoef[2] = { - getFloat24(gstate.fog1), - getFloat24(gstate.fog2), - }; - // The PSP just ignores infnan here (ignoring IEEE), so take it down to a valid float. - // Workaround for https://github.com/hrydgard/ppsspp/issues/5384#issuecomment-38365988 - if (my_isnanorinf(fogcoef[0])) { - // Not really sure what a sensible value might be, but let's try 64k. - fogcoef[0] = std::signbit(fogcoef[0]) ? -65535.0f : 65535.0f; - } - if (my_isnanorinf(fogcoef[1])) { - fogcoef[1] = std::signbit(fogcoef[1]) ? -65535.0f : 65535.0f; - } + float fogcoef[2]; + UpdateFogCoef(gstate, fogcoef); render_->SetUniformF(&u_fogcoef, 2, fogcoef); } if (dirty & DIRTY_UVSCALEOFFSET) { - float widthFactor = 1.0f; - float heightFactor = 1.0f; - if (gstate_c.textureIsFramebuffer) { - const float invW = 1.0f / (float)gstate_c.curTextureWidth; - const float invH = 1.0f / (float)gstate_c.curTextureHeight; - const int w = gstate.getTextureWidth(0); - const int h = gstate.getTextureHeight(0); - widthFactor = (float)w * invW; - heightFactor = (float)h * invH; - } float uvscaleoff[4]; - if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) { - // When we are generating UV coordinates through the bezier/spline, we need to apply the scaling. - // However, this is missing a check that we're not getting our UV:s supplied for us in the vertices. - uvscaleoff[0] = gstate_c.uv.uScale * widthFactor; - uvscaleoff[1] = gstate_c.uv.vScale * heightFactor; - uvscaleoff[2] = gstate_c.uv.uOff * widthFactor; - uvscaleoff[3] = gstate_c.uv.vOff * heightFactor; - } else { - uvscaleoff[0] = widthFactor; - uvscaleoff[1] = heightFactor; - uvscaleoff[2] = 0.0f; - uvscaleoff[3] = 0.0f; - } + UpdateUVScaleOff(gstate, uvscaleoff); render_->SetUniformF(&u_uvscaleoffset, 4, uvscaleoff); }