diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 829458b29..33302dc81 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -190,16 +190,24 @@ class WrappedOpenGL struct ProgramData { - ProgramData() : colOutProg(0), linked(false) {} + ProgramData() : colOutProg(0), linked(false) + { + RDCEraseEl(stageShaders); + } vector shaders; GLuint colOutProg; bool linked; + ResourceId stageShaders[6]; }; struct PipelineData { - PipelineData() {} + PipelineData() + { + RDCEraseEl(stagePrograms); + RDCEraseEl(stageShaders); + } struct ProgramUse { @@ -210,6 +218,8 @@ class WrappedOpenGL }; vector programs; + ResourceId stagePrograms[6]; + ResourceId stageShaders[6]; }; map m_Shaders; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 9f6695362..7d823a4cc 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -942,42 +942,15 @@ void GLReplay::SavePipelineState() ResourceId id = rm->GetID(ProgramPipeRes(ctx, curProg)); auto &pipeDetails = m_pDriver->m_Pipelines[id]; - RDCASSERT(pipeDetails.programs.size()); - - // TODO: we could pre-flatten this (to list all the shaders in the pipeline) - - // look at the programs in the pipeline - for(size_t p=0; p < pipeDetails.programs.size(); p++) + for(size_t i=0; i < ARRAY_COUNT(pipeDetails.stageShaders); i++) { - auto &progDetails = m_pDriver->m_Programs[pipeDetails.programs[p].id]; - - RDCASSERT(progDetails.shaders.size()); - - curProg = rm->GetCurrentResource(pipeDetails.programs[p].id).name; - - // look at the shaders in the program - for(int s=0; s < ARRAY_COUNT(shaders); s++) + if(pipeDetails.stageShaders[i] != ResourceId()) { - // if this program is being used for a shader stage - if(pipeDetails.programs[p].use & shaders[s].bit) - { - auto &progDetails = m_pDriver->m_Programs[pipeDetails.programs[p].id]; - - // find the shader stage that's being used - for(size_t i=0; i < progDetails.shaders.size(); i++) - { - if(m_pDriver->m_Shaders[ progDetails.shaders[i] ].type == shaders[s].type) - { - // set Shader ID and bindpoint mapping directly in the pipe state - // store reflection and mapping locally too - stages[s]->Shader = rm->GetOriginalID(progDetails.shaders[i]); - refls[s] = GetShader(progDetails.shaders[i]); - GetMapping(gl, curProg, s, refls[s], stages[s]->BindpointMapping); - mappings[s] = &stages[s]->BindpointMapping; - break; - } - } - } + curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; + stages[i]->Shader = rm->GetOriginalID(pipeDetails.stageShaders[i]); + refls[i] = GetShader(pipeDetails.stageShaders[i]); + GetMapping(gl, curProg, (int)i, refls[i], stages[i]->BindpointMapping); + mappings[i] = &stages[i]->BindpointMapping; } } } @@ -985,24 +958,15 @@ void GLReplay::SavePipelineState() else { auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(ctx, curProg))]; - - RDCASSERT(progDetails.shaders.size()); - - // look at the shaders in the program - for(size_t i=0; i < progDetails.shaders.size(); i++) + + for(size_t i=0; i < ARRAY_COUNT(progDetails.stageShaders); i++) { - // find the matching stage - for(int s=0; s < ARRAY_COUNT(shaders); s++) + if(progDetails.stageShaders[i] != ResourceId()) { - if(m_pDriver->m_Shaders[ progDetails.shaders[i] ].type == shaders[s].type) - { - // set Shader ID and bindpoint mapping directly in the pipe state - // store reflection and mapping locally too - stages[s]->Shader = rm->GetOriginalID(progDetails.shaders[i]); - refls[s] = GetShader(progDetails.shaders[i]); - GetMapping(gl, curProg, s, refls[s], stages[s]->BindpointMapping); - mappings[s] = &stages[s]->BindpointMapping; - } + stages[i]->Shader = rm->GetOriginalID(progDetails.stageShaders[i]); + refls[i] = GetShader(progDetails.stageShaders[i]); + GetMapping(gl, curProg, (int)i, refls[i], stages[i]->BindpointMapping); + mappings[i] = &stages[i]->BindpointMapping; } } } @@ -1186,29 +1150,23 @@ void GLReplay::FillCBufferValue(WrappedOpenGL &gl, GLuint prog, bool bufferBacke { uint32_t *dest = &outVar.value.uv[0]; + uint32_t majorsize = outVar.columns; + uint32_t minorsize = outVar.rows; + if(rowMajor) { - for(uint32_t r=0; r < outVar.rows; r++) - { - if(datasize > 0) - memcpy((byte *)dest, bufdata, RDCMIN(rangelen, outVar.columns*sizeof(float))); - - datasize -= RDCMIN(datasize, matStride); - bufdata += matStride; - dest += outVar.columns; - } + majorsize = outVar.rows; + minorsize = outVar.columns; } - else - { - for(uint32_t c=0; c < outVar.columns; c++) - { - if(datasize > 0) - memcpy((byte *)dest, bufdata, RDCMIN(rangelen, outVar.rows*sizeof(float))); - datasize -= RDCMIN(datasize, matStride); - bufdata += matStride; - dest += outVar.rows; - } + for(uint32_t c=0; c < majorsize; c++) + { + if(datasize > 0) + memcpy((byte *)dest, bufdata, RDCMIN(rangelen, minorsize*sizeof(float))); + + datasize -= RDCMIN(datasize, (size_t)matStride); + bufdata += matStride; + dest += minorsize; } } else diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index ae9689354..ec653f75d 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -436,9 +436,33 @@ bool WrappedOpenGL::Serialise_glLinkProgram(GLuint program) if(m_State == READING) { ResourceId progid = GetResourceManager()->GetLiveID(id); - - m_Programs[progid].linked = true; + ProgramData &progDetails = m_Programs[progid]; + + progDetails.linked = true; + + struct + { + GLenum bit; + GLenum type; + } shaders[] = { + { eGL_VERTEX_SHADER_BIT, eGL_VERTEX_SHADER }, + { eGL_TESS_CONTROL_SHADER_BIT, eGL_TESS_CONTROL_SHADER }, + { eGL_TESS_EVALUATION_SHADER_BIT, eGL_TESS_EVALUATION_SHADER }, + { eGL_GEOMETRY_SHADER_BIT, eGL_GEOMETRY_SHADER }, + { eGL_FRAGMENT_SHADER_BIT, eGL_FRAGMENT_SHADER }, + { eGL_COMPUTE_SHADER_BIT, eGL_COMPUTE_SHADER }, + }; + + for(size_t s=0; s < ARRAY_COUNT(shaders); s++) + { + for(size_t sh=0; sh < progDetails.shaders.size(); sh++) + { + if(m_Shaders[ progDetails.shaders[sh] ].type == shaders[s].type) + progDetails.stageShaders[s] = progDetails.shaders[sh]; + } + } + m_Real.glLinkProgram(GetResourceManager()->GetLiveResource(id).name); } @@ -614,7 +638,39 @@ bool WrappedOpenGL::Serialise_glUseProgramStages(GLuint pipeline, GLbitfield sta ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe); ResourceId liveProgId = GetResourceManager()->GetLiveID(prog); - m_Pipelines[livePipeId].programs.push_back(PipelineData::ProgramUse(liveProgId, Stages)); + PipelineData &pipeDetails = m_Pipelines[livePipeId]; + ProgramData &progDetails = m_Programs[liveProgId]; + + pipeDetails.programs.push_back(PipelineData::ProgramUse(liveProgId, Stages)); + + struct + { + GLenum bit; + GLenum type; + } shaders[] = { + { eGL_VERTEX_SHADER_BIT, eGL_VERTEX_SHADER }, + { eGL_TESS_CONTROL_SHADER_BIT, eGL_TESS_CONTROL_SHADER }, + { eGL_TESS_EVALUATION_SHADER_BIT, eGL_TESS_EVALUATION_SHADER }, + { eGL_GEOMETRY_SHADER_BIT, eGL_GEOMETRY_SHADER }, + { eGL_FRAGMENT_SHADER_BIT, eGL_FRAGMENT_SHADER }, + { eGL_COMPUTE_SHADER_BIT, eGL_COMPUTE_SHADER }, + }; + + for(size_t s=0; s < ARRAY_COUNT(shaders); s++) + { + if(Stages & shaders[s].bit) + { + for(size_t sh=0; sh < progDetails.shaders.size(); sh++) + { + if(m_Shaders[ progDetails.shaders[sh] ].type == shaders[s].type) + { + pipeDetails.stagePrograms[s] = liveProgId; + pipeDetails.stageShaders[s] = progDetails.shaders[sh]; + break; + } + } + } + } m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, Stages,