[llvm] 76985fd - [DXIL] Adding support to RootSignatureFlags in obj2yaml (#122396)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 7 14:19:24 PST 2025
Author: joaosaffran
Date: 2025-02-07T14:19:19-08:00
New Revision: 76985fd7cafddec5254c15caeeeabc80e5a8c2f9
URL: https://github.com/llvm/llvm-project/commit/76985fd7cafddec5254c15caeeeabc80e5a8c2f9
DIFF: https://github.com/llvm/llvm-project/commit/76985fd7cafddec5254c15caeeeabc80e5a8c2f9.diff
LOG: [DXIL] Adding support to RootSignatureFlags in obj2yaml (#122396)
This PR adds:
- `RootSignatureFlags` extraction from DXContainer using `obj2yaml`
This PR is part of: #121493
---------
Co-authored-by: joaosaffran <joao.saffran at microsoft.com>
Added:
llvm/include/llvm/MC/DXContainerRootSignature.h
llvm/lib/MC/DXContainerRootSignature.cpp
llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml
Modified:
llvm/include/llvm/BinaryFormat/DXContainer.h
llvm/include/llvm/BinaryFormat/DXContainerConstants.def
llvm/include/llvm/Object/DXContainer.h
llvm/include/llvm/ObjectYAML/DXContainerYAML.h
llvm/lib/MC/CMakeLists.txt
llvm/lib/Object/DXContainer.cpp
llvm/lib/ObjectYAML/DXContainerEmitter.cpp
llvm/lib/ObjectYAML/DXContainerYAML.cpp
llvm/tools/obj2yaml/dxcontainer2yaml.cpp
llvm/unittests/Object/DXContainerTest.cpp
llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 21e28d546286eea..fbab066bf45176e 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -14,6 +14,8 @@
#define LLVM_BINARYFORMAT_DXCONTAINER_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/BinaryStreamError.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/TargetParser/Triple.h"
@@ -152,6 +154,11 @@ enum class FeatureFlags : uint64_t {
static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63,
"Shader flag bits exceed enum size.");
+#define ROOT_ELEMENT_FLAG(Num, Val) Val = 1ull << Num,
+enum class RootElementFlag : uint32_t {
+#include "DXContainerConstants.def"
+};
+
PartType parsePartType(StringRef S);
struct VertexPSVInfo {
@@ -541,6 +548,23 @@ struct ProgramSignatureElement {
static_assert(sizeof(ProgramSignatureElement) == 32,
"ProgramSignatureElement is misaligned");
+struct RootSignatureValidations {
+
+ static Expected<uint32_t> validateRootFlag(uint32_t Flags) {
+ if ((Flags & ~0x80000fff) != 0)
+ return llvm::make_error<BinaryStreamError>("Invalid Root Signature flag");
+ return Flags;
+ }
+
+ static Expected<uint32_t> validateVersion(uint32_t Version) {
+ if (Version == 1 || Version == 2)
+ return Version;
+
+ return llvm::make_error<BinaryStreamError>(
+ "Invalid Root Signature Version");
+ }
+};
+
} // namespace dxbc
} // namespace llvm
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 96d4499c9cadc98..6d44ea14df444ba 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -4,6 +4,7 @@ CONTAINER_PART(DXIL)
CONTAINER_PART(SFI0)
CONTAINER_PART(HASH)
CONTAINER_PART(PSV0)
+CONTAINER_PART(RTS0)
CONTAINER_PART(ISG1)
CONTAINER_PART(OSG1)
CONTAINER_PART(PSG1)
@@ -52,6 +53,26 @@ SHADER_FEATURE_FLAG(31, 36, NextUnusedBit, "Next reserved shader flag bit (not a
#undef SHADER_FEATURE_FLAG
#endif // SHADER_FEATURE_FLAG
+
+// ROOT_ELEMENT_FLAG(bit offset for the flag, name).
+#ifdef ROOT_ELEMENT_FLAG
+
+ROOT_ELEMENT_FLAG(0, AllowInputAssemblerInputLayout)
+ROOT_ELEMENT_FLAG(1, DenyVertexShaderRootAccess)
+ROOT_ELEMENT_FLAG(2, DenyHullShaderRootAccess)
+ROOT_ELEMENT_FLAG(3, DenyDomainShaderRootAccess)
+ROOT_ELEMENT_FLAG(4, DenyGeometryShaderRootAccess)
+ROOT_ELEMENT_FLAG(5, DenyPixelShaderRootAccess)
+ROOT_ELEMENT_FLAG(6, AllowStreamOutput)
+ROOT_ELEMENT_FLAG(7, LocalRootSignature)
+ROOT_ELEMENT_FLAG(8, DenyAmplificationShaderRootAccess)
+ROOT_ELEMENT_FLAG(9, DenyMeshShaderRootAccess)
+ROOT_ELEMENT_FLAG(10, CBVSRVUAVHeapDirectlyIndexed)
+ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
+#undef ROOT_ELEMENT_FLAG
+#endif // ROOT_ELEMENT_FLAG
+
+
#ifdef DXIL_MODULE_FLAG
// Only save DXIL module flags which not map to feature flags here.
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
new file mode 100644
index 000000000000000..e1a9be5fc52d8b7
--- /dev/null
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -0,0 +1,28 @@
+//===- llvm/MC/DXContainerRootSignature.h - RootSignature -*- C++ -*- ========//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdint>
+#include <limits>
+
+namespace llvm {
+
+class raw_ostream;
+
+namespace mcdxbc {
+struct RootSignatureHeader {
+ uint32_t Version = 2;
+ uint32_t NumParameters = 0;
+ uint32_t RootParametersOffset = 0;
+ uint32_t NumStaticSamplers = 0;
+ uint32_t StaticSamplersOffset = 0;
+ uint32_t Flags = 0;
+
+ void write(raw_ostream &OS);
+};
+} // namespace mcdxbc
+} // namespace llvm
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 19c83ba6c6e85df..c3a2f756bd683fd 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -116,6 +116,28 @@ template <typename T> struct ViewArray {
};
namespace DirectX {
+
+class RootSignature {
+private:
+ uint32_t Version;
+ uint32_t NumParameters;
+ uint32_t RootParametersOffset;
+ uint32_t NumStaticSamplers;
+ uint32_t StaticSamplersOffset;
+ uint32_t Flags;
+
+public:
+ RootSignature() {}
+
+ Error parse(StringRef Data);
+ uint32_t getVersion() const { return Version; }
+ uint32_t getNumParameters() const { return NumParameters; }
+ uint32_t getRootParametersOffset() const { return RootParametersOffset; }
+ uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
+ uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
+ uint32_t getFlags() const { return Flags; }
+};
+
class PSVRuntimeInfo {
using ResourceArray = ViewArray<dxbc::PSV::v2::ResourceBindInfo>;
@@ -287,6 +309,7 @@ class DXContainer {
std::optional<uint64_t> ShaderFeatureFlags;
std::optional<dxbc::ShaderHash> Hash;
std::optional<DirectX::PSVRuntimeInfo> PSVInfo;
+ std::optional<DirectX::RootSignature> RootSignature;
DirectX::Signature InputSignature;
DirectX::Signature OutputSignature;
DirectX::Signature PatchConstantSignature;
@@ -296,6 +319,7 @@ class DXContainer {
Error parseDXILHeader(StringRef Part);
Error parseShaderFeatureFlags(StringRef Part);
Error parseHash(StringRef Part);
+ Error parseRootSignature(StringRef Part);
Error parsePSVInfo(StringRef Part);
Error parseSignature(StringRef Part, DirectX::Signature &Array);
friend class PartIterator;
@@ -382,6 +406,10 @@ class DXContainer {
std::optional<dxbc::ShaderHash> getShaderHash() const { return Hash; }
+ std::optional<DirectX::RootSignature> getRootSignature() const {
+ return RootSignature;
+ }
+
const std::optional<DirectX::PSVRuntimeInfo> &getPSVInfo() const {
return PSVInfo;
};
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 66ad057ab0e30f3..0200f5cb196ff08 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Object/DXContainer.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
#include <array>
@@ -72,6 +73,22 @@ struct ShaderHash {
std::vector<llvm::yaml::Hex8> Digest;
};
+#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
+struct RootSignatureDesc {
+ RootSignatureDesc() = default;
+ RootSignatureDesc(const object::DirectX::RootSignature &Data);
+
+ uint32_t Version;
+ uint32_t NumParameters;
+ uint32_t RootParametersOffset;
+ uint32_t NumStaticSamplers;
+ uint32_t StaticSamplersOffset;
+
+ uint32_t getEncodedFlags();
+
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+};
+
using ResourceFlags = dxbc::PSV::ResourceFlags;
using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo;
@@ -159,6 +176,7 @@ struct Part {
std::optional<ShaderHash> Hash;
std::optional<PSVInfo> Info;
std::optional<DXContainerYAML::Signature> Signature;
+ std::optional<DXContainerYAML::RootSignatureDesc> RootSignature;
};
struct Object {
@@ -241,6 +259,11 @@ template <> struct MappingTraits<DXContainerYAML::Signature> {
static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El);
};
+template <> struct MappingTraits<DXContainerYAML::RootSignatureDesc> {
+ static void mapping(IO &IO,
+ DXContainerYAML::RootSignatureDesc &RootSignature);
+};
+
} // namespace yaml
} // namespace llvm
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index e1d19196c8766a7..f49f14c848b9023 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMMC
ConstantPools.cpp
DXContainerPSVInfo.cpp
+ DXContainerRootSignature.cpp
ELFObjectWriter.cpp
GOFFObjectWriter.cpp
MCAsmBackend.cpp
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
new file mode 100644
index 000000000000000..000d23f24d2413e
--- /dev/null
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -0,0 +1,23 @@
+//===- llvm/MC/DXContainerRootSignature.cpp - RootSignature -*- C++ -*-=======//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/DXContainerRootSignature.h"
+#include "llvm/Support/EndianStream.h"
+
+using namespace llvm;
+using namespace llvm::mcdxbc;
+
+void RootSignatureHeader::write(raw_ostream &OS) {
+
+ support::endian::write(OS, Version, llvm::endianness::little);
+ support::endian::write(OS, NumParameters, llvm::endianness::little);
+ support::endian::write(OS, RootParametersOffset, llvm::endianness::little);
+ support::endian::write(OS, NumStaticSamplers, llvm::endianness::little);
+ support::endian::write(OS, StaticSamplersOffset, llvm::endianness::little);
+ support::endian::write(OS, Flags, llvm::endianness::little);
+}
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index 3b1a6203a1f8fcb..f28b096008b2fd6 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -10,6 +10,7 @@
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/Alignment.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
@@ -92,6 +93,15 @@ Error DXContainer::parseHash(StringRef Part) {
return Error::success();
}
+Error DXContainer::parseRootSignature(StringRef Part) {
+ if (RootSignature)
+ return parseFailed("More than one RTS0 part is present in the file");
+ RootSignature = DirectX::RootSignature();
+ if (Error Err = RootSignature->parse(Part))
+ return Err;
+ return Error::success();
+}
+
Error DXContainer::parsePSVInfo(StringRef Part) {
if (PSVInfo)
return parseFailed("More than one PSV0 part is present in the file");
@@ -193,6 +203,10 @@ Error DXContainer::parsePartOffsets() {
break;
case dxbc::PartType::Unknown:
break;
+ case dxbc::PartType::RTS0:
+ if (Error Err = parseRootSignature(PartData))
+ return Err;
+ break;
}
}
@@ -228,6 +242,53 @@ void DXContainer::PartIterator::updateIteratorImpl(const uint32_t Offset) {
IteratorState.Offset = Offset;
}
+Error DirectX::RootSignature::parse(StringRef Data) {
+ const char *Current = Data.begin();
+
+ // Root Signature headers expects 6 integers to be present.
+ if (Data.size() < 6 * sizeof(uint32_t))
+ return parseFailed(
+ "Invalid root signature, insufficient space for header.");
+
+ uint32_t VValue =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ Expected<uint32_t> MaybeVersion =
+ dxbc::RootSignatureValidations::validateVersion(VValue);
+ if (Error E = MaybeVersion.takeError())
+ return E;
+ Version = MaybeVersion.get();
+
+ NumParameters =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ RootParametersOffset =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ NumStaticSamplers =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ StaticSamplersOffset =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ uint32_t FValue =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ Expected<uint32_t> MaybeFlag =
+ dxbc::RootSignatureValidations::validateRootFlag(FValue);
+ if (Error E = MaybeFlag.takeError())
+ return E;
+ Flags = MaybeFlag.get();
+
+ return Error::success();
+}
+
Error DirectX::PSVRuntimeInfo::parse(uint16_t ShaderKind) {
Triple::EnvironmentType ShaderStage = dxbc::getShaderStage(ShaderKind);
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index 175f1a12f93145f..b7d1c6558fa1fd7 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -13,6 +13,7 @@
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/MC/DXContainerPSVInfo.h"
+#include "llvm/MC/DXContainerRootSignature.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/ObjectYAML/yaml2obj.h"
#include "llvm/Support/Errc.h"
@@ -261,6 +262,20 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
}
case dxbc::PartType::Unknown:
break; // Skip any handling for unrecognized parts.
+ case dxbc::PartType::RTS0:
+ if (!P.RootSignature.has_value())
+ continue;
+
+ mcdxbc::RootSignatureHeader Header;
+ Header.Flags = P.RootSignature->getEncodedFlags();
+ Header.Version = P.RootSignature->Version;
+ Header.NumParameters = P.RootSignature->NumParameters;
+ Header.RootParametersOffset = P.RootSignature->RootParametersOffset;
+ Header.NumStaticSamplers = P.RootSignature->NumStaticSamplers;
+ Header.StaticSamplersOffset = P.RootSignature->StaticSamplersOffset;
+
+ Header.write(OS);
+ break;
}
uint64_t BytesWritten = OS.tell() - DataStart;
RollingOffset += BytesWritten;
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 5dee1221b27c015..0869fd4fa978587 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -29,6 +29,27 @@ DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
+DXContainerYAML::RootSignatureDesc::RootSignatureDesc(
+ const object::DirectX::RootSignature &Data)
+ : Version(Data.getVersion()), NumParameters(Data.getNumParameters()),
+ RootParametersOffset(Data.getRootParametersOffset()),
+ NumStaticSamplers(Data.getNumStaticSamplers()),
+ StaticSamplersOffset(Data.getStaticSamplersOffset()) {
+ uint32_t Flags = Data.getFlags();
+#define ROOT_ELEMENT_FLAG(Num, Val) \
+ Val = (Flags & (uint32_t)dxbc::RootElementFlag::Val) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+}
+
+uint32_t DXContainerYAML::RootSignatureDesc::getEncodedFlags() {
+ uint64_t Flag = 0;
+#define ROOT_ELEMENT_FLAG(Num, Val) \
+ if (Val) \
+ Flag |= (uint32_t)dxbc::RootElementFlag::Val;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ return Flag;
+}
+
uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
uint64_t Flag = 0;
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
@@ -188,6 +209,17 @@ void MappingTraits<DXContainerYAML::Signature>::mapping(
IO.mapRequired("Parameters", S.Parameters);
}
+void MappingTraits<DXContainerYAML::RootSignatureDesc>::mapping(
+ IO &IO, DXContainerYAML::RootSignatureDesc &S) {
+ IO.mapRequired("Version", S.Version);
+ IO.mapRequired("NumParameters", S.NumParameters);
+ IO.mapRequired("RootParametersOffset", S.RootParametersOffset);
+ IO.mapRequired("NumStaticSamplers", S.NumStaticSamplers);
+ IO.mapRequired("StaticSamplersOffset", S.StaticSamplersOffset);
+#define ROOT_ELEMENT_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+}
+
void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
DXContainerYAML::Part &P) {
IO.mapRequired("Name", P.Name);
@@ -197,6 +229,7 @@ void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
IO.mapOptional("Hash", P.Hash);
IO.mapOptional("PSVInfo", P.Info);
IO.mapOptional("Signature", P.Signature);
+ IO.mapOptional("RootSignature", P.RootSignature);
}
void MappingTraits<DXContainerYAML::Object>::mapping(
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml
new file mode 100644
index 000000000000000..b0a3e6945f454bc
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml
@@ -0,0 +1,33 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !dxcontainer
+Header:
+ Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ Version:
+ Major: 1
+ Minor: 0
+ PartCount: 1
+ PartOffsets: [ 60 ]
+Parts:
+ - Name: RTS0
+ Size: 24
+ RootSignature:
+ Version: 2
+ NumParameters: 1
+ RootParametersOffset: 3
+ NumStaticSamplers: 4
+ StaticSamplersOffset: 5
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+
+# CHECK: - Name: RTS0
+# CHECK-NEXT: Size: 24
+# CHECK-NEXT: RootSignature:
+# CHECK-NEXT: Version: 2
+# CHECK-NEXT: NumParameters: 1
+# CHECK-NEXT: RootParametersOffset: 3
+# CHECK-NEXT: NumStaticSamplers: 4
+# CHECK-NEXT: StaticSamplersOffset: 5
+# CHECK-NEXT: AllowInputAssemblerInputLayout: true
+# CHECK-NEXT: DenyGeometryShaderRootAccess: true
diff --git a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp
index 06966b1883586c5..54a912d9438afdb 100644
--- a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp
+++ b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp
@@ -153,6 +153,11 @@ dumpDXContainer(MemoryBufferRef Source) {
break;
case dxbc::PartType::Unknown:
break;
+ case dxbc::PartType::RTS0:
+ std::optional<DirectX::RootSignature> RS = Container.getRootSignature();
+ if (RS.has_value())
+ NewPart.RootSignature = DXContainerYAML::RootSignatureDesc(*RS);
+ break;
}
}
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 5a2c852d6aef976..88a915f560e05f4 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -821,3 +821,73 @@ TEST(DXCFile, MalformedSignature) {
"the end of the part data"));
}
}
+
+TEST(RootSignature, ParseRootFlags) {
+ {
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F,
+ 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ };
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<68>(Buffer)));
+
+ const auto &RS = C.getRootSignature();
+ ASSERT_TRUE(RS.has_value());
+ ASSERT_EQ(RS->getVersion(), 2);
+ ASSERT_EQ(RS->getNumParameters(), 0);
+ ASSERT_EQ(RS->getRootParametersOffset(), 0);
+ ASSERT_EQ(RS->getNumStaticSamplers(), 0);
+ ASSERT_EQ(RS->getStaticSamplersOffset(), 0);
+ ASSERT_EQ(RS->getFlags(), 0x01);
+ }
+
+ {
+ // this parameter has the root signature definition missing some values.
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35,
+ 0x6F, 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00,
+ 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+ EXPECT_THAT_EXPECTED(
+ DXContainer::create(getMemoryBuffer<64>(Buffer)),
+ FailedWithMessage(
+ "Invalid root signature, insufficient space for header."));
+ }
+ {
+ // Version has been changed to an invalid number.
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F,
+ 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ };
+ EXPECT_THAT_EXPECTED(
+ DXContainer::create(getMemoryBuffer<68>(Buffer)),
+ FailedWithMessage("Stream Error: An unspecified error has occurred. "
+ "Invalid Root Signature Version"));
+ }
+ {
+ // Flag has been set to an invalid value
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F,
+ 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xFF,
+ };
+ EXPECT_THAT_EXPECTED(
+ DXContainer::create(getMemoryBuffer<68>(Buffer)),
+ FailedWithMessage("Stream Error: An unspecified error has occurred. "
+ "Invalid Root Signature flag"));
+ }
+}
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index d4232295c8584ad..b48cd9ce5398731 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -107,3 +107,42 @@ TEST(DXCFile, ParseEmptyParts) {
EXPECT_EQ(Storage.size(), 116u);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 116) == 0);
}
+
+TEST(RootSignature, ParseRootFlags) {
+ SmallString<128> Storage;
+
+ // First read a fully explicit yaml with all sizes and offsets provided
+ ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+ Header:
+ Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
+ 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+ Version:
+ Major: 1
+ Minor: 0
+ FileSize: 68
+ PartCount: 1
+ PartOffsets: [ 36 ]
+ Parts:
+ - Name: RTS0
+ Size: 24
+ RootSignature:
+ Version: 2
+ NumParameters: 0
+ RootParametersOffset: 0
+ NumStaticSamplers: 0
+ StaticSamplersOffset: 0
+ AllowInputAssemblerInputLayout: true
+ )"));
+
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F,
+ 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ };
+
+ EXPECT_EQ(Storage.size(), 68u);
+ EXPECT_TRUE(memcmp(Buffer, Storage.data(), 68u) == 0);
+}
More information about the llvm-commits
mailing list