From 4c003525b36c3f8bbe119222ce7fdcfb2313959d Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 30 Sep 2024 11:07:53 +0100 Subject: [PATCH] Add support for PSV data version 3 * This has a very disappointingly considered string in the header struct which comes *before* the string table. --- .../driver/shaders/dxil/dxil_metadata.cpp | 29 ++++++++++++++++--- renderdoc/driver/shaders/dxil/dxil_metadata.h | 12 ++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_metadata.cpp b/renderdoc/driver/shaders/dxil/dxil_metadata.cpp index 3e2206ed6..287284c95 100644 --- a/renderdoc/driver/shaders/dxil/dxil_metadata.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_metadata.cpp @@ -407,11 +407,16 @@ bool DXBCContainer::GetPipelineValidation(DXIL::PSVData &psv) const memcpy(&psv, header, headerSize); psv.version = PSVData::Version::Version2; } - else if(headerSize > sizeof(DXIL::PSVData2)) + else if(headerSize == DXIL::PSVData3::ExpectedSize) { - RDCWARN("Unexpected PSV header size %u, only reading ver2", headerSize); memcpy(&psv, header, sizeof(DXIL::PSVData2)); - psv.version = PSVData::Version::Version2; + psv.version = PSVData::Version::Version3; + } + else if(headerSize > DXIL::PSVData3::ExpectedSize) + { + RDCWARN("Unexpected PSV header size %u, only reading ver3", headerSize); + memcpy(&psv, header, sizeof(DXIL::PSVData2)); + psv.version = PSVData::Version::Version3; } else { @@ -608,6 +613,14 @@ bool DXBCContainer::GetPipelineValidation(DXIL::PSVData &psv) const bitmask[i].ReadTable(in, psv.outputSigVectors[0]); } } + + if(psv.version >= PSVData::Version::Version3) + { + // annoyingly the entry name sits at the end of the header but BEFORE the string buffer... + IndexReference *name = (IndexReference *)((byte *)header + sizeof(DXIL::PSVData2)); + + psv.entryName = stringbuf.GetString(*name); + } } RDCASSERT(in == end); @@ -628,6 +641,7 @@ void DXBCContainer::SetPipelineValidation(bytebuf &ByteCode, const DXIL::PSVData case PSVData::Version::Version0: headerSize = sizeof(PSVData::PSVData0); break; case PSVData::Version::Version1: headerSize = sizeof(PSVData::PSVData1); break; case PSVData::Version::Version2: headerSize = sizeof(PSVData::PSVData2); break; + case PSVData::Version::Version3: headerSize = PSVData::PSVData3::ExpectedSize; break; } // PSV does not deduplicate @@ -638,7 +652,11 @@ void DXBCContainer::SetPipelineValidation(bytebuf &ByteCode, const DXIL::PSVData // write header writer.Write(headerSize); - writer.Write(&psv, headerSize); + writer.Write(&psv, RDCMIN((uint32_t)sizeof(PSVData::PSVData2), headerSize)); + uint64_t entryNameOffset = writer.GetOffset(); + + if(psv.version >= PSVData::Version::Version3) + writer.Write(0); // write resources const uint32_t resourceCount = psv.resources.count(); @@ -681,6 +699,9 @@ void DXBCContainer::SetPipelineValidation(bytebuf &ByteCode, const DXIL::PSVData idxArrays.MakeRef(psv.patchConstPrimSig[i].semIndices, false); } + if(psv.version >= PSVData::Version::Version3) + writer.WriteAt(entryNameOffset, stringbuf.MakeRef(psv.entryName)); + const uint32_t stringBufSize = AlignUp4(stringbuf.GetBlob().count()); writer.Write(stringBufSize); writer.Write(stringbuf.GetBlob().data(), stringbuf.GetBlob().size()); diff --git a/renderdoc/driver/shaders/dxil/dxil_metadata.h b/renderdoc/driver/shaders/dxil/dxil_metadata.h index 6b0c5f5d3..198edc974 100644 --- a/renderdoc/driver/shaders/dxil/dxil_metadata.h +++ b/renderdoc/driver/shaders/dxil/dxil_metadata.h @@ -152,6 +152,13 @@ struct PSVData2 : public PSVData1 static const size_t ExpectedSize = sizeof(PSVData1) + 3 * sizeof(uint32_t); }; +struct PSVData3 : public PSVData2 +{ + rdcstr entryName; + + static const size_t ExpectedSize = sizeof(PSVData2) + sizeof(uint32_t); +}; + struct PSVResource0 { DXILResourceType type; @@ -200,14 +207,15 @@ struct PSVSignature0 using PSVSignature = PSVSignature0; -struct PSVData : public PSVData2 +struct PSVData : public PSVData3 { enum class Version { Version0 = 0, Version1, Version2, - VersionLatest = Version2, + Version3, + VersionLatest = Version3, } version = Version::VersionLatest; enum class ResourceVersion