diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index bb73ed173..434c1093e 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -122,12 +122,12 @@ struct DebugFile bool empty() { return path.empty(); } - void ReadAndProcess(bool lz4, const rdcfixedarray &desiredHash) + void ReadAndProcess(bool lz4, const rdcfixedarray &desiredHash, rdcstr &log) { FileIO::ReadAll(path, contents); - Process(lz4, desiredHash); + Process(lz4, desiredHash, log); } - void Process(bool lz4, const rdcfixedarray &desiredHash) + void Process(bool lz4, const rdcfixedarray &desiredHash, rdcstr &log) { if(lz4) { @@ -151,6 +151,7 @@ struct DebugFile if(ret < 0) { RDCERR("Failed to decompress LZ4 data from %s", path.c_str()); + log += StringFormat::Fmt("\nFailed to decompress LZ4 data from '%s'\n", path.c_str()); return; } } @@ -183,6 +184,11 @@ struct DebugFile if(debugDataHash != desiredHash) { RDCWARN("Debug info file at %s does not match hash from shader, ignoring", path.c_str()); + log += StringFormat::Fmt( + "Ignoring debug info file '%s' hash 0x08%X08%X08%X08%X does not match shader hash " + "0x08%X08%X08%X08%X", + path.c_str(), debugDataHash[0], debugDataHash[1], debugDataHash[2], debugDataHash[3], + desiredHash[0], desiredHash[1], desiredHash[2], desiredHash[3]); // invalidate ourselves path.clear(); @@ -1482,6 +1488,7 @@ rdcstr DXBCContainer::GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLe void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &debugInfoPath) { + rdcstr loadingLog; if(!CheckForDebugInfo((const void *)&byteCode[0], byteCode.size())) { rdcstr originalPath = debugInfoPath; @@ -1499,6 +1506,8 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d for(uint32_t i = 0; i < desiredHash.byteSize(); i++) originalPath += StringFormat::Fmt("%02x", h[i]); originalPath += ".pdb"; + loadingLog += StringFormat::Fmt("No shader PDB filename specified using default '%s'\n\n", + originalPath.c_str()); RDCDEBUG("No shader pdb filename specified - assuming default '%s'", originalPath.c_str()); } @@ -1518,6 +1527,33 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d size_t numSearchPaths = searchPaths.size(); + const rdcarray nonRecursiveSearchPaths = Replay_Shader_LimitedSearchDirPaths(); + loadingLog += StringFormat::Fmt("Shader filepath '%s'\n", originalPath.c_str()); + if(searchPaths.size() > nonRecursiveSearchPaths.size()) + { + loadingLog += rdcstr("\nRecursive Search Path(s):\n"); + for(const rdcstr &path : searchPaths) + { + if(nonRecursiveSearchPaths.contains(path)) + continue; + loadingLog += StringFormat::Fmt("'%s'\n", path.c_str()); + } + } + else + { + loadingLog += rdcstr("\nNo Recursive Search Paths\n"); + } + if(!nonRecursiveSearchPaths.empty()) + { + loadingLog += rdcstr("\nNon-Recursive Search Path(s):\n"); + for(const rdcstr &path : nonRecursiveSearchPaths) + loadingLog += StringFormat::Fmt("'%s'\n", path.c_str()); + } + else + { + loadingLog += rdcstr("\nNo Non-Recursive Search Paths\n"); + } + DebugFile found; rdcstr nickname = originalPath; @@ -1537,6 +1573,7 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d { if(i == 0) { + loadingLog += rdcstr("\n"); if(FileIO::exists(tempPath)) found.path = tempPath; else if(!hasSuffix && FileIO::exists(tempPath + ".pdb")) @@ -1548,7 +1585,16 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d tempPath.c_str(), originalPath.c_str()); // this may empty out found, if the hash doesn't match - found.ReadAndProcess(lz4, desiredHash); + found.ReadAndProcess(lz4, desiredHash, loadingLog); + loadingLog += StringFormat::Fmt("File found using filepath '%s'\n", found.path.c_str()); + } + else + { + loadingLog += + StringFormat::Fmt("File not found using filepath '%s'\n", tempPath.c_str()); + if(!hasSuffix) + loadingLog += + StringFormat::Fmt("File not found using filepath '%s.pdb'\n", tempPath.c_str()); } } else @@ -1568,7 +1614,18 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d tempPath.c_str(), originalPath.c_str()); // this may empty out found, if the hash doesn't match - found.ReadAndProcess(lz4, desiredHash); + found.ReadAndProcess(lz4, desiredHash, loadingLog); + loadingLog += StringFormat::Fmt( + "File found in search directory using filepath '%s'\n", found.path.c_str()); + } + else + { + loadingLog += StringFormat::Fmt( + "File not found in search directory using filepath '%s'\n", checkPath.c_str()); + if(!hasSuffix) + loadingLog += StringFormat::Fmt( + "File not found in search directory using filepath '%s.pdb'\n", + checkPath.c_str()); } } } @@ -1599,6 +1656,7 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d // on each replay. if(found.empty() && !originalPath.contains('/') && !originalPath.contains('\\')) { + loadingLog += rdcstr("\n"); CacheSearchDirDebugPaths(); auto it = cachedDebugFilesLookup.find(originalPath); @@ -1609,8 +1667,27 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d found.path = it->second; RDCDEBUG("Found %s recursively as %s", originalPath.c_str(), found.path.c_str()); - found.ReadAndProcess(lz4, desiredHash); + found.ReadAndProcess(lz4, desiredHash, loadingLog); + loadingLog += StringFormat::Fmt( + "File found in recursive directory search using filepath '%s'\n", found.path.c_str()); } + else + { + loadingLog += StringFormat::Fmt( + "File not found in recursive directory search using filepath '%s'\n", + originalPath.c_str()); + if(!hasSuffix) + loadingLog += StringFormat::Fmt( + "File not found in recursive directory search using filepath '%s.pdb'\n", + originalPath.c_str()); + } + } + else if(found.empty()) + { + loadingLog += StringFormat::Fmt( + "\nNot performing a recursive directory search because filepath contains directory " + "information '%s'\n", + originalPath.c_str()); } // Try to retrieve debug file from the externally referenced files in the capture @@ -1618,14 +1695,31 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d { if(RenderDoc::Inst().GetTrackedFileData(nickname, found.contents)) { + loadingLog += StringFormat::Fmt( + "\nFound debug data from files embedded in the capture using nickname '%s'\n", + nickname.c_str()); found.path = nickname; - found.Process(lz4, desiredHash); + found.Process(lz4, desiredHash, loadingLog); + } + else + { + loadingLog += StringFormat::Fmt( + "\nFile not found in files embedded in the capture using nickname '%s'\n", + nickname.c_str()); } } if(found.empty()) { RDCDEBUG("Couldn't find pdb for %s", originalPath.c_str()); + m_DebugInfoLoadingLog = + StringFormat::Fmt("Did not find debug data for '%s'\n\n", originalPath.c_str()); + if(!loadingLog.empty()) + { + m_DebugInfoLoadingLog += StringFormat::Fmt("Details\n"); + m_DebugInfoLoadingLog += StringFormat::Fmt("-------\n\n"); + m_DebugInfoLoadingLog += loadingLog; + } return; } @@ -1639,8 +1733,21 @@ void DXBCContainer::TryFetchSeparateDebugInfo(bytebuf &byteCode, const rdcstr &d { byteCode.swap(found.contents); } + m_DebugInfoLoadingLog = + StringFormat::Fmt("Found debug data using filepath '%s'\n\n", found.path.c_str()); } } + else + { + m_DebugInfoLoadingLog = + StringFormat::Fmt("Found debug data in the shader '%s'\n\n", debugInfoPath.c_str()); + } + if(!loadingLog.empty()) + { + m_DebugInfoLoadingLog += StringFormat::Fmt("Details\n"); + m_DebugInfoLoadingLog += StringFormat::Fmt("-------\n\n"); + m_DebugInfoLoadingLog += loadingLog; + } } DXBCContainer::DXBCContainer(const bytebuf &ByteCode, const rdcstr &debugInfoPath, GraphicsAPI api, diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.h b/renderdoc/driver/shaders/dxbc/dxbc_container.h index cfec5641f..22c9a31bb 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.h @@ -209,6 +209,7 @@ public: void CacheOutputTopology(); D3D_PRIMITIVE_TOPOLOGY GetOutputTopology() const { return m_OutputTopology; } ThreadScope GetThreadScope() const { return m_Threadscope; } + const rdcstr &GetDebugInfoLoadingLog() const { return m_DebugInfoLoadingLog; } CBufferVariableType GetRayPayload(const ShaderEntryPoint &entry) { @@ -285,6 +286,7 @@ private: bytebuf m_ShaderBlob; rdcstr m_Disassembly; + rdcstr m_DebugInfoLoadingLog; bool m_DXCStyle = false; D3D_PRIMITIVE_TOPOLOGY m_OutputTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp index b6eba449e..df5c6d918 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp @@ -320,6 +320,7 @@ void MakeShaderReflection(DXBC::DXBCContainer *dxbc, const ShaderEntryPoint &ent } refl->debugInfo.entrySourceName = refl->entryPoint = "main"; + refl->debugInfo.debugInfoLoadingLog = dxbc->GetDebugInfoLoadingLog(); if(dxbc->GetDebugInfo()) {