Unify more shader uniform update code, fix bug in fallback for Uint8x3ToFloat4.

This commit is contained in:
Henrik Rydgård committed 2026-06-13 10:14:39 +02:00
1 parent 884af80a31
commit c5931ea690
5 files changed
+51 -74

No files matched your search

+1 -1
View File
@@ -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
}
+1
View File
@@ -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;
+16 -37
View File
@@ -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;
}
}
+30
View File
@@ -3,6 +3,8 @@
#include <cstdint>
#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;
}
}
+3 -36
View File
@@ -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);
}