diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp index 5b1702b70..cdf5d222d 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp @@ -1062,13 +1062,23 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength) char *c = (char *)fourcc; RDCWARN("Unknown chunk: %c%c%c%c", c[0], c[1], c[2], c[3]); } - else if(*fourcc == FOURCC_SDBG) + } + + // initialise debug chunks last + for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) + { + uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); + + if(*fourcc == FOURCC_SDBG) { m_DebugInfo = new SDBGChunk(fourcc); } else if(*fourcc == FOURCC_SPDB) { - m_DebugInfo = new SPDBChunk(fourcc); + m_DebugInfo = new SPDBChunk(this, fourcc); + } + } + // we do a mini-preprocess of the files from the debug info to handle #line directives. // This means that any lines that our source file declares to be in another filename via a #line // get put in the right place for what the debug information hopefully matches. diff --git a/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp b/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp index de1b4f7b5..4010347ab 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp @@ -42,7 +42,7 @@ namespace DXBC { static const uint32_t FOURCC_SPDB = MAKE_FOURCC('S', 'P', 'D', 'B'); -SPDBChunk::SPDBChunk(void *chunk) +SPDBChunk::SPDBChunk(DXBCFile *dxbc, void *chunk) { m_HasDebugInfo = false; @@ -1079,24 +1079,32 @@ SPDBChunk::SPDBChunk(void *chunk) bool indexable = false; const char *regtype = ""; const char *regprefix = "?"; - switch((CV_HLSLREG_e)defrange->regType) + + // CV_HLSLREG_e == OperandType + + switch((OperandType)defrange->regType) { - case CV_HLSLREG_TEMP: + case TYPE_TEMP: mapping.var.registerType = RegisterType::Temporary; regtype = "temp"; regprefix = "r"; break; - case CV_HLSLREG_INPUT: + case TYPE_INPUT: mapping.var.registerType = RegisterType::Input; regtype = "input"; regprefix = "v"; break; - case CV_HLSLREG_OUTPUT: + case TYPE_OUTPUT: + case TYPE_OUTPUT_DEPTH: + case TYPE_OUTPUT_DEPTH_LESS_EQUAL: + case TYPE_OUTPUT_DEPTH_GREATER_EQUAL: + case TYPE_OUTPUT_STENCIL_REF: + case TYPE_OUTPUT_COVERAGE_MASK: mapping.var.registerType = RegisterType::Output; regtype = "output"; regprefix = "o"; break; - case CV_HLSLREG_INDEXABLE_TEMP: + case TYPE_INDEXABLE_TEMP: mapping.var.registerType = RegisterType::IndexedTemporary; regtype = "indexable"; regprefix = "x"; @@ -1127,6 +1135,43 @@ SPDBChunk::SPDBChunk(void *chunk) uint32_t regfirstcomp = indexable ? 0 : (regoffset % 16) / 4; uint32_t regnumcomps = indexable ? 4 : defrange->sizeInParent / 4; + ShaderBuiltin builtin = ShaderBuiltin::Undefined; + switch((OperandType)defrange->regType) + { + case TYPE_OUTPUT_DEPTH: builtin = ShaderBuiltin::DepthOutput; break; + case TYPE_OUTPUT_DEPTH_LESS_EQUAL: builtin = ShaderBuiltin::DepthOutputLessEqual; break; + case TYPE_OUTPUT_DEPTH_GREATER_EQUAL: + builtin = ShaderBuiltin::DepthOutputGreaterEqual; + break; + case TYPE_OUTPUT_STENCIL_REF: builtin = ShaderBuiltin::StencilReference; break; + case TYPE_OUTPUT_COVERAGE_MASK: builtin = ShaderBuiltin::MSAACoverage; break; + default: break; + } + + if(builtin != ShaderBuiltin::Undefined) + { + bool found = false; + + for(size_t i = 0; i < dxbc->m_OutputSig.size(); i++) + { + if(dxbc->m_OutputSig[i].systemValue == builtin) + { + regindex = (uint32_t)i; + regfirstcomp = 0; + found = true; + break; + } + } + + if(!found) + { + RDCERR( + "Found variable mapping for %d but no matching register declared in out signature", + defrange->regType); + regindex = ~0U; + } + } + char *regswizzle = regcomps; regswizzle += regfirstcomp; regswizzle[regnumcomps] = 0; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_spdb.h b/renderdoc/driver/shaders/dxbc/dxbc_spdb.h index 693bac88d..19958dcf0 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_spdb.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_spdb.h @@ -261,7 +261,9 @@ struct LocalMapping class SPDBChunk : public DXBCDebugChunk { public: - SPDBChunk(void *data); + SPDBChunk(DXBCFile *dxbc, void *data); + SPDBChunk(const SPDBChunk &) = delete; + SPDBChunk &operator=(const SPDBChunk &o) = delete; std::string GetCompilerSig() const { return m_CompilerSig; } std::string GetEntryFunction() const { return m_Entry; } @@ -273,9 +275,6 @@ public: void GetLocals(size_t instruction, uintptr_t offset, rdcarray &locals) const; private: - SPDBChunk(const SPDBChunk &); - SPDBChunk &operator=(const SPDBChunk &o); - bool m_HasDebugInfo; std::string m_CompilerSig;