Ensure uniforms are updated on GL pixel history programs. Closes #3760

* When we replace a program, GL programs have *state* in the form of uniforms
  and so must be updated each time even if we retrieve the replacement from a
  cache.
This commit is contained in:
baldurk committed 2026-01-05 14:36:33 +00:00
1 parent 856c838def
commit 8c97cfb7aa
1 file changed
+39 -8
+39 -8
View File
@@ -133,18 +133,49 @@ enum class PerFragmentQueryType
PrimitiveId
};
GLuint RefreshUniforms(WrappedOpenGL *driver, GLRenderState &rs, GLuint dstProgram)
{
ContextPair &ctx = driver->GetCtx();
GLuint srcProgram = 0;
if(rs.Program.name)
{
srcProgram = rs.Program.name;
}
else if(rs.Pipeline.name)
{
ResourceId id = driver->GetResourceManager()->GetResID(ProgramPipeRes(ctx, rs.Pipeline.name));
const WrappedOpenGL::PipelineData &pipeDetails = driver->GetPipeline(id);
srcProgram = driver->GetResourceManager()
->GetCurrentResource(pipeDetails.stagePrograms[(size_t)ShaderStage::Pixel])
.name;
}
PerStageReflections stages;
driver->FillReflectionArray(ProgramRes(ctx, srcProgram), stages);
PerStageReflections dstStages;
driver->FillReflectionArray(ProgramRes(ctx, dstProgram), dstStages);
CopyProgramUniforms(stages, srcProgram, dstStages, dstProgram);
return dstProgram;
}
GLuint GetFixedColProgram(WrappedOpenGL *driver, GLReplay *replay,
GLPixelHistoryResources &resources, GLuint currentProgram)
{
GLRenderState rs;
rs.FetchState(driver);
auto programIterator = resources.fixedColPrograms.find(currentProgram);
if(programIterator != resources.fixedColPrograms.end())
{
return programIterator->second;
return RefreshUniforms(driver, rs, programIterator->second);
}
GLRenderState rs;
rs.FetchState(driver);
GLuint ret = driver->glCreateProgram();
replay->CreateShaderReplacementProgram(rs.Program.name, rs.Pipeline.name, ret, ShaderStage::Pixel,
resources.fixedColFragmentShader,
@@ -158,15 +189,15 @@ GLuint GetFixedColProgram(WrappedOpenGL *driver, GLReplay *replay,
GLuint GetPrimitiveIdProgram(WrappedOpenGL *driver, GLReplay *replay,
GLPixelHistoryResources &resources, GLuint currentProgram)
{
GLRenderState rs;
rs.FetchState(driver);
auto programIterator = resources.primIdPrograms.find(currentProgram);
if(programIterator != resources.primIdPrograms.end())
{
return programIterator->second;
return RefreshUniforms(driver, rs, programIterator->second);
}
GLRenderState rs;
rs.FetchState(driver);
GLuint ret = driver->glCreateProgram();
replay->CreateShaderReplacementProgram(rs.Program.name, rs.Pipeline.name, ret, ShaderStage::Pixel,
resources.primitiveIdFragmentShader,