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:
baldurk
2014-11-25 22:18:24 +00:00
parent cbc4c4cc43
commit 3f33541132
8 changed files with 135 additions and 2 deletions
+2
View File
@@ -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,
+8
View File
@@ -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;
+2
View File
@@ -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));
+2
View File
@@ -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;
+4
View File
@@ -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); \
+50 -2
View File
@@ -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();
+6
View File
@@ -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)));