diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index dfd62f810..40b502cfd 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -382,13 +382,13 @@ rdcstr TypeName(CBufferVariableType::Descriptor desc) return ret; } -CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkContents, +CBufferVariableType DXBCContainer::ParseRDEFType(const RDEFHeader *h, const byte *chunkContents, uint32_t typeOffset) { if(m_Variables.find(typeOffset) != m_Variables.end()) return m_Variables[typeOffset]; - RDEFCBufferType *type = (RDEFCBufferType *)(chunkContents + typeOffset); + const RDEFCBufferType *type = (const RDEFCBufferType *)(chunkContents + typeOffset); CBufferVariableType ret; @@ -405,7 +405,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte { if(h->targetVersion >= 0x500 && type->nameOffset > 0) { - ret.descriptor.name += " " + rdcstr(chunkContents + type->nameOffset); + ret.descriptor.name += " " + rdcstr((const char *)chunkContents + type->nameOffset); } else { @@ -418,7 +418,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte { if(h->targetVersion >= 0x500 && type->nameOffset > 0) { - ret.descriptor.name = chunkContents + type->nameOffset; + ret.descriptor.name = (const char *)chunkContents + type->nameOffset; } else { @@ -428,7 +428,8 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte if(type->memberOffset) { - RDEFCBufferChildType *members = (RDEFCBufferChildType *)(chunkContents + type->memberOffset); + const RDEFCBufferChildType *members = + (const RDEFCBufferChildType *)(chunkContents + type->memberOffset); ret.members.reserve(type->numMembers); @@ -438,7 +439,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte { CBufferVariable v; - v.name = chunkContents + members[j].nameOffset; + v.name = (const char *)(chunkContents + members[j].nameOffset); v.type = ParseRDEFType(h, chunkContents, members[j].typeOffset); v.descriptor.offset = members[j].memberOffset; @@ -738,14 +739,14 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength) for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) { - uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); - uint32_t *chunkSize = (uint32_t *)(fourcc + 1); + const uint32_t *fourcc = (const uint32_t *)(data + chunkOffsets[chunkIdx]); + const uint32_t *chunkSize = (const uint32_t *)(fourcc + 1); - char *chunkContents = (char *)(chunkSize + 1); + const byte *chunkContents = (const byte *)(chunkSize + 1); if(*fourcc == FOURCC_RDEF) { - RDEFHeader *h = (RDEFHeader *)chunkContents; + const RDEFHeader *h = (const RDEFHeader *)chunkContents; // for target version 0x500, unknown[0] is FOURCC_RD11. // for 0x501 it's "\x13\x13\D%" @@ -793,7 +794,7 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength) ShaderInputBind desc; - desc.name = chunkContents + res->nameOffset; + desc.name = (const char *)(chunkContents + res->nameOffset); desc.type = (ShaderInputBind::InputType)res->type; desc.space = h->targetVersion >= 0x501 ? res->space : 0; desc.reg = res->bindPoint; @@ -907,9 +908,9 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength) if(cbuf->nameOffset == 0) continue; - cb.name = chunkContents + cbuf->nameOffset; + cb.name = (const char *)(chunkContents + cbuf->nameOffset); - cb.descriptor.name = chunkContents + cbuf->nameOffset; + cb.descriptor.name = (const char *)(chunkContents + cbuf->nameOffset); cb.descriptor.byteSize = cbuf->size; cb.descriptor.type = (CBuffer::Descriptor::Type)cbuf->type; cb.descriptor.flags = cbuf->flags; @@ -949,7 +950,7 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength) CBufferVariable v; - v.name = chunkContents + var->nameOffset; + v.name = (const char *)(chunkContents + var->nameOffset); v.descriptor.defaultValue.resize(var->size); @@ -1007,7 +1008,15 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength) } else if(*fourcc == FOURCC_STAT) { - if(*chunkSize == STATSizeDX10) + if(DXIL::Program::Valid(chunkContents, *chunkSize)) + { + RDCEraseEl(m_ShaderStats); + m_ShaderStats.version = ShaderStatistics::STATS_DX12; + /* + DXIL::Program prog(chunkContents, *chunkSize); + */ + } + else if(*chunkSize == STATSizeDX10) { memcpy(&m_ShaderStats, chunkContents, STATSizeDX10); m_ShaderStats.version = ShaderStatistics::STATS_DX10; @@ -1024,20 +1033,35 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength) } else if(*fourcc == FOURCC_SHEX || *fourcc == FOURCC_SHDR) { - m_DXBCByteCode = new DXBCBytecode::Program((const byte *)chunkContents, *chunkSize); + m_DXBCByteCode = new DXBCBytecode::Program(chunkContents, *chunkSize); + } + else if(*fourcc == FOURCC_ILDB || *fourcc == FOURCC_DXIL) + { + // we avoiding parsing these immediately because you can get both in a dxbc, so we prefer the + // debug version. } else if(*fourcc == FOURCC_ILDN) { - ILDNHeader *h = (ILDNHeader *)chunkContents; + const ILDNHeader *h = (const ILDNHeader *)chunkContents; m_DebugFileName = rdcstr(h->Name, h->NameLength); } else if(*fourcc == FOURCC_HASH) { - HASHHeader *h = (HASHHeader *)chunkContents; + const HASHHeader *h = (const HASHHeader *)chunkContents; memcpy(m_Hash, h->hashValue, sizeof(h->hashValue)); } + else if(*fourcc == FOURCC_ISGN || *fourcc == FOURCC_OSGN || *fourcc == FOURCC_ISG1 || + *fourcc == FOURCC_OSG1 || *fourcc == FOURCC_OSG5 || *fourcc == FOURCC_PCSG) + { + // processed later + } + else + { + RDCWARN("Unknown chunk %c%c%c%c", ((const char *)fourcc)[0], ((const char *)fourcc)[1], + ((const char *)fourcc)[2], ((const char *)fourcc)[3]); + } } if(m_DXBCByteCode == NULL) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.h b/renderdoc/driver/shaders/dxbc/dxbc_container.h index f3f1e7668..fb0f6cf14 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.h @@ -104,6 +104,7 @@ struct ShaderStatistics STATS_UNKNOWN = 0, STATS_DX10, STATS_DX11, + STATS_DX12, } version; }; @@ -176,7 +177,7 @@ private: D3D_PRIMITIVE_TOPOLOGY m_OutputTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; - CBufferVariableType ParseRDEFType(RDEFHeader *h, char *chunk, uint32_t offset); + CBufferVariableType ParseRDEFType(const RDEFHeader *h, const byte *chunk, uint32_t offset); std::map m_Variables; uint32_t m_Hash[4]; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index e9cceefce..7b91cc937 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -569,6 +569,25 @@ static void dumpBlock(const LLVMBC::BlockOrRecord &block, int indent) RDCLOG("%s", line.c_str()); } +bool Program::Valid(const byte *bytes, size_t length) +{ + if(length < sizeof(ProgramHeader)) + return false; + + const byte *ptr = bytes; + const ProgramHeader *header = (const ProgramHeader *)ptr; + if(header->DxilMagic != MAKE_FOURCC('D', 'X', 'I', 'L')) + return false; + + size_t expected = offsetof(ProgramHeader, DxilMagic) + header->BitcodeOffset + header->BitcodeSize; + + if(expected != length) + return false; + + return LLVMBC::BitcodeReader::Valid( + ptr + offsetof(ProgramHeader, DxilMagic) + header->BitcodeOffset, header->BitcodeSize); +} + Program::Program(const byte *bytes, size_t length) { const byte *ptr = bytes; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index f5493da8d..8b0f0167f 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -183,6 +183,8 @@ public: Program(const Program &o) = default; Program &operator=(const Program &o) = default; + static bool Valid(const byte *bytes, size_t length); + void FetchComputeProperties(DXBC::Reflection *reflection); DXBC::Reflection *GetReflection(); diff --git a/renderdoc/driver/shaders/dxil/llvm_decoder.cpp b/renderdoc/driver/shaders/dxil/llvm_decoder.cpp index 3a598b529..9fdb56e7c 100644 --- a/renderdoc/driver/shaders/dxil/llvm_decoder.cpp +++ b/renderdoc/driver/shaders/dxil/llvm_decoder.cpp @@ -82,11 +82,18 @@ enum class BlockInfoRecord SETRECORDNAME = 3, }; +static const uint32_t BitcodeMagic = MAKE_FOURCC('B', 'C', 0xC0, 0xDE); + +bool BitcodeReader::Valid(const byte *bitcode, size_t length) +{ + return length >= 4 && memcmp(bitcode, &BitcodeMagic, sizeof(uint32_t)) == 0; +} + BitcodeReader::BitcodeReader(const byte *bitcode, size_t length) : b(bitcode, length) { uint32_t magic = b.Read(); - RDCASSERT(magic == MAKE_FOURCC('B', 'C', 0xC0, 0xDE)); + RDCASSERT(magic == BitcodeMagic); } BitcodeReader::~BitcodeReader() diff --git a/renderdoc/driver/shaders/dxil/llvm_decoder.h b/renderdoc/driver/shaders/dxil/llvm_decoder.h index 7e9031fc8..074526db8 100644 --- a/renderdoc/driver/shaders/dxil/llvm_decoder.h +++ b/renderdoc/driver/shaders/dxil/llvm_decoder.h @@ -64,6 +64,8 @@ public: BlockOrRecord ReadToplevelBlock(); bool AtEndOfStream(); + static bool Valid(const byte *bitcode, size_t length); + private: BitReader b;