Don't try to relink programs created by glCreateShaderProgramv

* When creating a program with glCreateShaderProgramv it implicitly acts
  as if the shaders are detached and deleted after linking. This means
  it cannot be relinked again.
* However the only time we need to relink a program is when we are
  copying across fragdata and vertex attrib bindings in case they were
  changed from creation - but for the same reason that we can't relink
  a program to apply them, the application can't either - which means
  the data must be unchanged from creation, and so the copy is not
  needed.
This commit is contained in:
baldurk
2017-05-03 19:46:36 +01:00
parent 9876b6e5cb
commit 390e3c1bf4
3 changed files with 12 additions and 2 deletions
+7
View File
@@ -303,6 +303,13 @@ private:
map<GLint, GLint> 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];
};
+4 -2
View File
@@ -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);
@@ -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];