From 2eb41f860dabfcf057e9edcba646c8c75045b55d Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 30 Aug 2024 13:28:40 +0100 Subject: [PATCH] Add DXBC container helpers for manipulating single-chunk containers --- .../driver/shaders/dxbc/dxbc_container.cpp | 61 +++++++++++++++++-- .../driver/shaders/dxbc/dxbc_container.h | 5 ++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index 32fe13c0b..5b5753139 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -124,6 +124,12 @@ struct FileHeader // uint32 chunkOffsets[numChunks]; follows }; +struct PartHeader +{ + uint32_t fourcc; + uint32_t partLength; +}; + struct ILDNHeader { uint16_t Flags; @@ -820,38 +826,44 @@ void DXBCContainer::ReplaceChunk(bytebuf &ByteCode, uint32_t fourcc, const byte HashContainer(ByteCode.data(), ByteCode.size()); } -const byte *DXBCContainer::FindChunk(const bytebuf &ByteCode, uint32_t fourcc, size_t &size) +const byte *DXBCContainer::FindChunk(const byte *ByteCode, size_t ByteCodeLength, uint32_t fourcc, + size_t &size) { - const FileHeader *header = (const FileHeader *)ByteCode.data(); + const FileHeader *header = (const FileHeader *)ByteCode; size = 0; if(header->fourcc != FOURCC_DXBC) return NULL; - if(header->fileLength != (uint32_t)ByteCode.size()) + if(header->fileLength != (uint32_t)ByteCodeLength) return NULL; const uint32_t *chunkOffsets = - (const uint32_t *)(ByteCode.data() + sizeof(FileHeader)); // right after the header + (const uint32_t *)(ByteCode + sizeof(FileHeader)); // right after the header for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) { uint32_t offs = chunkOffsets[chunkIdx]; - const uint32_t *chunkFourcc = (uint32_t *)(ByteCode.data() + offs); + const uint32_t *chunkFourcc = (uint32_t *)(ByteCode + offs); const uint32_t *chunkSize = (uint32_t *)(chunkFourcc + 1); if(*chunkFourcc == fourcc) { size = *chunkSize; - return ByteCode.data() + offs + 8; + return ByteCode + offs + 8; } } return NULL; } +const byte *DXBCContainer::FindChunk(const bytebuf &ByteCode, uint32_t fourcc, size_t &size) +{ + return FindChunk(ByteCode.data(), ByteCode.size(), fourcc, size); +} + void DXBCContainer::GetHash(uint32_t hash[4], const void *ByteCode, size_t BytecodeLength) { if(BytecodeLength < sizeof(FileHeader) || ByteCode == NULL) @@ -892,6 +904,43 @@ void DXBCContainer::GetHash(uint32_t hash[4], const void *ByteCode, size_t Bytec } } +bytebuf DXBCContainer::MakeContainerForChunk(uint32_t fourcc, const byte *chunk, uint64_t chunkSize) +{ + FileHeader dxbcHeader; + PartHeader partHeader; + + dxbcHeader.fourcc = FOURCC_DXBC; + dxbcHeader.containerVersion = 1; + dxbcHeader.fileLength = + uint32_t(sizeof(FileHeader) + sizeof(uint32_t) + sizeof(PartHeader) + chunkSize); + dxbcHeader.numChunks = 1; + + partHeader.fourcc = fourcc; + partHeader.partLength = (uint32_t)chunkSize; + + uint32_t chunkOffset = sizeof(FileHeader) + sizeof(uint32_t); + + bytebuf ret; + ret.resize(dxbcHeader.fileLength); + + byte *write = ret.data(); + + memcpy(write, &dxbcHeader, sizeof(dxbcHeader)); + write += sizeof(dxbcHeader); + + memcpy(write, &chunkOffset, sizeof(chunkOffset)); + write += sizeof(chunkOffset); + + memcpy(write, &partHeader, sizeof(partHeader)); + write += sizeof(partHeader); + + memcpy(write, chunk, chunkSize); + + HashContainer(ret.data(), ret.size()); + + return ret; +} + bool DXBCContainer::IsHashedContainer(const void *ByteCode, size_t BytecodeLength) { if(BytecodeLength < sizeof(FileHeader) || ByteCode == NULL) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.h b/renderdoc/driver/shaders/dxbc/dxbc_container.h index 21260aece..9d9ac5101 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.h @@ -221,6 +221,8 @@ public: } static const byte *FindChunk(const bytebuf &ByteCode, uint32_t fourcc, size_t &size); + static const byte *FindChunk(const byte *ByteCode, size_t ByteCodeLength, uint32_t fourcc, + size_t &size); const DXBCBytecode::Program *GetDXBCByteCode() const { return m_DXBCByteCode; } DXBCBytecode::Program *GetDXBCByteCode() { return m_DXBCByteCode; } @@ -233,6 +235,9 @@ public: return m_ShaderBlob.data() + m_NonDebugDXILByteCodeOffset; } size_t GetNonDebugDXILByteCodeSize() const { return m_NonDebugDXILByteCodeSize; } + + static bytebuf MakeContainerForChunk(uint32_t fourcc, const byte *chunk, uint64_t chunkSize); + static bool IsHashedContainer(const void *ByteCode, size_t BytecodeLength); static bool HashContainer(void *ByteCode, size_t BytecodeLength);