diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index f87311c96..e188f6c9b 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -303,6 +303,13 @@ private: map locationTranslate; + // this flag indicates the program was created with glCreateShaderProgram and cannot be relinked + // again (because that function implicitly detaches and destroys the shader). However we only + // need to relink when restoring things like frag data or attrib bindings which must be relinked + // to apply - and since the application *also* could not have relinked them, they must be + // unchanged since creation. So in this case, we can skip the relink since it was impossible for + // the application to modify anything. + bool shaderProgramUnlinkable = false; bool linked; ResourceId stageShaders[6]; }; diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index f2cbd34da..ba99ac4b1 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -1953,8 +1953,10 @@ void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData i CopyProgramFragDataBindings(gl, initial.resource.name, live.name, &m_GL->m_Shaders[prog.stageShaders[4]].reflection); - // we need to re-link the program to apply the bindings. - gl.glLinkProgram(live.name); + // we need to re-link the program to apply the bindings, as long as it's linkable. + // See the comment on shaderProgramUnlinkable for more information. + if(!prog.shaderProgramUnlinkable) + gl.glLinkProgram(live.name); } CopyProgramUniforms(gl, initial.resource.name, live.name); diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index dc7fc7de1..b95e1c415 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -456,6 +456,7 @@ bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type progDetails.linked = true; progDetails.shaders.push_back(liveId); progDetails.stageShaders[ShaderIdx(Type)] = liveId; + progDetails.shaderProgramUnlinkable = true; auto &shadDetails = m_Shaders[liveId];