From fec709b2d15559fd0aa2be63f6671eb4a28b9616 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 16 Jun 2020 11:07:13 +0100 Subject: [PATCH] Support using ILDN to locate separate debug info * This works the same way as the existing separate pdb support --- renderdoc/driver/d3d11/d3d11_resources.cpp | 44 ++++++++++++++----- renderdoc/driver/d3d12/d3d12_resources.cpp | 44 ++++++++++++++----- .../driver/shaders/dxbc/dxbc_container.cpp | 13 ++++++ 3 files changed, 79 insertions(+), 22 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 7e0ef5fbc..60cadb7d1 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -99,21 +99,43 @@ void WrappedShader::ShaderEntry::TryReplaceOriginalByteCode() rdcstr foundPath; - // while we haven't found a file, keep trying through the search paths. For i==0 - // check the path on its own, in case it's an absolute path. - for(size_t i = 0; originalShaderFile == NULL && i <= numSearchPaths; i++) + // keep searching until we've exhausted all possible path options, or we've found a file that + // opens + while(originalShaderFile == NULL && !originalPath.empty()) { - if(i == 0) + // while we haven't found a file, keep trying through the search paths. For i==0 + // check the path on its own, in case it's an absolute path. + for(size_t i = 0; originalShaderFile == NULL && i <= numSearchPaths; i++) { - originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); - foundPath = originalPath; - continue; + if(i == 0) + { + originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); + foundPath = originalPath; + continue; + } + else + { + const rdcstr &searchPath = (*m_DebugInfoSearchPaths)[i - 1]; + foundPath = searchPath + "/" + originalPath; + originalShaderFile = FileIO::fopen(foundPath.c_str(), "rb"); + } } - else + + if(originalShaderFile == NULL) { - const rdcstr &searchPath = (*m_DebugInfoSearchPaths)[i - 1]; - foundPath = searchPath + "/" + originalPath; - originalShaderFile = FileIO::fopen(foundPath.c_str(), "rb"); + // the "documented" behaviour for D3D debug info names is that when presented with a + // relative path containing subfolders like foo/bar/blah.pdb then we should first try to + // append it to all search paths as-is, then strip off the top-level subdirectory to get + // bar/blah.pdb and try that in all search directories, and keep going. So if we got here + // and didn't open a file, try to strip off the the top directory and continue. + int32_t offs = originalPath.find_first_of("\\/"); + + // if we couldn't find a directory separator there's nothing to do, stop looking + if(offs == -1) + break; + + // otherwise strip up to there and keep going + originalPath.erase(0, offs + 1); } } diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index e676d9a31..a269377ee 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -61,21 +61,43 @@ void WrappedID3D12Shader::TryReplaceOriginalByteCode() rdcstr foundPath; - // while we haven't found a file, keep trying through the search paths. For i==0 - // check the path on its own, in case it's an absolute path. - for(size_t i = 0; originalShaderFile == NULL && i <= numSearchPaths; i++) + // keep searching until we've exhausted all possible path options, or we've found a file that + // opens + while(originalShaderFile == NULL && !originalPath.empty()) { - if(i == 0) + // while we haven't found a file, keep trying through the search paths. For i==0 + // check the path on its own, in case it's an absolute path. + for(size_t i = 0; originalShaderFile == NULL && i <= numSearchPaths; i++) { - originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); - foundPath = originalPath; - continue; + if(i == 0) + { + originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); + foundPath = originalPath; + continue; + } + else + { + const rdcstr &searchPath = (*m_DebugInfoSearchPaths)[i - 1]; + foundPath = searchPath + "/" + originalPath; + originalShaderFile = FileIO::fopen(foundPath.c_str(), "rb"); + } } - else + + if(originalShaderFile == NULL) { - const rdcstr &searchPath = (*m_DebugInfoSearchPaths)[i - 1]; - foundPath = searchPath + "/" + originalPath; - originalShaderFile = FileIO::fopen(foundPath.c_str(), "rb"); + // the "documented" behaviour for D3D debug info names is that when presented with a + // relative path containing subfolders like foo/bar/blah.pdb then we should first try to + // append it to all search paths as-is, then strip off the top-level subdirectory to get + // bar/blah.pdb and try that in all search directories, and keep going. So if we got here + // and didn't open a file, try to strip off the the top directory and continue. + int32_t offs = originalPath.find_first_of("\\/"); + + // if we couldn't find a directory separator there's nothing to do, stop looking + if(offs == -1) + break; + + // otherwise strip up to there and keep going + originalPath.erase(0, offs + 1); } } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index f6ef9359c..a735cc35d 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -768,6 +768,7 @@ rdcstr DXBCContainer::GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLe uint32_t *chunkOffsets = (uint32_t *)(header + 1); // right after the header + // prefer RenderDoc's magic value which pre-dated D3D's support for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) { uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); @@ -789,6 +790,18 @@ rdcstr DXBCContainer::GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLe } } + for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) + { + uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); + if(*fourcc == FOURCC_ILDN) + { + const ILDNHeader *h = (const ILDNHeader *)(fourcc + 2); + + debugPath.append(h->Name, h->NameLength); + return debugPath; + } + } + return debugPath; }