mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 06:56:40 +00:00
Implement glBindFragDataLocationIndexed and glUniformSubroutines
* Note that the uniform subroutines are saved and restored by the render state, but they are not properly restored anywhere where we fetch & restore the current program. Will probably need a special helper class to push/pop that correctly.
This commit is contained in:
@@ -148,8 +148,10 @@ enum GLChunkType
|
||||
PROGRAMPARAMETER,
|
||||
BINDATTRIB_LOCATION,
|
||||
BINDFRAGDATA_LOCATION,
|
||||
BINDFRAGDATA_LOCATION_INDEXED,
|
||||
UNIFORM_BLOCKBIND,
|
||||
STORAGE_BLOCKBIND,
|
||||
UNIFORM_SUBROUTINE,
|
||||
PROGRAMUNIFORM_VECTOR,
|
||||
PROGRAMUNIFORM_MATRIX,
|
||||
LINKPROGRAM,
|
||||
|
||||
@@ -93,8 +93,10 @@ const char *GLChunkNames[] =
|
||||
"glProgramParameter",
|
||||
"glBindAttribLocation",
|
||||
"glBindFragDataLocation",
|
||||
"glBindFragDataLocationIndexed",
|
||||
"glUniformBlockBinding",
|
||||
"glShaderStorageBlockBinding",
|
||||
"glUniformSubroutinesuiv",
|
||||
"glProgramUniformMatrix*",
|
||||
"glProgramUniformVector*",
|
||||
"glLinkProgram",
|
||||
@@ -1722,12 +1724,18 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
|
||||
case BINDFRAGDATA_LOCATION:
|
||||
Serialise_glBindFragDataLocation(0, 0, NULL);
|
||||
break;
|
||||
case BINDFRAGDATA_LOCATION_INDEXED:
|
||||
Serialise_glBindFragDataLocationIndexed(0, 0, 0, NULL);
|
||||
break;
|
||||
case UNIFORM_BLOCKBIND:
|
||||
Serialise_glUniformBlockBinding(0, 0, 0);
|
||||
break;
|
||||
case STORAGE_BLOCKBIND:
|
||||
Serialise_glShaderStorageBlockBinding(0, 0, 0);
|
||||
break;
|
||||
case UNIFORM_SUBROUTINE:
|
||||
Serialise_glUniformSubroutinesuiv(eGL_NONE, 0, NULL);
|
||||
break;
|
||||
case PROGRAMUNIFORM_VECTOR:
|
||||
Serialise_glProgramUniformVector(0, eGL_NONE, 0, 0, UNIFORM_UNKNOWN);
|
||||
break;
|
||||
|
||||
@@ -515,8 +515,10 @@ class WrappedOpenGL
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glProgramParameteri(GLuint program, GLenum pname, GLint value));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glBindAttribLocation(GLuint program, GLuint index, const GLchar *name));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgram(GLuint program));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program));
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, glValidateProgram(GLuint program));
|
||||
|
||||
@@ -424,6 +424,7 @@ struct GLHookSet
|
||||
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||
PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation;
|
||||
PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glBindFragDataLocationIndexed;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer;
|
||||
@@ -476,6 +477,7 @@ struct GLHookSet
|
||||
PFNGLVIEWPORTARRAYVPROC glViewportArrayv;
|
||||
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
PFNGLSHADERSTORAGEBLOCKBINDINGPROC glShaderStorageBlockBinding;
|
||||
PFNGLUNIFORMSUBROUTINESUIVPROC glUniformSubroutinesuiv;
|
||||
PFNGLUNIFORM1FPROC glUniform1f;
|
||||
PFNGLUNIFORM1IPROC glUniform1i;
|
||||
PFNGLUNIFORM1UIPROC glUniform1ui;
|
||||
|
||||
@@ -454,6 +454,7 @@
|
||||
HookExtension(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor); \
|
||||
HookExtension(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); \
|
||||
HookExtension(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation); \
|
||||
HookExtension(PFNGLBINDFRAGDATALOCATIONINDEXEDPROC, glBindFragDataLocationIndexed); \
|
||||
HookExtension(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \
|
||||
HookExtension(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); \
|
||||
HookExtension(PFNGLBINDVERTEXBUFFERPROC, glBindVertexBuffer); \
|
||||
@@ -508,6 +509,7 @@
|
||||
HookExtension(PFNGLVIEWPORTARRAYVPROC, glViewportArrayv); \
|
||||
HookExtension(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding); \
|
||||
HookExtension(PFNGLSHADERSTORAGEBLOCKBINDINGPROC, glShaderStorageBlockBinding); \
|
||||
HookExtension(PFNGLUNIFORMSUBROUTINESUIVPROC, glUniformSubroutinesuiv); \
|
||||
HookExtension(PFNGLUNIFORM1FPROC, glUniform1f); \
|
||||
HookExtension(PFNGLUNIFORM1IPROC, glUniform1i); \
|
||||
HookExtension(PFNGLUNIFORM1UIPROC, glUniform1ui); \
|
||||
@@ -1134,6 +1136,7 @@
|
||||
HookWrapper2(void, glVertexAttribDivisor, GLuint, index, GLuint, divisor); \
|
||||
HookWrapper3(void, glBindAttribLocation, GLuint, program, GLuint, index, const GLchar *, name); \
|
||||
HookWrapper3(void, glBindFragDataLocation, GLuint, program, GLuint, color, const GLchar *, name); \
|
||||
HookWrapper4(void, glBindFragDataLocationIndexed, GLuint, program, GLuint, colorNumber, GLuint, index, const GLchar *, name); \
|
||||
HookWrapper1(void, glEnableVertexAttribArray, GLuint, index); \
|
||||
HookWrapper1(void, glDisableVertexAttribArray, GLuint, index); \
|
||||
HookWrapper4(void, glBindVertexBuffer, GLuint, bindingindex, GLuint, buffer, GLintptr, offset, GLsizei, stride); \
|
||||
@@ -1186,6 +1189,7 @@
|
||||
HookWrapper3(void, glViewportArrayv, GLuint, first, GLsizei, count, const GLfloat *, v); \
|
||||
HookWrapper3(void, glUniformBlockBinding, GLuint, program, GLuint, uniformBlockIndex, GLuint, uniformBlockBinding); \
|
||||
HookWrapper3(void, glShaderStorageBlockBinding, GLuint, program, GLuint, storageBlockIndex, GLuint, storageBlockBinding); \
|
||||
HookWrapper3(void, glUniformSubroutinesuiv, GLenum, shadertype, GLsizei, count, const GLuint *, indices); \
|
||||
HookWrapper2(void, glUniform1f, GLint, location, GLfloat, v0); \
|
||||
HookWrapper2(void, glUniform1i, GLint, location, GLint, v0); \
|
||||
HookWrapper2(void, glUniform1ui, GLint, location, GLuint, v0); \
|
||||
|
||||
@@ -164,6 +164,24 @@ void GLRenderState::FetchState()
|
||||
|
||||
m_Real->glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&Program);
|
||||
m_Real->glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&Pipeline);
|
||||
|
||||
GLenum shs[] = {
|
||||
eGL_VERTEX_SHADER,
|
||||
eGL_TESS_CONTROL_SHADER,
|
||||
eGL_TESS_EVALUATION_SHADER,
|
||||
eGL_GEOMETRY_SHADER,
|
||||
eGL_FRAGMENT_SHADER,
|
||||
eGL_COMPUTE_SHADER
|
||||
};
|
||||
|
||||
RDCCOMPILE_ASSERT(ARRAY_COUNT(shs) == ARRAY_COUNT(Subroutines), "Subroutine array not the right size");
|
||||
for(size_t s=0; s < ARRAY_COUNT(shs); s++)
|
||||
{
|
||||
m_Real->glGetIntegerv(eGL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &Subroutines[s].numSubroutines);
|
||||
|
||||
for(GLint i=0; i < Subroutines[s].numSubroutines; i++)
|
||||
m_Real->glGetUniformSubroutineuiv(shs[s], i, &Subroutines[s].Values[s]);
|
||||
}
|
||||
|
||||
m_Real->glGetIntegerv(eGL_ARRAY_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Array]);
|
||||
m_Real->glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Copy_Read]);
|
||||
@@ -376,6 +394,20 @@ void GLRenderState::ApplyState()
|
||||
|
||||
m_Real->glUseProgram(Program);
|
||||
m_Real->glBindProgramPipeline(Pipeline);
|
||||
|
||||
GLenum shs[] = {
|
||||
eGL_VERTEX_SHADER,
|
||||
eGL_TESS_CONTROL_SHADER,
|
||||
eGL_TESS_EVALUATION_SHADER,
|
||||
eGL_GEOMETRY_SHADER,
|
||||
eGL_FRAGMENT_SHADER,
|
||||
eGL_COMPUTE_SHADER
|
||||
};
|
||||
|
||||
RDCCOMPILE_ASSERT(ARRAY_COUNT(shs) == ARRAY_COUNT(Subroutines), "Subroutine array not the right size");
|
||||
for(size_t s=0; s < ARRAY_COUNT(shs); s++)
|
||||
if(Subroutines[s].numSubroutines > 0)
|
||||
m_Real->glUniformSubroutinesuiv(shs[s], Subroutines[s].numSubroutines, Subroutines[s].Values);
|
||||
|
||||
m_Real->glBindBuffer(eGL_ARRAY_BUFFER, BufferBindings[eBufIdx_Array]);
|
||||
m_Real->glBindBuffer(eGL_COPY_READ_BUFFER, BufferBindings[eBufIdx_Copy_Read]);
|
||||
@@ -529,17 +561,26 @@ void GLRenderState::Clear()
|
||||
RDCEraseEl(Tex2D);
|
||||
RDCEraseEl(Samplers);
|
||||
RDCEraseEl(ActiveTexture);
|
||||
|
||||
RDCEraseEl(Program);
|
||||
RDCEraseEl(Pipeline);
|
||||
|
||||
RDCEraseEl(Subroutines);
|
||||
|
||||
RDCEraseEl(VAO);
|
||||
RDCEraseEl(VertexBuffers);
|
||||
|
||||
RDCEraseEl(GenericVertexAttribs);
|
||||
|
||||
RDCEraseEl(PointFadeThresholdSize);
|
||||
RDCEraseEl(PointSpriteOrigin);
|
||||
RDCEraseEl(LineWidth);
|
||||
RDCEraseEl(PointSize);
|
||||
|
||||
RDCEraseEl(Program);
|
||||
RDCEraseEl(Pipeline);
|
||||
RDCEraseEl(PrimitiveRestartIndex);
|
||||
RDCEraseEl(ClipOrigin);
|
||||
RDCEraseEl(ClipDepth);
|
||||
RDCEraseEl(ProvokingVertex);
|
||||
|
||||
RDCEraseEl(BufferBindings);
|
||||
RDCEraseEl(AtomicCounter);
|
||||
@@ -571,6 +612,7 @@ void GLRenderState::Clear()
|
||||
RDCEraseEl(SampleMask);
|
||||
RDCEraseEl(SampleCoverage);
|
||||
RDCEraseEl(SampleCoverageInvert);
|
||||
RDCEraseEl(MinSampleShading);
|
||||
RDCEraseEl(LogicOp);
|
||||
RDCEraseEl(ColorClearValue);
|
||||
|
||||
@@ -656,6 +698,12 @@ void GLRenderState::Serialise(LogState state, void *ctx, WrappedOpenGL *gl)
|
||||
m_pSerialiser->Serialise("GL_PROGRAM_PIPELINE_BINDING", ID);
|
||||
if(state < WRITING && ID != ResourceId()) Pipeline = rm->GetLiveResource(ID).name;
|
||||
}
|
||||
|
||||
for(size_t s=0; s < ARRAY_COUNT(Subroutines); s++)
|
||||
{
|
||||
m_pSerialiser->Serialise("GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS", Subroutines[s].numSubroutines);
|
||||
m_pSerialiser->Serialise<128>("GL_SUBROUTINE_UNIFORMS", Subroutines[s].Values);
|
||||
}
|
||||
|
||||
{
|
||||
ResourceId ID = ResourceId();
|
||||
|
||||
@@ -86,6 +86,12 @@ struct GLRenderState
|
||||
GLuint Program;
|
||||
GLuint Pipeline;
|
||||
|
||||
struct
|
||||
{
|
||||
GLint numSubroutines;
|
||||
GLuint Values[128];
|
||||
} Subroutines[6];
|
||||
|
||||
enum
|
||||
{
|
||||
eBufIdx_Array,
|
||||
|
||||
@@ -609,6 +609,67 @@ void WrappedOpenGL::glBindFragDataLocation(GLuint program, GLuint color, const G
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices)
|
||||
{
|
||||
SERIALISE_ELEMENT(GLenum, sh, shadertype);
|
||||
SERIALISE_ELEMENT(uint32_t, Count, count);
|
||||
SERIALISE_ELEMENT_ARR(uint32_t, Idxs, indices, Count);
|
||||
|
||||
if(m_State <= EXECUTING)
|
||||
m_Real.glUniformSubroutinesuiv(sh, Count, Idxs);
|
||||
|
||||
SAFE_DELETE_ARRAY(Idxs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedOpenGL::glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices)
|
||||
{
|
||||
m_Real.glUniformSubroutinesuiv(shadertype, count, indices);
|
||||
|
||||
if(m_State >= WRITING_CAPFRAME)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(UNIFORM_SUBROUTINE);
|
||||
Serialise_glUniformSubroutinesuiv(shadertype, count, indices);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name_)
|
||||
{
|
||||
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program)));
|
||||
SERIALISE_ELEMENT(uint32_t, colNum, colorNumber);
|
||||
SERIALISE_ELEMENT(uint32_t, idx, index);
|
||||
|
||||
string name = name_ ? name_ : "";
|
||||
m_pSerialiser->Serialise("Name", name);
|
||||
|
||||
if(m_State == READING)
|
||||
{
|
||||
m_Real.glBindFragDataLocationIndexed(GetResourceManager()->GetLiveResource(id).name, colNum, idx, name.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedOpenGL::glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)
|
||||
{
|
||||
m_Real.glBindFragDataLocationIndexed(program, colorNumber, index, name);
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
|
||||
RDCASSERT(record);
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION_INDEXED);
|
||||
Serialise_glBindFragDataLocationIndexed(program, colorNumber, index, name);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glProgramParameteri(GLuint program, GLenum pname, GLint value)
|
||||
{
|
||||
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program)));
|
||||
|
||||
Reference in New Issue
Block a user