diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index 042a37dbf..94345b73f 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -422,7 +422,7 @@ ResourceFormat MakeResourceFormat(WrappedOpenGL &gl, GLenum target, GLenum fmt) } template -static void ForAllProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint progSrc, GLuint progDst, bool writing) +static void ForAllProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint progSrc, GLuint progDst, map *locTranslate, bool writing) { const bool ReadSourceProgram = CopyUniforms || (SerialiseUniforms && writing); const bool WriteDestProgram = CopyUniforms || (SerialiseUniforms && !writing); @@ -520,7 +520,10 @@ static void ForAllProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint p GLint newloc = 0; if(WriteDestProgram) + { newloc = gl.glGetUniformLocation(progDst, name.c_str()); + if(locTranslate) (*locTranslate)[srcLocation] = newloc; + } if(CopyUniforms && newloc == -1) continue; @@ -807,14 +810,14 @@ void CopyProgramUniforms(const GLHookSet &gl, GLuint progSrc, GLuint progDst) { const bool CopyUniforms = true; const bool SerialiseUniforms = false; - ForAllProgramUniforms(gl, NULL, progSrc, progDst, false); + ForAllProgramUniforms(gl, NULL, progSrc, progDst, NULL, false); } -void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, bool writing) +void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, map *locTranslate, bool writing) { const bool CopyUniforms = false; const bool SerialiseUniforms = true; - ForAllProgramUniforms(gl, ser, prog, prog, writing); + ForAllProgramUniforms(gl, ser, prog, prog, locTranslate, writing); } template<> diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 665ac6731..05a654005 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -112,7 +112,7 @@ void DoVendorChecks(const GLHookSet &gl); #include "core/core.h" void CopyProgramUniforms(const GLHookSet &gl, GLuint progSrc, GLuint progDst); -void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, bool writing); +void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, map *locTranslate, bool writing); enum GLChunkType { diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index a7b911dfc..2eb5ecc09 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -211,6 +211,8 @@ class WrappedOpenGL } vector shaders; + map locationTranslate; + GLuint colOutProg; bool linked; ResourceId stageShaders[6]; diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 327ee3b7f..bb1f44ea0 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -156,7 +156,7 @@ bool GLResourceManager::Prepare_InitialState(GLResource res) m_pSerialiser->Serialise("Id", Id); - SerialiseProgramUniforms(gl, m_pSerialiser, res.name, true); + SerialiseProgramUniforms(gl, m_pSerialiser, res.name, NULL, true); SetInitialChunk(Id, scope.Get()); } @@ -356,7 +356,7 @@ bool GLResourceManager::Serialise_InitialState(GLResource res) gl.glLinkProgram(initProg); - SerialiseProgramUniforms(gl, m_pSerialiser, initProg, false); + SerialiseProgramUniforms(gl, m_pSerialiser, initProg, &details.locationTranslate, false); SetInitialContents(Id, InitialContentData(ProgramRes(m_GL->GetCtx(), initProg), 0, NULL)); } diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index 4770b601a..0e930946d 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -376,6 +376,10 @@ GLuint WrappedOpenGL::glCreateShaderProgramv(GLenum type, GLsizei count, const G GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); + // we always want to mark programs as dirty so we can serialise their + // locations as initial state (and form a remapping table) + GetResourceManager()->MarkDirtyResource(id); + record->AddChunk(chunk); } else @@ -426,6 +430,10 @@ GLuint WrappedOpenGL::glCreateProgram() GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); + + // we always want to mark programs as dirty so we can serialise their + // locations as initial state (and form a remapping table) + GetResourceManager()->MarkDirtyResource(id); record->AddChunk(chunk); } diff --git a/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp index 11850ab24..51e272a4f 100644 --- a/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp @@ -76,29 +76,39 @@ bool WrappedOpenGL::Serialise_glProgramUniformVector(GLuint program, GLint locat else if(m_State <= EXECUTING) { value = m_pSerialiser->RawReadBytes(elemSize*elemsPerVec*Count); - + + ResourceId liveProgId = GetResourceManager()->GetLiveID(id); GLuint live = GetResourceManager()->GetLiveResource(id).name; + + map &translate = m_Programs[liveProgId].locationTranslate; + if(translate.find(Loc) != translate.end()) + Loc = translate[Loc]; + else + Loc = -1; - switch(Type) + if(Loc >= 0) { - case VEC1iv: m_Real.glProgramUniform1iv(live, Loc, Count, (const GLint *)value); break; - case VEC1uiv: m_Real.glProgramUniform1uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC1fv: m_Real.glProgramUniform1fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC1dv: m_Real.glProgramUniform1dv(live, Loc, Count, (const GLdouble *)value); break; - case VEC2iv: m_Real.glProgramUniform2iv(live, Loc, Count, (const GLint *)value); break; - case VEC2uiv: m_Real.glProgramUniform2uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC2fv: m_Real.glProgramUniform2fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC2dv: m_Real.glProgramUniform2dv(live, Loc, Count, (const GLdouble *)value); break; - case VEC3iv: m_Real.glProgramUniform3iv(live, Loc, Count, (const GLint *)value); break; - case VEC3uiv: m_Real.glProgramUniform3uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC3fv: m_Real.glProgramUniform3fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC3dv: m_Real.glProgramUniform3dv(live, Loc, Count, (const GLdouble *)value); break; - case VEC4iv: m_Real.glProgramUniform4iv(live, Loc, Count, (const GLint *)value); break; - case VEC4uiv: m_Real.glProgramUniform4uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC4fv: m_Real.glProgramUniform4fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC4dv: m_Real.glProgramUniform4dv(live, Loc, Count, (const GLdouble *)value); break; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); + switch(Type) + { + case VEC1iv: m_Real.glProgramUniform1iv(live, Loc, Count, (const GLint *)value); break; + case VEC1uiv: m_Real.glProgramUniform1uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC1fv: m_Real.glProgramUniform1fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC1dv: m_Real.glProgramUniform1dv(live, Loc, Count, (const GLdouble *)value); break; + case VEC2iv: m_Real.glProgramUniform2iv(live, Loc, Count, (const GLint *)value); break; + case VEC2uiv: m_Real.glProgramUniform2uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC2fv: m_Real.glProgramUniform2fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC2dv: m_Real.glProgramUniform2dv(live, Loc, Count, (const GLdouble *)value); break; + case VEC3iv: m_Real.glProgramUniform3iv(live, Loc, Count, (const GLint *)value); break; + case VEC3uiv: m_Real.glProgramUniform3uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC3fv: m_Real.glProgramUniform3fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC3dv: m_Real.glProgramUniform3dv(live, Loc, Count, (const GLdouble *)value); break; + case VEC4iv: m_Real.glProgramUniform4iv(live, Loc, Count, (const GLint *)value); break; + case VEC4uiv: m_Real.glProgramUniform4uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC4fv: m_Real.glProgramUniform4fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC4dv: m_Real.glProgramUniform4dv(live, Loc, Count, (const GLdouble *)value); break; + default: + RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); + } } } @@ -206,31 +216,41 @@ bool WrappedOpenGL::Serialise_glProgramUniformMatrix(GLuint program, GLint locat else if(m_State <= EXECUTING) { value = m_pSerialiser->RawReadBytes(elemSize*elemsPerMat*Count); - + + ResourceId liveProgId = GetResourceManager()->GetLiveID(id); GLuint live = GetResourceManager()->GetLiveResource(id).name; + + map &translate = m_Programs[liveProgId].locationTranslate; + if(translate.find(Loc) != translate.end()) + Loc = translate[Loc]; + else + Loc = -1; - switch(Type) + if(Loc >= 0) { - case MAT2fv: m_Real.glProgramUniformMatrix2fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT2x3fv: m_Real.glProgramUniformMatrix2x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT2x4fv: m_Real.glProgramUniformMatrix2x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT3fv: m_Real.glProgramUniformMatrix3fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT3x2fv: m_Real.glProgramUniformMatrix3x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT3x4fv: m_Real.glProgramUniformMatrix3x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT4fv: m_Real.glProgramUniformMatrix4fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT4x2fv: m_Real.glProgramUniformMatrix4x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT4x3fv: m_Real.glProgramUniformMatrix4x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT2dv: m_Real.glProgramUniformMatrix2dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT2x3dv: m_Real.glProgramUniformMatrix2x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT2x4dv: m_Real.glProgramUniformMatrix2x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT3dv: m_Real.glProgramUniformMatrix3dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT3x2dv: m_Real.glProgramUniformMatrix3x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT3x4dv: m_Real.glProgramUniformMatrix3x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT4dv: m_Real.glProgramUniformMatrix4dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT4x2dv: m_Real.glProgramUniformMatrix4x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT4x3dv: m_Real.glProgramUniformMatrix4x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + switch(Type) + { + case MAT2fv: m_Real.glProgramUniformMatrix2fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT2x3fv: m_Real.glProgramUniformMatrix2x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT2x4fv: m_Real.glProgramUniformMatrix2x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT3fv: m_Real.glProgramUniformMatrix3fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT3x2fv: m_Real.glProgramUniformMatrix3x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT3x4fv: m_Real.glProgramUniformMatrix3x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT4fv: m_Real.glProgramUniformMatrix4fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT4x2fv: m_Real.glProgramUniformMatrix4x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT4x3fv: m_Real.glProgramUniformMatrix4x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + case MAT2dv: m_Real.glProgramUniformMatrix2dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT2x3dv: m_Real.glProgramUniformMatrix2x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT2x4dv: m_Real.glProgramUniformMatrix2x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT3dv: m_Real.glProgramUniformMatrix3dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT3x2dv: m_Real.glProgramUniformMatrix3x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT3x4dv: m_Real.glProgramUniformMatrix3x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT4dv: m_Real.glProgramUniformMatrix4dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT4x2dv: m_Real.glProgramUniformMatrix4x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; + case MAT4x3dv: m_Real.glProgramUniformMatrix4x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; + default: + RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + } } }