From a995ee66e2a2673997006b3112c12f677571a1eb Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 13 Dec 2015 14:01:04 +0100 Subject: [PATCH] Change handling of shaders and entry points so they're not aliased --- renderdoc/api/replay/renderdoc_replay.h | 6 +- renderdoc/api/replay/vk_pipestate.h | 2 + renderdoc/core/image_viewer.cpp | 4 +- renderdoc/core/replay_proxy.cpp | 29 +++--- renderdoc/core/replay_proxy.h | 22 ++++- renderdoc/driver/d3d11/d3d11_replay.cpp | 8 +- renderdoc/driver/d3d11/d3d11_replay.h | 4 +- renderdoc/driver/gl/gl_debug.cpp | 16 ++-- renderdoc/driver/gl/gl_replay.cpp | 10 +- renderdoc/driver/gl/gl_replay.h | 4 +- .../driver/gl/wrappers/gl_shader_funcs.cpp | 5 +- renderdoc/driver/shaders/spirv/spirv_common.h | 6 +- .../shaders/spirv/spirv_disassemble.cpp | 96 +++++++++++-------- renderdoc/driver/vulkan/vk_debug.cpp | 15 +-- renderdoc/driver/vulkan/vk_info.cpp | 36 ++++--- renderdoc/driver/vulkan/vk_info.h | 13 ++- renderdoc/driver/vulkan/vk_replay.cpp | 30 +++--- renderdoc/driver/vulkan/vk_replay.h | 4 +- renderdoc/replay/replay_driver.h | 4 +- renderdoc/replay/replay_renderer.cpp | 21 ++-- renderdoc/replay/replay_renderer.h | 3 +- renderdocui/Code/CommonPipelineState.cs | 18 ++++ renderdocui/Interop/ReplayRenderer.cs | 23 ++--- renderdocui/Interop/VulkanPipelineState.cs | 3 + .../Dialogs/ConstantBufferPreviewer.cs | 7 +- 25 files changed, 217 insertions(+), 172 deletions(-) diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 04f749274..c59aa0e32 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -197,7 +197,6 @@ struct IReplayRenderer virtual bool GetTextures(rdctype::array *texs) = 0; virtual bool GetBuffers(rdctype::array *bufs) = 0; virtual bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace) = 0; - virtual ShaderReflection* GetShaderDetails(ResourceId shader) = 0; virtual bool GetDebugMessages(rdctype::array *msgs) = 0; virtual bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history) = 0; @@ -207,7 +206,7 @@ struct IReplayRenderer virtual bool GetUsage(ResourceId id, rdctype::array *usage) = 0; - virtual bool GetCBufferVariableContents(ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) = 0; + virtual bool GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) = 0; virtual bool SaveTexture(const TextureSave &saveData, const char *path) = 0; @@ -265,7 +264,6 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DescribeCounter(Repl extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextures(ReplayRenderer *rend, rdctype::array *texs); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBuffers(ReplayRenderer *rend, rdctype::array *bufs); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace); -extern "C" RENDERDOC_API ShaderReflection* RENDERDOC_CC ReplayRenderer_GetShaderDetails(ReplayRenderer *rend, ResourceId shader); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *msgs); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_PixelHistory(ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history); @@ -275,7 +273,7 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugThread(ReplayRe extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetUsage(ReplayRenderer *rend, ResourceId id, rdctype::array *usage); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents(ReplayRenderer *rend, ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents(ReplayRenderer *rend, ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, const TextureSave &saveData, const char *path); diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index 80992a58e..d13ab300f 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -128,6 +128,8 @@ struct VulkanPipelineState { ShaderStage() : Shader(), ShaderDetails(NULL), customName(false) {} ResourceId Shader; + rdctype::str entryPoint; + rdctype::str ShaderName; bool32 customName; ShaderReflection *ShaderDetails; diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index f7cd9ba99..c1a3a0373 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -126,12 +126,12 @@ class ImageViewer : public IReplayDriver vector EnumerateCounters() { return vector(); } void DescribeCounter(uint32_t counterID, CounterDescription &desc) { RDCEraseEl(desc); desc.counterID = counterID; } vector FetchCounters(uint32_t frameID, uint32_t minEventID, uint32_t maxEventID, const vector &counters) { return vector(); } - void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data) {} + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) {} void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) {} void InitPostVSBuffers(uint32_t frameID, uint32_t eventID) {} MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, uint32_t instID, MeshDataStage stage) { MeshFormat ret; RDCEraseEl(ret); return ret; } ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents) { return ResourceId(); } - ShaderReflection *GetShader(ResourceId id) { return NULL; } + ShaderReflection *GetShader(ResourceId shader, string entryPoint) { return NULL; } bool HasCallstacks() { return false; } void InitCallstackResolver() {} Callstack::StackResolver *GetCallstackResolver() { return NULL; } diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 9e46d5efa..6518409fc 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1303,7 +1303,7 @@ bool ProxySerialiser::Tick() GetBuffer(ResourceId()); break; case eCommand_GetShader: - GetShader(ResourceId()); + GetShader(ResourceId(), ""); break; case eCommand_GetDebugMessages: GetDebugMessages(); @@ -1354,7 +1354,7 @@ bool ProxySerialiser::Tick() { vector vars; vector data; - FillCBufferVariables(ResourceId(), 0, vars, data); + FillCBufferVariables(ResourceId(), "", 0, vars, data); break; } case eCommand_GetBufferData: @@ -1780,16 +1780,17 @@ void ProxySerialiser::DescribeCounter(uint32_t counterID, CounterDescription &de return; } -void ProxySerialiser::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data) +void ProxySerialiser::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) { m_ToReplaySerialiser->Serialise("", shader); + m_ToReplaySerialiser->Serialise("", entryPoint); m_ToReplaySerialiser->Serialise("", cbufSlot); m_ToReplaySerialiser->Serialise("", outvars); m_ToReplaySerialiser->Serialise("", (vector &)data); if(m_ReplayHost) { - m_Remote->FillCBufferVariables(shader, cbufSlot, outvars, data); + m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data); } else { @@ -1797,8 +1798,6 @@ void ProxySerialiser::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, return; } - m_FromReplaySerialiser->Serialise("", shader); - m_FromReplaySerialiser->Serialise("", cbufSlot); m_FromReplaySerialiser->Serialise("", outvars); return; @@ -1945,13 +1944,14 @@ ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverla return ret; } -ShaderReflection *ProxySerialiser::GetShader(ResourceId id) +ShaderReflection *ProxySerialiser::GetShader(ResourceId id, string entryPoint) { if(m_ReplayHost) { m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", entryPoint); - ShaderReflection *refl = m_Remote->GetShader(id); + ShaderReflection *refl = m_Remote->GetShader(id, entryPoint); bool hasrefl = (refl != NULL); m_FromReplaySerialiser->Serialise("", hasrefl); @@ -1962,9 +1962,12 @@ ShaderReflection *ProxySerialiser::GetShader(ResourceId id) return NULL; } - if(m_ShaderReflectionCache.find(id) == m_ShaderReflectionCache.end()) + ShaderReflKey key(id, entryPoint); + + if(m_ShaderReflectionCache.find(key) == m_ShaderReflectionCache.end()) { m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", entryPoint); if(!SendReplayCommand(eCommand_GetShader)) return NULL; @@ -1974,17 +1977,17 @@ ShaderReflection *ProxySerialiser::GetShader(ResourceId id) if(hasrefl) { - m_ShaderReflectionCache[id] = new ShaderReflection(); + m_ShaderReflectionCache[key] = new ShaderReflection(); - m_FromReplaySerialiser->Serialise("", *m_ShaderReflectionCache[id]); + m_FromReplaySerialiser->Serialise("", *m_ShaderReflectionCache[key]); } else { - m_ShaderReflectionCache[id] = NULL; + m_ShaderReflectionCache[key] = NULL; } } - return m_ShaderReflectionCache[id]; + return m_ShaderReflectionCache[key]; } void ProxySerialiser::FreeTargetResource(ResourceId id) diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 66488c9b4..b2e653d8f 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -345,7 +345,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver void DescribeCounter(uint32_t counterID, CounterDescription &desc); vector FetchCounters(uint32_t frameID, uint32_t minEventID, uint32_t maxEventID, const vector &counterID); - void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data); + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); @@ -355,7 +355,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents); - ShaderReflection *GetShader(ResourceId id); + ShaderReflection *GetShader(ResourceId shader, string entryPoint); bool HasCallstacks(); void InitCallstackResolver(); @@ -429,7 +429,23 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver map m_LiveIDs; - map m_ShaderReflectionCache; + struct ShaderReflKey + { + ShaderReflKey() {} + ShaderReflKey(ResourceId i, string e) : id(i), entryPoint(e) {} + + ResourceId id; + string entryPoint; + bool operator < (const ShaderReflKey &o) const + { + if(id != o.id) + return id < o.id; + + return entryPoint < o.entryPoint; + } + }; + + map m_ShaderReflectionCache; Network::Socket *m_Socket; Serialiser *m_FromReplaySerialiser; diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 2d955c45a..64596857d 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -293,9 +293,9 @@ FetchTexture D3D11Replay::GetTexture(ResourceId id) return tex; } -ShaderReflection *D3D11Replay::GetShader(ResourceId id) +ShaderReflection *D3D11Replay::GetShader(ResourceId shader, string entryPoint) { - auto it = WrappedShader::m_ShaderList.find(id); + auto it = WrappedShader::m_ShaderList.find(shader); if(it == WrappedShader::m_ShaderList.end()) return NULL; @@ -450,7 +450,7 @@ D3D11PipelineState D3D11Replay::MakePipelineState() ResourceId layoutId = GetIDForResource(rs->IA.Layout); ret.m_IA.layout = rm->GetOriginalID(layoutId); - ret.m_IA.Bytecode = GetShader(layoutId); + ret.m_IA.Bytecode = GetShader(layoutId, ""); create_array_uninit(ret.m_IA.layouts, vec.size()); @@ -1379,7 +1379,7 @@ void D3D11Replay::RenderHighlightBox(float w, float h, float scale) m_pDevice->GetDebugManager()->RenderHighlightBox(w, h, scale); } -void D3D11Replay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data) +void D3D11Replay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) { auto it = WrappedShader::m_ShaderList.find(shader); diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 59a41b4a5..06efca6fe 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -53,7 +53,7 @@ class D3D11Replay : public IReplayDriver vector GetDebugMessages(); - ShaderReflection *GetShader(ResourceId id); + ShaderReflection *GetShader(ResourceId shader, string entryPoint); vector GetUsage(ResourceId id); @@ -115,7 +115,7 @@ class D3D11Replay : public IReplayDriver void RenderHighlightBox(float w, float h, float scale); - void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data); + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); vector PixelHistory(uint32_t frameID, vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 1d3255d8b..bbe24a365 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1742,7 +1742,7 @@ void GLReplay::SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint frag CopyProgramUniforms(gl.GetHookset(), progsrc, progdst); if(i == 0) - CopyProgramAttribBindings(gl.GetHookset(), progsrc, progdst, GetShader(pipeDetails.stageShaders[i])); + CopyProgramAttribBindings(gl.GetHookset(), progsrc, progdst, GetShader(pipeDetails.stageShaders[i], "")); } } } @@ -1762,7 +1762,7 @@ void GLReplay::SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint frag CopyProgramUniforms(gl.GetHookset(), Program, progdst); if(i == 0) - CopyProgramAttribBindings(gl.GetHookset(), Program, progdst, GetShader(progDetails.stageShaders[i])); + CopyProgramAttribBindings(gl.GetHookset(), Program, progdst, GetShader(progDetails.stageShaders[i], "")); } } } @@ -2353,7 +2353,7 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) if(pipeDetails.stageShaders[0] != ResourceId()) { - vsRefl = GetShader(pipeDetails.stageShaders[0]); + vsRefl = GetShader(pipeDetails.stageShaders[0], ""); vsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[0]].prog; vsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[0]).name; } @@ -2364,13 +2364,13 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) } if(pipeDetails.stageShaders[2] != ResourceId()) { - tesRefl = GetShader(pipeDetails.stageShaders[2]); + tesRefl = GetShader(pipeDetails.stageShaders[2], ""); tesProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[2]].prog; tesProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[2]).name; } if(pipeDetails.stageShaders[3] != ResourceId()) { - gsRefl = GetShader(pipeDetails.stageShaders[3]); + gsRefl = GetShader(pipeDetails.stageShaders[3], ""); gsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[3]].prog; gsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[3]).name; } @@ -2382,7 +2382,7 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) if(progDetails.stageShaders[0] != ResourceId()) { - vsRefl = GetShader(progDetails.stageShaders[0]); + vsRefl = GetShader(progDetails.stageShaders[0], ""); vsProg = m_pDriver->m_Shaders[progDetails.stageShaders[0]].prog; } if(progDetails.stageShaders[1] != ResourceId()) @@ -2391,12 +2391,12 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) } if(progDetails.stageShaders[2] != ResourceId()) { - tesRefl = GetShader(progDetails.stageShaders[2]); + tesRefl = GetShader(progDetails.stageShaders[2], ""); tesProg = m_pDriver->m_Shaders[progDetails.stageShaders[2]].prog; } if(progDetails.stageShaders[3] != ResourceId()) { - gsRefl = GetShader(progDetails.stageShaders[3]); + gsRefl = GetShader(progDetails.stageShaders[3], ""); gsProg = m_pDriver->m_Shaders[progDetails.stageShaders[3]].prog; } diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 34c465737..417f528f1 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -788,9 +788,9 @@ vector GLReplay::GetDebugMessages() return m_pDriver->GetDebugMessages(); } -ShaderReflection *GLReplay::GetShader(ResourceId id) +ShaderReflection *GLReplay::GetShader(ResourceId shader, string entryPoint) { - auto &shaderDetails = m_pDriver->m_Shaders[id]; + auto &shaderDetails = m_pDriver->m_Shaders[shader]; if(shaderDetails.prog == 0) { @@ -1044,7 +1044,7 @@ void GLReplay::SavePipelineState() { curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; stages[i]->Shader = rm->GetOriginalID(pipeDetails.stageShaders[i]); - refls[i] = GetShader(pipeDetails.stageShaders[i]); + refls[i] = GetShader(pipeDetails.stageShaders[i], ""); GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); mappings[i] = &stages[i]->BindpointMapping; } @@ -1064,7 +1064,7 @@ void GLReplay::SavePipelineState() if(progDetails.stageShaders[i] != ResourceId()) { stages[i]->Shader = rm->GetOriginalID(progDetails.stageShaders[i]); - refls[i] = GetShader(progDetails.stageShaders[i]); + refls[i] = GetShader(progDetails.stageShaders[i], ""); GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); mappings[i] = &stages[i]->BindpointMapping; } @@ -2019,7 +2019,7 @@ void GLReplay::FillCBufferVariables(WrappedOpenGL &gl, GLuint prog, bool bufferB } } -void GLReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data) +void GLReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) { WrappedOpenGL &gl = *m_pDriver; diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index a4d0cfc8b..e118b6920 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -98,7 +98,7 @@ class GLReplay : public IReplayDriver vector GetTextures(); FetchTexture GetTexture(ResourceId id) { return m_CachedTextures[id]; } - ShaderReflection *GetShader(ResourceId id); + ShaderReflection *GetShader(ResourceId shader, string entryPoint); vector GetDebugMessages(); @@ -159,7 +159,7 @@ class GLReplay : public IReplayDriver void RenderHighlightBox(float w, float h, float scale); - void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data); + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); vector PixelHistory(uint32_t frameID, vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index f689959d3..459e3ca73 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -55,9 +55,8 @@ void WrappedOpenGL::ShaderData::Compile(const GLHookSet &gl) if(!spirvwords.empty()) ParseSPIRV(&spirvwords.front(), spirvwords.size(), spirv); - spirv.Disassemble(); - - reflection.Disassembly = spirv.m_Disassembly; + // for classic GL, entry point is always main + reflection.Disassembly = spirv.Disassemble("main"); create_array_uninit(reflection.DebugInfo.files, sources.size()); for(size_t i=0; i < sources.size(); i++) diff --git a/renderdoc/driver/shaders/spirv/spirv_common.h b/renderdoc/driver/shaders/spirv/spirv_common.h index 347cfeaeb..75003e67e 100644 --- a/renderdoc/driver/shaders/spirv/spirv_common.h +++ b/renderdoc/driver/shaders/spirv/spirv_common.h @@ -77,13 +77,11 @@ struct SPVModule vector globals; // global variables vector funcs; // functions vector structs; // struct types - - string m_Disassembly; SPVInstruction *GetByID(uint32_t id); - void Disassemble(); + string Disassemble(const string &entryPoint); - void MakeReflection(ShaderReflection *reflection, ShaderBindpointMapping *mapping); + void MakeReflection(const string &entryPoint, ShaderReflection *reflection, ShaderBindpointMapping *mapping); }; string CompileSPIRV(SPIRVShaderStage shadType, const vector &sources, vector &spirv); diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 910486d0d..ddd590e23 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -1461,45 +1461,49 @@ SPVInstruction * SPVModule::GetByID(uint32_t id) return &op; } -void SPVModule::Disassemble() +string SPVModule::Disassemble(const string &entryPoint) { - m_Disassembly = "SPIR-V:\n\n"; + string retDisasm = ""; + + // TODO filter to only functions/resources used by entryPoint + + retDisasm = "SPIR-V:\n\n"; const char *gen = "Unrecognised"; for(size_t i=0; i < ARRAY_COUNT(KnownGenerators); i++) if(KnownGenerators[i].magic == generator) gen = KnownGenerators[i].name; - m_Disassembly += StringFormat::Fmt("Version %u, Generator %08x (%s)\n", moduleVersion, generator, gen); - m_Disassembly += StringFormat::Fmt("IDs up to {%u}\n", (uint32_t)ids.size()); + retDisasm += StringFormat::Fmt("Version %u, Generator %08x (%s)\n", moduleVersion, generator, gen); + retDisasm += StringFormat::Fmt("IDs up to {%u}\n", (uint32_t)ids.size()); - m_Disassembly += "\n"; + retDisasm += "\n"; - m_Disassembly += StringFormat::Fmt("Source is %s %u\n", ToStr::Get(sourceLang).c_str(), sourceVer); + retDisasm += StringFormat::Fmt("Source is %s %u\n", ToStr::Get(sourceLang).c_str(), sourceVer); for(size_t s=0; s < sourceexts.size(); s++) - m_Disassembly += StringFormat::Fmt(" + %s\n", sourceexts[s]->str.c_str()); + retDisasm += StringFormat::Fmt(" + %s\n", sourceexts[s]->str.c_str()); - m_Disassembly += "\n"; + retDisasm += "\n"; - m_Disassembly += "Capabilities:"; + retDisasm += "Capabilities:"; for(size_t c=0; c < capabilities.size(); c++) - m_Disassembly += StringFormat::Fmt(" %s", ToStr::Get(capabilities[c]).c_str()); - m_Disassembly += "\n"; + retDisasm += StringFormat::Fmt(" %s", ToStr::Get(capabilities[c]).c_str()); + retDisasm += "\n"; for(size_t i=0; i < entries.size(); i++) { RDCASSERT(entries[i]->entry); uint32_t func = entries[i]->entry->func; RDCASSERT(ids[func]); - m_Disassembly += StringFormat::Fmt("Entry point '%s' (%s)\n", ids[func]->str.c_str(), ToStr::Get(entries[i]->entry->model).c_str()); + retDisasm += StringFormat::Fmt("Entry point '%s' (%s)\n", ids[func]->str.c_str(), ToStr::Get(entries[i]->entry->model).c_str()); for(size_t m=0; m < entries[i]->entry->modes.size(); m++) { SPVExecutionMode &mode = entries[i]->entry->modes[m]; - m_Disassembly += StringFormat::Fmt(" %s", ToStr::Get(mode.mode).c_str()); + retDisasm += StringFormat::Fmt(" %s", ToStr::Get(mode.mode).c_str()); if(mode.mode == spv::ExecutionModeInvocations || mode.mode == spv::ExecutionModeOutputVertices) - m_Disassembly += StringFormat::Fmt(" = %u", mode.x); + retDisasm += StringFormat::Fmt(" = %u", mode.x); if(mode.mode == spv::ExecutionModeLocalSize || mode.mode == spv::ExecutionModeLocalSizeHint) - m_Disassembly += StringFormat::Fmt(" = <%u, %u, %u>", mode.x, mode.y, mode.z); + retDisasm += StringFormat::Fmt(" = <%u, %u, %u>", mode.x, mode.y, mode.z); if(mode.mode == spv::ExecutionModeVecTypeHint) { uint16_t dataType = (mode.x & 0xffff); @@ -1507,33 +1511,33 @@ void SPVModule::Disassemble() switch(dataType) { // 0 represents an 8-bit integer value. - case 0: m_Disassembly += StringFormat::Fmt(" = byte%u", numComps); break; + case 0: retDisasm += StringFormat::Fmt(" = byte%u", numComps); break; // 1 represents a 16-bit integer value. - case 1: m_Disassembly += StringFormat::Fmt(" = short%u", numComps); break; + case 1: retDisasm += StringFormat::Fmt(" = short%u", numComps); break; // 2 represents a 32-bit integer value. - case 2: m_Disassembly += StringFormat::Fmt(" = int%u", numComps); break; + case 2: retDisasm += StringFormat::Fmt(" = int%u", numComps); break; // 3 represents a 64-bit integer value. - case 3: m_Disassembly += StringFormat::Fmt(" = longlong%u", numComps); break; + case 3: retDisasm += StringFormat::Fmt(" = longlong%u", numComps); break; // 4 represents a 16-bit float value. - case 4: m_Disassembly += StringFormat::Fmt(" = half%u", numComps); break; + case 4: retDisasm += StringFormat::Fmt(" = half%u", numComps); break; // 5 represents a 32-bit float value. - case 5: m_Disassembly += StringFormat::Fmt(" = float%u", numComps); break; + case 5: retDisasm += StringFormat::Fmt(" = float%u", numComps); break; // 6 represents a 64-bit float value. - case 6: m_Disassembly += StringFormat::Fmt(" = double%u", numComps); break; + case 6: retDisasm += StringFormat::Fmt(" = double%u", numComps); break; // ... - default: m_Disassembly += StringFormat::Fmt(" = invalid%u", numComps); break; + default: retDisasm += StringFormat::Fmt(" = invalid%u", numComps); break; } } - m_Disassembly += "\n"; + retDisasm += "\n"; } } - m_Disassembly += "\n"; + retDisasm += "\n"; for(size_t i=0; i < structs.size(); i++) { - m_Disassembly += StringFormat::Fmt("struct %s {\n", structs[i]->type->GetName().c_str()); + retDisasm += StringFormat::Fmt("struct %s {\n", structs[i]->type->GetName().c_str()); for(size_t c=0; c < structs[i]->type->children.size(); c++) { auto member = structs[i]->type->children[c]; @@ -1543,9 +1547,9 @@ void SPVModule::Disassemble() if(varName.empty()) varName = StringFormat::Fmt("_member%u", c); - m_Disassembly += StringFormat::Fmt(" %s;\n", member.first->DeclareVariable(structs[i]->type->decorations[c], varName).c_str()); + retDisasm += StringFormat::Fmt(" %s;\n", member.first->DeclareVariable(structs[i]->type->decorations[c], varName).c_str()); } - m_Disassembly += StringFormat::Fmt("}; // struct %s\n\n", structs[i]->type->GetName().c_str()); + retDisasm += StringFormat::Fmt("}; // struct %s\n\n", structs[i]->type->GetName().c_str()); } for(size_t i=0; i < globals.size(); i++) @@ -1564,10 +1568,10 @@ void SPVModule::Disassemble() } string varName = globals[i]->str; - m_Disassembly += StringFormat::Fmt("%s %s;\n", ToStr::Get(globals[i]->var->storage).c_str(), globals[i]->var->type->DeclareVariable(globals[i]->decorations, varName).c_str()); + retDisasm += StringFormat::Fmt("%s %s;\n", ToStr::Get(globals[i]->var->storage).c_str(), globals[i]->var->type->DeclareVariable(globals[i]->decorations, varName).c_str()); } - m_Disassembly += "\n"; + retDisasm += "\n"; for(size_t f=0; f < funcs.size(); f++) { @@ -1591,7 +1595,7 @@ void SPVModule::Disassemble() args += ", "; } - m_Disassembly += StringFormat::Fmt("%s %s(%s)%s {\n", func->retType->GetName().c_str(), funcs[f]->str.c_str(), args.c_str(), OptionalFlagString(func->control).c_str()); + retDisasm += StringFormat::Fmt("%s %s(%s)%s {\n", func->retType->GetName().c_str(), funcs[f]->str.c_str(), args.c_str(), OptionalFlagString(func->control).c_str()); // local copy of variables vector vector vars = func->variables; @@ -2009,13 +2013,13 @@ void SPVModule::Disassemble() for(size_t v=0; v < vars.size(); v++) { RDCASSERT(vars[v]->var && vars[v]->var->type); - m_Disassembly += string(indent, ' ') + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; + retDisasm += string(indent, ' ') + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; varDeclared[v] = true; } if(!vars.empty()) - m_Disassembly += "\n"; + retDisasm += "\n"; #endif vector selectionstack; @@ -2176,8 +2180,8 @@ void SPVModule::Disassemble() // begins and continue as normal. if(indent > tabSize) { - m_Disassembly += string(tabSize, ' '); - m_Disassembly += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; + retDisasm += string(tabSize, ' '); + retDisasm += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; } else { @@ -2229,8 +2233,8 @@ void SPVModule::Disassemble() // begins and continue as normal. if(indent > tabSize) { - m_Disassembly += string(tabSize, ' '); - m_Disassembly += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; + retDisasm += string(tabSize, ' '); + retDisasm += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; } else { @@ -2275,8 +2279,8 @@ void SPVModule::Disassemble() // begins and continue as normal. if(indent > tabSize) { - m_Disassembly += string(tabSize, ' '); - m_Disassembly += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; + retDisasm += string(tabSize, ' '); + retDisasm += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; } else { @@ -2307,12 +2311,14 @@ void SPVModule::Disassemble() funcops[o]->line = (int)o; } - m_Disassembly += funcDisassembly; + retDisasm += funcDisassembly; SAFE_DELETE_ARRAY(varDeclared); - m_Disassembly += StringFormat::Fmt("} // %s\n\n", funcs[f]->str.c_str()); + retDisasm += StringFormat::Fmt("} // %s\n\n", funcs[f]->str.c_str()); } + + return retDisasm; } void MakeConstantBlockVariables(SPVTypeData *type, rdctype::array &cblock) @@ -2577,12 +2583,18 @@ void AddSignatureParameter(uint32_t id, uint32_t childIdx, string varName, SPVTy } } -void SPVModule::MakeReflection(ShaderReflection *reflection, ShaderBindpointMapping *mapping) +void SPVModule::MakeReflection(const string &entryPoint, ShaderReflection *reflection, ShaderBindpointMapping *mapping) { vector inputs; vector outputs; vector cblocks; vector resources; + + // VKTODOLOW filter to only functions/resources used by entryPoint + + // VKTODOLOW set this properly + reflection->DebugInfo.entryFile = 0; + reflection->DebugInfo.entryFunc = entryPoint; create_array_uninit(mapping->InputAttributes, 16); for(size_t i=0; i < 16; i++) mapping->InputAttributes[i] = -1; diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index df9d3cbde..1972313a9 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -1873,7 +1873,7 @@ void VulkanDebugManager::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo & stages[stageCount].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stages[stageCount].stage = (VkShaderStageFlagBits)(1<GetCurrentHandle(pipeInfo.shaders[i].module); - stages[stageCount].pName = pipeInfo.shaders[i].name.c_str(); + stages[stageCount].pName = pipeInfo.shaders[i].entryPoint.c_str(); stages[stageCount].pNext = NULL; stages[stageCount].pSpecializationInfo = NULL; stageCount++; @@ -3888,12 +3888,13 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) if(p.shaders[0].module == ResourceId()) return; - // VKTODOHIGH handle shadermodule vs specific shader - const VulkanCreationInfo::ShaderModule &m = c.m_ShaderModule[p.shaders[0].module]; + const VulkanCreationInfo::ShaderModule &m = c.m_ShaderModule[ p.shaders[0].module ]; + + ShaderReflection *refl = p.shaders[0].refl; // no outputs from this shader? unexpected but theoretically possible (dummy VS before // tessellation maybe). Just fill out an empty data set - if(m.refl.OutputSig.count == 0) + if(refl->OutputSig.count == 0) { // empty vertex output signature m_PostVSData[idx].vsin.topo = p.topology; @@ -4109,7 +4110,7 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) uint32_t bufStride = 0; vector modSpirv = m.spirv.spirv; - AddOutputDumping(m.refl, p.shaders[0].name.c_str(), descSet, minIndex, numVerts, modSpirv, bufStride); + AddOutputDumping(*refl, p.shaders[0].entryPoint.c_str(), descSet, minIndex, numVerts, modSpirv, bufStride); // create vertex shader with modified code VkShaderModuleCreateInfo moduleInfo = { @@ -4449,7 +4450,7 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) // expect position at the start of the buffer, as system values are sorted first // and position is the first value - for(uint32_t i=1; m.refl.OutputSig[0].systemValue == eAttr_Position && i < numVerts; i++) + for(uint32_t i=1; refl->OutputSig[0].systemValue == eAttr_Position && i < numVerts; i++) { ////////////////////////////////////////////////////////////////////////////////// // derive near/far, assuming a standard perspective matrix @@ -4528,7 +4529,7 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) m_PostVSData[idx].vsout.idxFmt = state.ibuffer.bytewidth == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; } - m_PostVSData[idx].vsout.hasPosOut = m.refl.OutputSig[0].systemValue == eAttr_Position; + m_PostVSData[idx].vsout.hasPosOut = refl->OutputSig[0].systemValue == eAttr_Position; // delete pipeline layout m_pDriver->vkDestroyPipelineLayout(dev, pipeLayout, NULL); diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 1268d8598..5c3e8271d 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -83,11 +83,18 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk Shader &shad = shaders[s]; shad.module = id; - shad.name = pCreateInfo->pStages[i].pName; - shad.refl = new ShaderReflection(info.m_ShaderModule[id].refl); - shad.refl->DebugInfo.entryFunc = pCreateInfo->pStages[i].pName; - // VKTODOLOW set this properly - shad.refl->DebugInfo.entryFile = 0; + shad.entryPoint = pCreateInfo->pStages[i].pName; + + ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; + + if(reflData.entryPoint.empty()) + { + reflData.entryPoint = shad.entryPoint; + info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); + } + + shad.refl = &reflData.refl; + shad.mapping = &reflData.mapping; } if(pCreateInfo->pVertexInputState) @@ -207,11 +214,18 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk Shader &shad = shaders[0]; shad.module = id; - shad.name = pCreateInfo->stage.pName; - shad.refl = new ShaderReflection(info.m_ShaderModule[id].refl); - shad.refl->DebugInfo.entryFunc = pCreateInfo->stage.pName; - // VKTODOLOW set this properly - shad.refl->DebugInfo.entryFile = 0; + shad.entryPoint = pCreateInfo->stage.pName; + + ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; + + if(reflData.entryPoint.empty()) + { + reflData.entryPoint = shad.entryPoint; + info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); + } + + shad.refl = &reflData.refl; + shad.mapping = &reflData.mapping; } topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; @@ -386,6 +400,4 @@ void VulkanCreationInfo::ShaderModule::Init(VulkanResourceManager *resourceMan, RDCASSERT(pCreateInfo->codeSize % sizeof(uint32_t) == 0); ParseSPIRV((uint32_t *)pCreateInfo->pCode, pCreateInfo->codeSize/sizeof(uint32_t), spirv); } - - spirv.MakeReflection(&refl, &mapping); } diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 4384131af..fed1c1f99 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -70,9 +70,8 @@ struct VulkanCreationInfo struct Shader { Shader() : refl(NULL), mapping(NULL) {} - ~Shader() { SAFE_DELETE(refl); } ResourceId module; - string name; + string entryPoint; ShaderReflection *refl; ShaderBindpointMapping *mapping; }; @@ -293,8 +292,14 @@ struct VulkanCreationInfo void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkShaderModuleCreateInfo* pCreateInfo); SPVModule spirv; - ShaderReflection refl; - ShaderBindpointMapping mapping; + + struct Reflection + { + string entryPoint; + ShaderReflection refl; + ShaderBindpointMapping mapping; + }; + map m_Reflections; }; map m_ShaderModule; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index bf4b016ea..ae5f36ff9 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -780,11 +780,10 @@ FetchBuffer VulkanReplay::GetBuffer(ResourceId id) return ret; } -ShaderReflection *VulkanReplay::GetShader(ResourceId id) +ShaderReflection *VulkanReplay::GetShader(ResourceId shader, string entryPoint) { - // VKTODOHIGH update handling of this now that shaders no longer exist - auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(id); - + auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader); + if(shad == m_pDriver->m_CreationInfo.m_ShaderModule.end()) { RDCERR("Can't get shader details"); @@ -792,15 +791,10 @@ ShaderReflection *VulkanReplay::GetShader(ResourceId id) } // disassemble lazily on demand - if(shad->second.refl.Disassembly.count == 0) - { - if(shad->second.spirv.m_Disassembly.empty()) - shad->second.spirv.Disassemble(); + if(shad->second.m_Reflections[entryPoint].refl.Disassembly.count == 0) + shad->second.m_Reflections[entryPoint].refl.Disassembly = shad->second.spirv.Disassemble(entryPoint); - shad->second.refl.Disassembly = shad->second.spirv.m_Disassembly; - } - - return &shad->second.refl; + return &shad->second.m_Reflections[entryPoint].refl; } void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) @@ -2670,11 +2664,13 @@ void VulkanReplay::SavePipelineState() for(size_t i=0; i < ARRAY_COUNT(stages); i++) { stages[i]->Shader = rm->GetOriginalID(p.shaders[i].module); + stages[i]->entryPoint = p.shaders[i].entryPoint; stages[i]->ShaderDetails = NULL; stages[i]->customName = false; stages[i]->ShaderName = StringFormat::Fmt("Shader %llu", stages[i]->Shader); stages[i]->stage = ShaderStageType(eShaderStage_Vertex + i); - stages[i]->BindpointMapping = c.m_ShaderModule[p.shaders[i].module].mapping; + if(p.shaders[i].mapping) + stages[i]->BindpointMapping = *p.shaders[i].mapping; } // Tessellation @@ -3236,22 +3232,20 @@ void VulkanReplay::FillCBufferVariables(rdctype::array invars, v } } -void VulkanReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data) +void VulkanReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) { // Correct SPIR-V will ultimately need to set explicit layout information for each type. // For now, just assume D3D11 packing (float4 alignment on float4s, float3s, matrices, arrays and structures) - // VKTODOHIGH update handling of this now that shaders no longer exist - auto it = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader); - + if(it == m_pDriver->m_CreationInfo.m_ShaderModule.end()) { RDCERR("Can't get shader details"); return; } - ShaderReflection &refl = it->second.refl; + ShaderReflection &refl = it->second.m_Reflections[entryPoint].refl; if(cbufSlot >= (uint32_t)refl.ConstantBlocks.count) { diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 56352603a..305129ba5 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -84,7 +84,7 @@ class VulkanReplay : public IReplayDriver vector GetTextures(); FetchTexture GetTexture(ResourceId id); - ShaderReflection *GetShader(ResourceId id); + ShaderReflection *GetShader(ResourceId shader, string entryPoint); vector GetUsage(ResourceId id); @@ -143,7 +143,7 @@ class VulkanReplay : public IReplayDriver void RenderHighlightBox(float w, float h, float scale); - void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data); + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); vector PixelHistory(uint32_t frameID, vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 6b17fd9fc..8daff23eb 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -62,7 +62,7 @@ class IRemoteDriver virtual vector GetDebugMessages() = 0; - virtual ShaderReflection *GetShader(ResourceId id) = 0; + virtual ShaderReflection *GetShader(ResourceId shader, string entryPoint) = 0; virtual vector GetUsage(ResourceId id) = 0; @@ -96,7 +96,7 @@ class IRemoteDriver virtual void DescribeCounter(uint32_t counterID, CounterDescription &desc) = 0; virtual vector FetchCounters(uint32_t frameID, uint32_t minEventID, uint32_t maxEventID, const vector &counterID) = 0; - virtual void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector &outvars, const vector &data) = 0; + virtual void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) = 0; virtual vector PixelHistory(uint32_t frameID, vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) = 0; virtual ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) = 0; diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index 703775881..efe1d4e96 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -1288,7 +1288,7 @@ bool ReplayRenderer::DebugThread(uint32_t groupid[3], uint32_t threadid[3], Shad return true; } -bool ReplayRenderer::GetCBufferVariableContents(ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) +bool ReplayRenderer::GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) { if(vars == NULL) return false; @@ -1298,18 +1298,13 @@ bool ReplayRenderer::GetCBufferVariableContents(ResourceId shader, uint32_t cbuf vector v; - m_pDevice->FillCBufferVariables(m_pDevice->GetLiveID(shader), cbufslot, v, data); + m_pDevice->FillCBufferVariables(m_pDevice->GetLiveID(shader), entryPoint, cbufslot, v, data); *vars = v; return true; } -ShaderReflection *ReplayRenderer::GetShaderDetails(ResourceId shader) -{ - return m_pDevice->GetShader(m_pDevice->GetLiveID(shader)); -} - ReplayOutput *ReplayRenderer::CreateOutput(void *wndhandle, OutputType type) { ReplayOutput *out = new ReplayOutput(this, wndhandle, type); @@ -1565,21 +1560,21 @@ void ReplayRenderer::FetchPipelineState() D3D11PipelineState::ShaderStage *stage = &m_D3D11PipelineState.m_VS; for(int i=0; i < 6; i++) if(stage[i].Shader != ResourceId()) - stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader)); + stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), ""); } { GLPipelineState::ShaderStage *stage = &m_GLPipelineState.m_VS; for(int i=0; i < 6; i++) if(stage[i].Shader != ResourceId()) - stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader)); + stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), ""); } { VulkanPipelineState::ShaderStage *stage = &m_VulkanPipelineState.VS; for(int i=0; i < 6; i++) if(stage[i].Shader != ResourceId()) - stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader)); + stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), stage[i].entryPoint.elems); } } @@ -1650,8 +1645,6 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBuffers(ReplayRen { return rend->GetBuffers(bufs); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace) { return rend->GetResolve(callstack, callstackLen, trace); } -extern "C" RENDERDOC_API ShaderReflection* RENDERDOC_CC ReplayRenderer_GetShaderDetails(ReplayRenderer *rend, ResourceId shader) -{ return rend->GetShaderDetails(shader); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *msgs) { return rend->GetDebugMessages(msgs); } @@ -1667,8 +1660,8 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugThread(ReplayRe extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetUsage(ReplayRenderer *rend, ResourceId id, rdctype::array *usage) { return rend->GetUsage(id, usage); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents(ReplayRenderer *rend, ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) -{ return rend->GetCBufferVariableContents(shader, cbufslot, buffer, offs, vars); } +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents(ReplayRenderer *rend, ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) +{ return rend->GetCBufferVariableContents(shader, entryPoint, cbufslot, buffer, offs, vars); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, const TextureSave &saveData, const char *path) { return rend->SaveTexture(saveData, path); } diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index f81e93f7b..11aa0dd87 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -168,7 +168,6 @@ struct ReplayRenderer : public IReplayRenderer bool GetTextures(rdctype::array *texs); bool GetBuffers(rdctype::array *bufs); bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace); - ShaderReflection *GetShaderDetails(ResourceId shader); bool GetDebugMessages(rdctype::array *msgs); bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history); @@ -188,7 +187,7 @@ struct ReplayRenderer : public IReplayRenderer bool SaveTexture(const TextureSave &saveData, const char *path); - bool GetCBufferVariableContents(ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars); + bool GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars); ReplayOutput *CreateOutput(void *handle, OutputType type); diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index 32523cb28..d490a3b8a 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -343,6 +343,24 @@ namespace renderdocui.Code return null; } + public String GetShaderEntryPoint(ShaderStageType stage) + { + if (LogLoaded && IsLogVK) + { + switch (stage) + { + case ShaderStageType.Vertex: return m_Vulkan.VS.entryPoint; + case ShaderStageType.Tess_Control: return m_Vulkan.TCS.entryPoint; + case ShaderStageType.Tess_Eval: return m_Vulkan.TES.entryPoint; + case ShaderStageType.Geometry: return m_Vulkan.GS.entryPoint; + case ShaderStageType.Fragment: return m_Vulkan.FS.entryPoint; + case ShaderStageType.Compute: return m_Vulkan.CS.entryPoint; + } + } + + return ""; + } + public ResourceId GetShader(ShaderStageType stage) { if (LogLoaded) diff --git a/renderdocui/Interop/ReplayRenderer.cs b/renderdocui/Interop/ReplayRenderer.cs index 8afdf657d..52c48d328 100644 --- a/renderdocui/Interop/ReplayRenderer.cs +++ b/renderdocui/Interop/ReplayRenderer.cs @@ -247,8 +247,6 @@ namespace renderdoc [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_GetResolve(IntPtr real, UInt64[] callstack, UInt32 callstackLen, IntPtr outtrace); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr ReplayRenderer_GetShaderDetails(IntPtr real, ResourceId shader); - [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_GetDebugMessages(IntPtr real, IntPtr outmsgs); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] @@ -264,7 +262,7 @@ namespace renderdoc private static extern bool ReplayRenderer_GetUsage(IntPtr real, ResourceId id, IntPtr outusage); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayRenderer_GetCBufferVariableContents(IntPtr real, ResourceId shader, UInt32 cbufslot, ResourceId buffer, UInt64 offs, IntPtr outvars); + private static extern bool ReplayRenderer_GetCBufferVariableContents(IntPtr real, ResourceId shader, IntPtr entryPoint, UInt32 cbufslot, ResourceId buffer, UInt64 offs, IntPtr outvars); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_SaveTexture(IntPtr real, TextureSave saveData, IntPtr path); @@ -619,18 +617,6 @@ namespace renderdoc return ret; } - public ShaderReflection GetShaderDetails(ResourceId shader) - { - IntPtr mem = ReplayRenderer_GetShaderDetails(m_Real, shader); - - ShaderReflection ret = null; - - if (mem != IntPtr.Zero) - ret = (ShaderReflection)CustomMarshal.PtrToStructure(mem, typeof(ShaderReflection), false); - - return ret; - } - public DebugMessage[] GetDebugMessages() { IntPtr mem = CustomMarshal.Alloc(typeof(templated_array)); @@ -727,17 +713,20 @@ namespace renderdoc return ret; } - public ShaderVariable[] GetCBufferVariableContents(ResourceId shader, UInt32 cbufslot, ResourceId buffer, UInt64 offs) + public ShaderVariable[] GetCBufferVariableContents(ResourceId shader, string entryPoint, UInt32 cbufslot, ResourceId buffer, UInt64 offs) { IntPtr mem = CustomMarshal.Alloc(typeof(templated_array)); - bool success = ReplayRenderer_GetCBufferVariableContents(m_Real, shader, cbufslot, buffer, offs, mem); + IntPtr entry_mem = CustomMarshal.MakeUTF8String(entryPoint); + + bool success = ReplayRenderer_GetCBufferVariableContents(m_Real, shader, entry_mem, cbufslot, buffer, offs, mem); ShaderVariable[] ret = null; if (success) ret = (ShaderVariable[])CustomMarshal.GetTemplatedArray(mem, typeof(ShaderVariable), true); + CustomMarshal.Free(entry_mem); CustomMarshal.Free(mem); return ret; diff --git a/renderdocui/Interop/VulkanPipelineState.cs b/renderdocui/Interop/VulkanPipelineState.cs index c4f62999a..e13f349ca 100644 --- a/renderdocui/Interop/VulkanPipelineState.cs +++ b/renderdocui/Interop/VulkanPipelineState.cs @@ -169,6 +169,9 @@ namespace renderdoc } public ResourceId Shader; + [CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)] + public string entryPoint; + [CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)] public string ShaderName; public bool customName; diff --git a/renderdocui/Windows/Dialogs/ConstantBufferPreviewer.cs b/renderdocui/Windows/Dialogs/ConstantBufferPreviewer.cs index 3250f670d..9c680040c 100644 --- a/renderdocui/Windows/Dialogs/ConstantBufferPreviewer.cs +++ b/renderdocui/Windows/Dialogs/ConstantBufferPreviewer.cs @@ -52,6 +52,7 @@ namespace renderdocui.Controls Slot = slot; ArrayIdx = idx; shader = m_Core.CurPipelineState.GetShader(stage); + entryPoint = m_Core.CurPipelineState.GetShaderEntryPoint(stage); UpdateLabels(); ulong offs = 0; @@ -60,7 +61,7 @@ namespace renderdocui.Controls m_Core.Renderer.BeginInvoke((ReplayRenderer r) => { - SetVariables(r.GetCBufferVariableContents(shader, Slot, cbuffer, offs)); + SetVariables(r.GetCBufferVariableContents(shader, entryPoint, Slot, cbuffer, offs)); }); m_Core.AddLogViewer(this); @@ -184,6 +185,7 @@ namespace renderdocui.Controls m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, ArrayIdx, out cbuffer, out offs, out size); shader = m_Core.CurPipelineState.GetShader(Stage); + entryPoint = m_Core.CurPipelineState.GetShaderEntryPoint(Stage); var reflection = m_Core.CurPipelineState.GetShaderReflection(Stage); UpdateLabels(); @@ -205,7 +207,7 @@ namespace renderdocui.Controls { m_Core.Renderer.BeginInvoke((ReplayRenderer r) => { - SetVariables(r.GetCBufferVariableContents(shader, Slot, cbuffer, offs)); + SetVariables(r.GetCBufferVariableContents(shader, entryPoint, Slot, cbuffer, offs)); }); } } @@ -214,6 +216,7 @@ namespace renderdocui.Controls private ResourceId cbuffer; private ResourceId shader; + private String entryPoint; private ShaderStageType Stage; private UInt32 Slot = 0; private UInt32 ArrayIdx = 0;