GLES: Don't skip uniform updates while a program's locations aren't known

UpdateUniforms checked some locations against -1 before queueing the update,
but the GL thread fills them in when it links the program, which can be
later. On drivers that link slowly the check saw -1, the update was dropped
along with its dirty flag, and the uniform stayed unset. On a PowerVR GE8320
and a Mali-G71 the texture clamp values never arrived, so Harvest Moon's and
11655's composites sampled one point of the framebuffer (122k and 76k px off
the Mac's Vulkan render, now 0). The GL thread already skips -1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-14 01:33:32 +02:00
1 parent 7080085571
commit 9bef51177b
1 file changed
+18 -25
+18 -25
View File
@@ -448,23 +448,24 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, const ShaderLanguageDesc
render_->SetUniformF(&u_uvscaleoffset, 4, uvscaleoff);
}
if ((dirty & DIRTY_TEXCLAMP) && u_texclamp != -1) {
// No checks for a location of -1 here: the GL thread fills the locations in when it links the program, which
// may be after this runs, and skips the uniforms a program doesn't have itself. Skipping them here dropped the
// values for good on drivers that link slowly (PowerVR and Mali sampled Harvest Moon's framebuffer at one
// point, with no texture clamp values).
if (dirty & DIRTY_TEXCLAMP) {
float texclamp[4];
float texclampoff[2];
CalcTexClamp(texclamp, texclampoff);
render_->SetUniformF(&u_texclamp, 4, texclamp);
if (u_texclampoff != -1) {
render_->SetUniformF(&u_texclampoff, 2, texclampoff);
}
render_->SetUniformF(&u_texclampoff, 2, texclampoff);
}
if ((dirty & DIRTY_MIPBIAS) && u_mipBias != -1) {
if (dirty & DIRTY_MIPBIAS) {
float mipBias = (float)gstate.getTexLevelOffset16() * (1.0 / 16.0f);
mipBias = (mipBias + 0.5f) / (float)(gstate.getTextureMaxLevel() + 1);
render_->SetUniformF(&u_mipBias, 1, &mipBias);
}
if ((dirty & DIRTY_MIPBIAS) && u_texLodBias != -1) {
// For GPU_USE_SHADER_LOD_BIAS, like ShaderUniforms.cpp: the sampler applies the bias only in auto mode.
float lodBias = gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_AUTO ? (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f) : 0.0f;
render_->SetUniformF(&u_texLodBias, 1, &lodBias);
@@ -526,20 +527,14 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, const ShaderLanguageDesc
}
if (dirty & DIRTY_SHADERBLEND) {
if (u_blendFixA != -1) {
SetColorUniform3(render_, &u_blendFixA, gstate.getFixA());
}
if (u_blendFixB != -1) {
SetColorUniform3(render_, &u_blendFixB, gstate.getFixB());
}
SetColorUniform3(render_, &u_blendFixA, gstate.getFixA());
SetColorUniform3(render_, &u_blendFixB, gstate.getFixB());
const float fbotexSize[2] = {
1.0f / (float)gstate_c.curRTRenderWidth,
1.0f / (float)gstate_c.curRTRenderHeight,
};
if (u_fbotexSize != -1) {
render_->SetUniformF(&u_fbotexSize, 2, fbotexSize);
}
render_->SetUniformF(&u_fbotexSize, 2, fbotexSize);
}
// Lighting
@@ -570,15 +565,13 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, const ShaderLanguageDesc
} else {
SetFloat24Uniform3(render_, &u_lightpos[i], &gstate.lpos[i * 3]);
}
if (u_lightdir[i] != -1) SetFloat24Uniform3Normalized(render_, &u_lightdir[i], &gstate.ldir[i * 3]);
if (u_lightatt[i] != -1) SetFloat24Uniform3(render_, &u_lightatt[i], &gstate.latt[i * 3]);
if (u_lightangle_spotCoef[i] != -1) {
float lightangle_spotCoef[2] = { getFloat24(gstate.lcutoff[i]), PSPLightExponent(getFloat24(gstate.lconv[i])) };
SetFloatUniform2(render_, &u_lightangle_spotCoef[i], lightangle_spotCoef);
}
if (u_lightambient[i] != -1) SetColorUniform3(render_, &u_lightambient[i], gstate.lcolor[i * 3]);
if (u_lightdiffuse[i] != -1) SetColorUniform3(render_, &u_lightdiffuse[i], gstate.lcolor[i * 3 + 1]);
if (u_lightspecular[i] != -1) SetColorUniform3(render_, &u_lightspecular[i], gstate.lcolor[i * 3 + 2]);
SetFloat24Uniform3Normalized(render_, &u_lightdir[i], &gstate.ldir[i * 3]);
SetFloat24Uniform3(render_, &u_lightatt[i], &gstate.latt[i * 3]);
float lightangle_spotCoef[2] = { getFloat24(gstate.lcutoff[i]), PSPLightExponent(getFloat24(gstate.lconv[i])) };
SetFloatUniform2(render_, &u_lightangle_spotCoef[i], lightangle_spotCoef);
SetColorUniform3(render_, &u_lightambient[i], gstate.lcolor[i * 3]);
SetColorUniform3(render_, &u_lightdiffuse[i], gstate.lcolor[i * 3 + 1]);
SetColorUniform3(render_, &u_lightspecular[i], gstate.lcolor[i * 3 + 2]);
}
}
}