mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-13 17:25:54 +00:00
Make sure shader&program interface is consistently ready. Refs #166
This commit is contained in:
@@ -249,12 +249,16 @@ class WrappedOpenGL : public IFrameCapturer
|
||||
|
||||
struct ShaderData
|
||||
{
|
||||
ShaderData() : type(eGL_NONE), prog(0) {}
|
||||
|
||||
GLenum type;
|
||||
vector<string> sources;
|
||||
vector<string> includepaths;
|
||||
vector<uint32_t> spirv;
|
||||
ShaderReflection reflection;
|
||||
GLuint prog;
|
||||
|
||||
void Compile(const GLHookSet &gl);
|
||||
};
|
||||
|
||||
struct ProgramData
|
||||
|
||||
@@ -30,6 +30,40 @@
|
||||
|
||||
#include "driver/shaders/spirv/spirv_common.h"
|
||||
|
||||
void WrappedOpenGL::ShaderData::Compile(const GLHookSet &gl)
|
||||
{
|
||||
bool pointSizeUsed = false, clipDistanceUsed = false;
|
||||
if(type == eGL_VERTEX_SHADER) CheckVertexOutputUses(sources, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
GLuint sepProg = prog;
|
||||
|
||||
if(sepProg == 0)
|
||||
sepProg = MakeSeparableShaderProgram(gl, type, sources, NULL);
|
||||
|
||||
if(sepProg == 0)
|
||||
{
|
||||
RDCERR("Couldn't make separable program for shader via patching - functionality will be broken.");
|
||||
}
|
||||
else
|
||||
{
|
||||
prog = sepProg;
|
||||
MakeShaderReflection(gl, type, sepProg, reflection, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(type)), sources, spirv);
|
||||
if(!spirv.empty())
|
||||
DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(type)), spirv, s);
|
||||
|
||||
reflection.Disassembly = s;
|
||||
|
||||
create_array_uninit(reflection.DebugInfo.files, sources.size());
|
||||
for(size_t i=0; i < sources.size(); i++)
|
||||
{
|
||||
reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
|
||||
reflection.DebugInfo.files[i].second = sources[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region Shaders
|
||||
|
||||
bool WrappedOpenGL::Serialise_glCreateShader(GLuint shader, GLenum type)
|
||||
@@ -79,6 +113,8 @@ GLuint WrappedOpenGL::glCreateShader(GLenum type)
|
||||
else
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, res);
|
||||
|
||||
m_Shaders[id].type = type;
|
||||
}
|
||||
|
||||
return real;
|
||||
@@ -142,6 +178,15 @@ void WrappedOpenGL::glShaderSource(GLuint shader, GLsizei count, const GLchar* c
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
|
||||
m_Shaders[id].sources.clear();
|
||||
m_Shaders[id].sources.reserve(count);
|
||||
|
||||
for(GLsizei i=0; i < count; i++)
|
||||
m_Shaders[id].sources.push_back(string[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
|
||||
@@ -152,35 +197,7 @@ bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
|
||||
{
|
||||
ResourceId liveId = GetResourceManager()->GetLiveID(id);
|
||||
|
||||
auto &shadDetails = m_Shaders[liveId];
|
||||
|
||||
bool pointSizeUsed = false, clipDistanceUsed = false;
|
||||
if(shadDetails.type == eGL_VERTEX_SHADER) CheckVertexOutputUses(shadDetails.sources, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
GLuint sepProg = MakeSeparableShaderProgram(m_Real, shadDetails.type, shadDetails.sources, NULL);
|
||||
|
||||
if(sepProg == 0)
|
||||
{
|
||||
RDCERR("Couldn't make separable program for shader via patching - functionality will be broken.");
|
||||
}
|
||||
else
|
||||
{
|
||||
shadDetails.prog = sepProg;
|
||||
MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.sources, shadDetails.spirv);
|
||||
if(!shadDetails.spirv.empty())
|
||||
DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.spirv, s);
|
||||
|
||||
shadDetails.reflection.Disassembly = s;
|
||||
|
||||
create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
|
||||
for(size_t i=0; i < shadDetails.sources.size(); i++)
|
||||
{
|
||||
shadDetails.reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
|
||||
shadDetails.reflection.DebugInfo.files[i].second = shadDetails.sources[i];
|
||||
}
|
||||
}
|
||||
m_Shaders[liveId].Compile(m_Real);
|
||||
|
||||
m_Real.glCompileShader(GetResourceManager()->GetLiveResource(id).name);
|
||||
}
|
||||
@@ -203,6 +220,10 @@ void WrappedOpenGL::glCompileShader(GLuint shader)
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Shaders[GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))].Compile(m_Real);
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedOpenGL::glReleaseShaderCompiler()
|
||||
@@ -260,6 +281,12 @@ void WrappedOpenGL::glAttachShader(GLuint program, GLuint shader)
|
||||
progRecord->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));
|
||||
ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
|
||||
m_Programs[progid].shaders.push_back(shadid);
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glDetachShader(GLuint program, GLuint shader)
|
||||
@@ -309,6 +336,24 @@ void WrappedOpenGL::glDetachShader(GLuint program, GLuint shader)
|
||||
progRecord->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));
|
||||
ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
|
||||
|
||||
if(!m_Programs[progid].linked)
|
||||
{
|
||||
for(auto it = m_Programs[progid].shaders.begin();
|
||||
it != m_Programs[progid].shaders.end(); ++it)
|
||||
{
|
||||
if(*it == shadid)
|
||||
{
|
||||
m_Programs[progid].shaders.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -356,27 +401,12 @@ bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type
|
||||
progDetails.stageShaders[ShaderIdx(Type)] = liveId;
|
||||
|
||||
auto &shadDetails = m_Shaders[liveId];
|
||||
|
||||
bool pointSizeUsed = false, clipDistanceUsed = false;
|
||||
if(Type == eGL_VERTEX_SHADER) CheckVertexOutputUses(src, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
|
||||
shadDetails.type = Type;
|
||||
shadDetails.sources.swap(src);
|
||||
shadDetails.prog = sepprog;
|
||||
MakeShaderReflection(m_Real, Type, real, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.sources, shadDetails.spirv);
|
||||
if(!shadDetails.spirv.empty())
|
||||
DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.spirv, s);
|
||||
|
||||
shadDetails.reflection.Disassembly = s;
|
||||
|
||||
create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
|
||||
for(size_t i=0; i < shadDetails.sources.size(); i++)
|
||||
{
|
||||
shadDetails.reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
|
||||
shadDetails.reflection.DebugInfo.files[i].second = shadDetails.sources[i];
|
||||
}
|
||||
shadDetails.Compile(m_Real);
|
||||
|
||||
GetResourceManager()->AddLiveResource(id, res);
|
||||
}
|
||||
@@ -414,6 +444,28 @@ GLuint WrappedOpenGL::glCreateShaderProgramv(GLenum type, GLsizei count, const G
|
||||
else
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, res);
|
||||
|
||||
vector<string> src;
|
||||
for(size_t i=0; i < count; i++)
|
||||
src.push_back(strings[i]);
|
||||
|
||||
GLuint sepprog = MakeSeparableShaderProgram(m_Real, type, src, NULL);
|
||||
|
||||
GLResource res = ProgramRes(GetCtx(), real);
|
||||
|
||||
auto &progDetails = m_Programs[id];
|
||||
|
||||
progDetails.linked = true;
|
||||
progDetails.shaders.push_back(id);
|
||||
progDetails.stageShaders[ShaderIdx(type)] = id;
|
||||
|
||||
auto &shadDetails = m_Shaders[id];
|
||||
|
||||
shadDetails.type = type;
|
||||
shadDetails.sources.swap(src);
|
||||
shadDetails.prog = sepprog;
|
||||
|
||||
shadDetails.Compile(m_Real);
|
||||
}
|
||||
|
||||
return real;
|
||||
@@ -469,6 +521,8 @@ GLuint WrappedOpenGL::glCreateProgram()
|
||||
else
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, res);
|
||||
|
||||
m_Programs[id].linked = false;
|
||||
}
|
||||
|
||||
return real;
|
||||
@@ -516,6 +570,23 @@ void WrappedOpenGL::glLinkProgram(GLuint program)
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));
|
||||
|
||||
ProgramData &progDetails = m_Programs[progid];
|
||||
|
||||
progDetails.linked = true;
|
||||
|
||||
for(size_t s=0; s < 6; s++)
|
||||
{
|
||||
for(size_t sh=0; sh < progDetails.shaders.size(); sh++)
|
||||
{
|
||||
if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s))
|
||||
progDetails.stageShaders[s] = progDetails.shaders[sh];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
|
||||
@@ -966,6 +1037,47 @@ void WrappedOpenGL::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuin
|
||||
record->AddParent(progrecord);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(program)
|
||||
{
|
||||
ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline));
|
||||
ResourceId progID = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));
|
||||
|
||||
PipelineData &pipeDetails = m_Pipelines[pipeID];
|
||||
ProgramData &progDetails = m_Programs[progID];
|
||||
|
||||
for(size_t s=0; s < 6; s++)
|
||||
{
|
||||
if(stages & ShaderBit(s))
|
||||
{
|
||||
for(size_t sh=0; sh < progDetails.shaders.size(); sh++)
|
||||
{
|
||||
if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s))
|
||||
{
|
||||
pipeDetails.stagePrograms[s] = progID;
|
||||
pipeDetails.stageShaders[s] = progDetails.shaders[sh];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline));
|
||||
PipelineData &pipeDetails = m_Pipelines[pipeID];
|
||||
|
||||
for(size_t s=0; s < 6; s++)
|
||||
{
|
||||
if(stages & ShaderBit(s))
|
||||
{
|
||||
pipeDetails.stagePrograms[s] = ResourceId();
|
||||
pipeDetails.stageShaders[s] = ResourceId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glGenProgramPipelines(GLsizei n, GLuint* pipelines)
|
||||
@@ -1193,33 +1305,7 @@ bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei c
|
||||
for(int32_t i=0; i < Count; i++)
|
||||
shadDetails.includepaths.push_back(pathstrings[i]);
|
||||
|
||||
bool pointSizeUsed = false, clipDistanceUsed = false;
|
||||
if(shadDetails.type == eGL_VERTEX_SHADER) CheckVertexOutputUses(shadDetails.sources, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
GLuint sepProg = MakeSeparableShaderProgram(m_Real, shadDetails.type, shadDetails.sources, &paths);
|
||||
|
||||
if(sepProg == 0)
|
||||
{
|
||||
RDCERR("Couldn't make separable program for shader via patching - functionality will be broken.");
|
||||
}
|
||||
else
|
||||
{
|
||||
shadDetails.prog = sepProg;
|
||||
MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
|
||||
|
||||
string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.sources, shadDetails.spirv);
|
||||
if(!shadDetails.spirv.empty())
|
||||
DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.spirv, s);
|
||||
|
||||
shadDetails.reflection.Disassembly = s;
|
||||
|
||||
create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
|
||||
for(size_t i=0; i < shadDetails.sources.size(); i++)
|
||||
{
|
||||
shadDetails.reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
|
||||
shadDetails.reflection.DebugInfo.files[i].second = shadDetails.sources[i];
|
||||
}
|
||||
}
|
||||
shadDetails.Compile(m_Real);
|
||||
|
||||
m_Real.glCompileShaderIncludeARB(GetResourceManager()->GetLiveResource(id).name, Count, pathstrings, NULL);
|
||||
|
||||
@@ -1244,6 +1330,20 @@ void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count, cons
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
|
||||
|
||||
auto &shadDetails = m_Shaders[id];
|
||||
|
||||
shadDetails.includepaths.clear();
|
||||
shadDetails.includepaths.reserve(count);
|
||||
|
||||
for(int32_t i=0; i < count; i++)
|
||||
shadDetails.includepaths.push_back(path[i]);
|
||||
|
||||
shadDetails.Compile(m_Real);
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedOpenGL::Serialise_glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *str)
|
||||
|
||||
Reference in New Issue
Block a user