From 8c97cfb7aa90378ee45c94954ea87a7531bc6c08 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 5 Jan 2026 14:36:33 +0000 Subject: [PATCH] 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. --- renderdoc/driver/gl/gl_pixelhistory.cpp | 47 ++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/renderdoc/driver/gl/gl_pixelhistory.cpp b/renderdoc/driver/gl/gl_pixelhistory.cpp index fb255e819..4b65c0977 100644 --- a/renderdoc/driver/gl/gl_pixelhistory.cpp +++ b/renderdoc/driver/gl/gl_pixelhistory.cpp @@ -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,