diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index f78414fbc..ae19090a4 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -122,6 +122,7 @@ enum GLChunkType BINDATTRIB_LOCATION, UNIFORM_BLOCKBIND, PROGRAMUNIFORM_VECTOR, + PROGRAMUNIFORM_MATRIX, LINKPROGRAM, GEN_PROGRAMPIPE, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 8b3f4e026..c04f7d2b7 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -71,6 +71,7 @@ const char *GLChunkNames[] = "glProgramParameter", "glBindAttribLocation", "glUniformBlockBinding", + "glProgramUniformMatrix*", "glProgramUniformVector*", "glLinkProgram", @@ -290,6 +291,7 @@ WrappedOpenGL::WrappedOpenGL(const wchar_t *logfile, const GLHookSet &funcs) m_DrawFramebufferRecord = NULL; m_ReadFramebufferRecord = NULL; m_TextureUnit = 0; + m_Program = 0; m_LastIndexSize = eGL_NONE; m_LastIndexOffset = 0; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 829ff11df..4262e6d6a 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -113,6 +113,7 @@ class WrappedOpenGL GLResourceRecord *m_DrawFramebufferRecord; GLResourceRecord *m_ReadFramebufferRecord; GLint m_TextureUnit; + GLuint m_Program; // internals Serialiser *m_pSerialiser; @@ -531,6 +532,7 @@ class WrappedOpenGL bool Serialise_glUniformMatrix(GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type); bool Serialise_glUniformVector(GLint location, GLsizei count, const void *value, UniformType type); + bool Serialise_glProgramUniformMatrix(GLuint program, GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type); bool Serialise_glProgramUniformVector(GLuint program, GLint location, GLsizei count, const void *value, UniformType type); IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); @@ -544,6 +546,7 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3fv(GLint location, GLsizei count, const GLfloat *value)); IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4fv(GLint location, GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1i(GLuint program, GLint location, GLint v0)); IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)); IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 4bf1ebf3f..abf71690e 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -139,6 +139,7 @@ struct GLHookSet PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler; PFNGLLINKPROGRAMPROC glLinkProgram; PFNGLPROGRAMPARAMETERIPROC glProgramParameteri; + PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv; PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i; PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv; PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index f1430b6e6..05f230468 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -152,6 +152,7 @@ HookExtension(PFNGLRELEASESHADERCOMPILERPROC, glReleaseShaderCompiler); \ HookExtension(PFNGLLINKPROGRAMPROC, glLinkProgram); \ HookExtension(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, glProgramUniformMatrix4fv); \ HookExtension(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i); \ HookExtension(PFNGLPROGRAMUNIFORM1FVPROC, glProgramUniform1fv); \ HookExtension(PFNGLPROGRAMUNIFORM1IVPROC, glProgramUniform1iv); \ @@ -502,6 +503,7 @@ HookWrapper0(void, glReleaseShaderCompiler); \ HookWrapper1(void, glLinkProgram, GLuint, program); \ HookWrapper3(void, glProgramParameteri, GLuint, program, GLenum, pname, GLint, value); \ + HookWrapper5(void, glProgramUniformMatrix4fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ HookWrapper3(void, glProgramUniform1i, GLuint, program, GLint, location, GLint, v0); \ HookWrapper4(void, glProgramUniform1fv, GLuint, program, GLint, location, GLsizei, count, const GLfloat *, value); \ HookWrapper4(void, glProgramUniform1iv, GLuint, program, GLint, location, GLsizei, count, const GLint *, value); \ diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index dd9b137f1..11e8aa550 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -593,6 +593,8 @@ void WrappedOpenGL::glUseProgram(GLuint program) { m_Real.glUseProgram(program); + m_Program = program; + if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(USEPROGRAM); diff --git a/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp index 650364526..8821b107a 100644 --- a/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp @@ -100,6 +100,16 @@ void WrappedOpenGL::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_MATRIX); + Serialise_glProgramUniformMatrix(m_Program, location, count, transpose, value, MAT4FV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glUniformVector(GLint location, GLsizei count, const void *value, UniformType type) @@ -202,6 +212,16 @@ void WrappedOpenGL::glUniform1f(GLint location, GLfloat value) m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, 1, &value, VEC1FV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform1i(GLint location, GLint value) @@ -215,6 +235,16 @@ void WrappedOpenGL::glUniform1i(GLint location, GLint value) m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, 1, &value, VEC1IV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform1ui(GLint location, GLuint value) @@ -228,6 +258,16 @@ void WrappedOpenGL::glUniform1ui(GLint location, GLuint value) m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, 1, &value, VEC1UIV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform1fv(GLint location, GLsizei count, const GLfloat *value) @@ -241,6 +281,16 @@ void WrappedOpenGL::glUniform1fv(GLint location, GLsizei count, const GLfloat *v m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, count, &value, VEC1FV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform1iv(GLint location, GLsizei count, const GLint *value) @@ -254,6 +304,16 @@ void WrappedOpenGL::glUniform1iv(GLint location, GLsizei count, const GLint *val m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, count, &value, VEC1IV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform1uiv(GLint location, GLsizei count, const GLuint *value) @@ -267,6 +327,16 @@ void WrappedOpenGL::glUniform1uiv(GLint location, GLsizei count, const GLuint *v m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, count, &value, VEC1UIV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform2fv(GLint location, GLsizei count, const GLfloat *value) @@ -280,6 +350,16 @@ void WrappedOpenGL::glUniform2fv(GLint location, GLsizei count, const GLfloat *v m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, count, &value, VEC2FV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform3fv(GLint location, GLsizei count, const GLfloat *value) @@ -293,6 +373,16 @@ void WrappedOpenGL::glUniform3fv(GLint location, GLsizei count, const GLfloat *v m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, count, &value, VEC3FV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glUniform4fv(GLint location, GLsizei count, const GLfloat *value) @@ -306,6 +396,16 @@ void WrappedOpenGL::glUniform4fv(GLint location, GLsizei count, const GLfloat *v m_ContextRecord->AddChunk(scope.Get()); } + else if(m_State == WRITING_IDLE) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); + Serialise_glProgramUniformVector(m_Program, location, count, &value, VEC4FV); + + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), m_Program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glProgramUniformVector(GLuint program, GLint location, GLsizei count, const void *value, UniformType type) @@ -560,3 +660,92 @@ void WrappedOpenGL::glProgramUniform4fv(GLuint program, GLint location, GLsizei } } } + +bool WrappedOpenGL::Serialise_glProgramUniformMatrix(GLuint program, GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type) +{ + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(UniformType, Type, type); + SERIALISE_ELEMENT(int32_t, Loc, location); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(uint8_t, Transpose, transpose); + + size_t elemsPerMat = 0; + + switch(Type) + { + case MAT4FV: elemsPerMat = 16; break; + default: + RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + } + + if(m_State >= WRITING) + { + m_pSerialiser->RawWriteBytes(value, sizeof(float)*elemsPerMat*Count); + } + else if(m_State <= EXECUTING) + { + value = m_pSerialiser->RawReadBytes(sizeof(float)*elemsPerMat*Count); + + GLuint live = GetResourceManager()->GetLiveResource(id).name; + + switch(Type) + { + case MAT4FV: m_Real.glProgramUniformMatrix4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; + default: + RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + } + } + + if(m_pSerialiser->GetDebugText()) + { + switch(Type) + { + case MAT4FV: + { + float *f = (float *)value; + if(Transpose) + { + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[0], f[4], f[8], f[12]); + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[1], f[5], f[9], f[13]); + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[2], f[6], f[10], f[14]); + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[3], f[7], f[11], f[15]); + } + else + { + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[0], f[1], f[2], f[3]); + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[4], f[5], f[6], f[7]); + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[8], f[9], f[10], f[11]); + m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[12], f[13], f[14], f[15]); + } + break; + } + default: + RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + } + } + + return true; +} + +void WrappedOpenGL::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + m_Real.glProgramUniformMatrix4fv(program, location, count, transpose, value); + + if(m_State > WRITING) + { + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_MATRIX); + Serialise_glProgramUniformMatrix(program, location, count, transpose, value, MAT4FV); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + } + else + { + // TODO grab this at capture time as initial state for program resources + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + record->AddChunk(scope.Get()); + } + } +}