Use serialised program initial states to translate uniform locations

* If you're capturing and replaying on the same driver it's insanely
  unlikely that this translation will be anything other than the identity
  map, although it wouldn't be illegal to renumber locations. However this
  should allow moving captures between vendors/driver versions/platforms,
  which in the past wasn't possible because locations would change (quite
  validly) when the programs were recompiled. There might be other issues,
  but at least this one is fixed.
This commit is contained in:
baldurk
2014-11-30 16:05:01 +00:00
parent c4f73c2b58
commit 9748813eb1
6 changed files with 82 additions and 49 deletions
+7 -4
View File
@@ -422,7 +422,7 @@ ResourceFormat MakeResourceFormat(WrappedOpenGL &gl, GLenum target, GLenum fmt)
}
template<const bool CopyUniforms, const bool SerialiseUniforms>
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<GLint, GLint> *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<CopyUniforms, SerialiseUniforms>(gl, NULL, progSrc, progDst, false);
ForAllProgramUniforms<CopyUniforms, SerialiseUniforms>(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<GLint, GLint> *locTranslate, bool writing)
{
const bool CopyUniforms = false;
const bool SerialiseUniforms = true;
ForAllProgramUniforms<CopyUniforms, SerialiseUniforms>(gl, ser, prog, prog, writing);
ForAllProgramUniforms<CopyUniforms, SerialiseUniforms>(gl, ser, prog, prog, locTranslate, writing);
}
template<>
+1 -1
View File
@@ -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<GLint, GLint> *locTranslate, bool writing);
enum GLChunkType
{
+2
View File
@@ -211,6 +211,8 @@ class WrappedOpenGL
}
vector<ResourceId> shaders;
map<GLint, GLint> locationTranslate;
GLuint colOutProg;
bool linked;
ResourceId stageShaders[6];
+2 -2
View File
@@ -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));
}
@@ -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);
}
@@ -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<GLint,GLint> &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<GLint,GLint> &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);
}
}
}