[llvm] [DirectX] Adding support for Root Descriptors in obj2yaml/yaml2obj (PR #137259)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 8 17:10:56 PDT 2025


https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/137259

>From 0abacfcb1e5b0602cd5b535cd224768028337077 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 24 Apr 2025 21:54:56 +0000
Subject: [PATCH 01/11] adding support for Root Descriptors

---
 llvm/include/llvm/BinaryFormat/DXContainer.h  |  28 ++++-
 .../BinaryFormat/DXContainerConstants.def     |  15 +++
 .../llvm/MC/DXContainerRootSignature.h        |   4 +-
 llvm/include/llvm/Object/DXContainer.h        |  47 +++++++-
 .../include/llvm/ObjectYAML/DXContainerYAML.h |  34 +++++-
 llvm/lib/MC/DXContainerRootSignature.cpp      |  25 +++++
 llvm/lib/ObjectYAML/DXContainerEmitter.cpp    |  17 +++
 llvm/lib/ObjectYAML/DXContainerYAML.cpp       |  53 ++++++++-
 .../RootSignature-Descriptor1.0.yaml          |  45 ++++++++
 .../RootSignature-Descriptor1.1.yaml          |  47 ++++++++
 .../RootSignature-MultipleParameters.yaml     |  20 +++-
 llvm/unittests/Object/DXContainerTest.cpp     |  91 ++++++++++++++++
 .../ObjectYAML/DXContainerYAMLTest.cpp        | 103 ++++++++++++++++++
 13 files changed, 514 insertions(+), 15 deletions(-)
 create mode 100644 llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml
 create mode 100644 llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.1.yaml

diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 455657980bf40..439bf7b40f31b 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -158,6 +158,11 @@ enum class RootElementFlag : uint32_t {
 #include "DXContainerConstants.def"
 };
 
+#define ROOT_DESCRIPTOR_FLAG(Num, Val) Val = 1ull << Num,
+enum class RootDescriptorFlag : uint32_t {
+#include "DXContainerConstants.def"
+};
+
 #define ROOT_PARAMETER(Val, Enum) Enum = Val,
 enum class RootParameterType : uint32_t {
 #include "DXContainerConstants.def"
@@ -422,7 +427,6 @@ struct SignatureElement {
 
 static_assert(sizeof(SignatureElement) == 4 * sizeof(uint32_t),
               "PSV Signature elements must fit in 16 bytes.");
-
 } // namespace v0
 
 namespace v1 {
@@ -463,7 +467,6 @@ struct RuntimeInfo : public v0::RuntimeInfo {
       sys::swapByteOrder(GeomData.MaxVertexCount);
   }
 };
-
 } // namespace v1
 
 namespace v2 {
@@ -580,7 +583,28 @@ struct ProgramSignatureElement {
 
 static_assert(sizeof(ProgramSignatureElement) == 32,
               "ProgramSignatureElement is misaligned");
+namespace RST0 {
+namespace v0 {
+struct RootDescriptor {
+  uint32_t ShaderRegister;
+  uint32_t RegisterSpace;
+  void swapBytes() {
+    sys::swapByteOrder(ShaderRegister);
+    sys::swapByteOrder(RegisterSpace);
+  }
+};
+} // namespace v0
 
+namespace v1 {
+struct RootDescriptor : public v0::RootDescriptor {
+  uint32_t Flags;
+  void swapBytes() {
+    v0::RootDescriptor::swapBytes();
+    sys::swapByteOrder(Flags);
+  }
+};
+} // namespace v1
+} // namespace RST0
 // following dx12 naming
 // https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_root_constants
 struct RootConstants {
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 590ded5e8c899..bd9bd760547dc 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -72,9 +72,24 @@ ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
 #undef ROOT_ELEMENT_FLAG
 #endif // ROOT_ELEMENT_FLAG
 
+ 
+// ROOT_ELEMENT_FLAG(bit offset for the flag, name).
+#ifdef ROOT_DESCRIPTOR_FLAG
+
+ROOT_DESCRIPTOR_FLAG(0, NONE)
+ROOT_DESCRIPTOR_FLAG(1, DATA_VOLATILE)
+ROOT_DESCRIPTOR_FLAG(2, DATA_STATIC_WHILE_SET_AT_EXECUTE)
+ROOT_DESCRIPTOR_FLAG(3, DATA_STATIC)
+#undef ROOT_DESCRIPTOR_FLAG
+#endif // ROOT_DESCRIPTOR_FLAG
+
+
 #ifdef ROOT_PARAMETER
 
 ROOT_PARAMETER(1, Constants32Bit)
+ROOT_PARAMETER(2, CBV)
+ROOT_PARAMETER(3, SRV)
+ROOT_PARAMETER(4, UAV)
 #undef ROOT_PARAMETER
 #endif // ROOT_PARAMETER
 
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index fee799249b255..ac062a375818c 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -19,13 +19,15 @@ struct RootParameter {
   dxbc::RootParameterHeader Header;
   union {
     dxbc::RootConstants Constants;
+    dxbc::RST0::v0::RootDescriptor Descriptor_V10;
+    dxbc::RST0::v1::RootDescriptor Descriptor_V11;
   };
 };
 struct RootSignatureDesc {
 
   uint32_t Version = 2U;
   uint32_t Flags = 0U;
-  uint32_t RootParameterOffset = 0U;
+  uint32_t RootParameterOffset = 24U;
   uint32_t StaticSamplersOffset = 0u;
   uint32_t NumStaticSamplers = 0u;
   SmallVector<mcdxbc::RootParameter> Parameters;
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e8287ce078365..ba261a9e42aea 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -120,9 +120,10 @@ template <typename T> struct ViewArray {
 namespace DirectX {
 struct RootParameterView {
   const dxbc::RootParameterHeader &Header;
+  uint32_t Version;
   StringRef ParamData;
-  RootParameterView(const dxbc::RootParameterHeader &H, StringRef P)
-      : Header(H), ParamData(P) {}
+  RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
+      : Header(H), Version(V), ParamData(P) {}
 
   template <typename T> Expected<T> readParameter() {
     T Struct;
@@ -149,6 +150,38 @@ struct RootConstantView : RootParameterView {
   }
 };
 
+struct RootDescriptorView_V1_0 : RootParameterView {
+  static bool classof(const RootParameterView *V) {
+    return (V->Version == 1 &&
+            (V->Header.ParameterType ==
+                 llvm::to_underlying(dxbc::RootParameterType::CBV) ||
+             V->Header.ParameterType ==
+                 llvm::to_underlying(dxbc::RootParameterType::SRV) ||
+             V->Header.ParameterType ==
+                 llvm::to_underlying(dxbc::RootParameterType::UAV)));
+  }
+
+  llvm::Expected<dxbc::RST0::v0::RootDescriptor> read() {
+    return readParameter<dxbc::RST0::v0::RootDescriptor>();
+  }
+};
+
+struct RootDescriptorView_V1_1 : RootParameterView {
+  static bool classof(const RootParameterView *V) {
+    return (V->Version == 2 &&
+            (V->Header.ParameterType ==
+                 llvm::to_underlying(dxbc::RootParameterType::CBV) ||
+             V->Header.ParameterType ==
+                 llvm::to_underlying(dxbc::RootParameterType::SRV) ||
+             V->Header.ParameterType ==
+                 llvm::to_underlying(dxbc::RootParameterType::UAV)));
+  }
+
+  llvm::Expected<dxbc::RST0::v1::RootDescriptor> read() {
+    return readParameter<dxbc::RST0::v1::RootDescriptor>();
+  }
+};
+
 static Error parseFailed(const Twine &Msg) {
   return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
 }
@@ -192,6 +225,14 @@ class RootSignature {
     case dxbc::RootParameterType::Constants32Bit:
       DataSize = sizeof(dxbc::RootConstants);
       break;
+    case dxbc::RootParameterType::CBV:
+    case dxbc::RootParameterType::SRV:
+    case dxbc::RootParameterType::UAV:
+      if (Version == 1)
+        DataSize = sizeof(dxbc::RST0::v0::RootDescriptor);
+      else
+        DataSize = sizeof(dxbc::RST0::v1::RootDescriptor);
+      break;
     }
     size_t EndOfSectionByte = getNumStaticSamplers() == 0
                                   ? PartData.size()
@@ -201,7 +242,7 @@ class RootSignature {
       return parseFailed("Reading structure out of file bounds");
 
     StringRef Buff = PartData.substr(Header.ParameterOffset, DataSize);
-    RootParameterView View = RootParameterView(Header, Buff);
+    RootParameterView View = RootParameterView(Version, Header, Buff);
     return View;
   }
 };
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 393bba9c79bf8..e86a869da99bc 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -73,24 +73,50 @@ struct ShaderHash {
   std::vector<llvm::yaml::Hex8> Digest;
 };
 
-#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
-
 struct RootConstantsYaml {
   uint32_t ShaderRegister;
   uint32_t RegisterSpace;
   uint32_t Num32BitValues;
 };
 
+#define ROOT_DESCRIPTOR_FLAG(Num, Val) bool Val = false;
+struct RootDescriptorYaml {
+  RootDescriptorYaml() = default;
+
+  uint32_t ShaderRegister;
+  uint32_t RegisterSpace;
+
+  uint32_t getEncodedFlags() const;
+
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+};
+
 struct RootParameterYamlDesc {
   uint32_t Type;
   uint32_t Visibility;
   uint32_t Offset;
+  RootParameterYamlDesc(){};
+  RootParameterYamlDesc(uint32_t T) : Type(T) {
+    switch (T) {
+
+    case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
+      Constants = RootConstantsYaml();
+      break;
+    case llvm::to_underlying(dxbc::RootParameterType::CBV):
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+      Descriptor = RootDescriptorYaml();
+      break;
+    }
+  }
 
   union {
     RootConstantsYaml Constants;
+    RootDescriptorYaml Descriptor;
   };
 };
 
+#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
 struct RootSignatureYamlDesc {
   RootSignatureYamlDesc() = default;
 
@@ -298,6 +324,10 @@ template <> struct MappingTraits<llvm::DXContainerYAML::RootConstantsYaml> {
   static void mapping(IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C);
 };
 
+template <> struct MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml> {
+  static void mapping(IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D);
+};
+
 } // namespace yaml
 
 } // namespace llvm
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index c2731d95c955e..a5210f4768f16 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -37,6 +37,15 @@ size_t RootSignatureDesc::getSize() const {
     case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
       Size += sizeof(dxbc::RootConstants);
       break;
+    case llvm::to_underlying(dxbc::RootParameterType::CBV):
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+      if (Version == 1)
+        Size += sizeof(dxbc::RST0::v0::RootDescriptor);
+      else
+        Size += sizeof(dxbc::RST0::v1::RootDescriptor);
+
+      break;
     }
   }
   return Size;
@@ -80,6 +89,22 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
       support::endian::write(BOS, P.Constants.Num32BitValues,
                              llvm::endianness::little);
       break;
+    case llvm::to_underlying(dxbc::RootParameterType::CBV):
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+      if (Version == 1) {
+        support::endian::write(BOS, P.Descriptor_V10.ShaderRegister,
+                               llvm::endianness::little);
+        support::endian::write(BOS, P.Descriptor_V10.RegisterSpace,
+                               llvm::endianness::little);
+      } else {
+        support::endian::write(BOS, P.Descriptor_V11.ShaderRegister,
+                               llvm::endianness::little);
+        support::endian::write(BOS, P.Descriptor_V11.RegisterSpace,
+                               llvm::endianness::little);
+        support::endian::write(BOS, P.Descriptor_V11.Flags,
+                               llvm::endianness::little);
+      }
     }
   }
   assert(Storage.size() == getSize());
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index 86e24eae4abc6..be0e52fef04f5 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -283,6 +283,23 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
           NewParam.Constants.Num32BitValues = Param.Constants.Num32BitValues;
           NewParam.Constants.RegisterSpace = Param.Constants.RegisterSpace;
           NewParam.Constants.ShaderRegister = Param.Constants.ShaderRegister;
+          break;
+        case llvm::to_underlying(dxbc::RootParameterType::SRV):
+        case llvm::to_underlying(dxbc::RootParameterType::UAV):
+        case llvm::to_underlying(dxbc::RootParameterType::CBV):
+          if (RS.Version == 1) {
+            NewParam.Descriptor_V10.RegisterSpace =
+                Param.Descriptor.RegisterSpace;
+            NewParam.Descriptor_V10.ShaderRegister =
+                Param.Descriptor.ShaderRegister;
+          } else {
+            NewParam.Descriptor_V11.RegisterSpace =
+                Param.Descriptor.RegisterSpace;
+            NewParam.Descriptor_V11.ShaderRegister =
+                Param.Descriptor.ShaderRegister;
+            NewParam.Descriptor_V11.Flags = Param.Descriptor.getEncodedFlags();
+          }
+
           break;
         }
 
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 59914fe30082d..ef86da85989e6 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Object/DXContainer.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <cstdint>
@@ -48,13 +49,12 @@ DXContainerYAML::RootSignatureYamlDesc::create(
   uint32_t Flags = Data.getFlags();
   for (const dxbc::RootParameterHeader &PH : Data.param_headers()) {
 
-    RootParameterYamlDesc NewP;
-    NewP.Offset = PH.ParameterOffset;
-
     if (!dxbc::isValidParameterType(PH.ParameterType))
       return createStringError(std::errc::invalid_argument,
                                "Invalid value for parameter type");
 
+    RootParameterYamlDesc NewP(PH.ParameterType);
+    NewP.Offset = PH.ParameterOffset;
     NewP.Type = PH.ParameterType;
 
     if (!dxbc::isValidShaderVisibility(PH.ShaderVisibility))
@@ -79,7 +79,32 @@ DXContainerYAML::RootSignatureYamlDesc::create(
       NewP.Constants.Num32BitValues = Constants.Num32BitValues;
       NewP.Constants.ShaderRegister = Constants.ShaderRegister;
       NewP.Constants.RegisterSpace = Constants.RegisterSpace;
+    } else if (auto *RDV = dyn_cast<object::DirectX::RootDescriptorView_V1_0>(
+                   &ParamView)) {
+      llvm::Expected<dxbc::RST0::v0::RootDescriptor> DescriptorOrErr =
+          RDV->read();
+      if (Error E = DescriptorOrErr.takeError())
+        return std::move(E);
+      auto Descriptor = *DescriptorOrErr;
+
+      NewP.Descriptor.ShaderRegister = Descriptor.ShaderRegister;
+      NewP.Descriptor.RegisterSpace = Descriptor.RegisterSpace;
+    } else if (auto *RDV = dyn_cast<object::DirectX::RootDescriptorView_V1_1>(
+                   &ParamView)) {
+      llvm::Expected<dxbc::RST0::v1::RootDescriptor> DescriptorOrErr =
+          RDV->read();
+      if (Error E = DescriptorOrErr.takeError())
+        return std::move(E);
+      auto Descriptor = *DescriptorOrErr;
+      NewP.Descriptor.ShaderRegister = Descriptor.ShaderRegister;
+      NewP.Descriptor.RegisterSpace = Descriptor.RegisterSpace;
+#define ROOT_DESCRIPTOR_FLAG(Num, Val)                                         \
+  NewP.Descriptor.Val =                                                        \
+      (Descriptor.Flags &                                                      \
+       llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
     }
+
     RootSigDesc.Parameters.push_back(NewP);
   }
 #define ROOT_ELEMENT_FLAG(Num, Val)                                            \
@@ -89,6 +114,15 @@ DXContainerYAML::RootSignatureYamlDesc::create(
   return RootSigDesc;
 }
 
+uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const {
+  uint64_t Flag = 0;
+#define ROOT_DESCRIPTOR_FLAG(Num, Val)                                         \
+  if (Val)                                                                     \
+    Flag |= (uint32_t)dxbc::RootDescriptorFlag::Val;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+  return Flag;
+}
+
 uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
   uint64_t Flag = 0;
 #define ROOT_ELEMENT_FLAG(Num, Val)                                            \
@@ -276,6 +310,14 @@ void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
   IO.mapRequired("ShaderRegister", C.ShaderRegister);
 }
 
+void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
+    IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
+  IO.mapRequired("RegisterSpace", D.RegisterSpace);
+  IO.mapRequired("ShaderRegister", D.ShaderRegister);
+#define ROOT_DESCRIPTOR_FLAG(Num, Val) IO.mapOptional(#Val, D.Val, false);
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+}
+
 void MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc>::mapping(
     IO &IO, llvm::DXContainerYAML::RootParameterYamlDesc &P) {
   IO.mapRequired("ParameterType", P.Type);
@@ -285,6 +327,11 @@ void MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc>::mapping(
   case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
     IO.mapRequired("Constants", P.Constants);
     break;
+  case llvm::to_underlying(dxbc::RootParameterType::CBV):
+  case llvm::to_underlying(dxbc::RootParameterType::SRV):
+  case llvm::to_underlying(dxbc::RootParameterType::UAV):
+    IO.mapRequired("Descriptor", P.Descriptor);
+    break;
   }
 }
 
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml
new file mode 100644
index 0000000000000..46cdf416ffcae
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml
@@ -0,0 +1,45 @@
+# 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:            96
+    RootSignature:
+      Version: 1
+      NumRootParameters: 1
+      RootParametersOffset: 24
+      NumStaticSamplers: 0
+      StaticSamplersOffset: 60
+      Parameters:         
+      - ParameterType: 2 # SRV
+        ShaderVisibility: 3 # Domain
+        Descriptor:
+          ShaderRegister: 31
+          RegisterSpace: 32
+      AllowInputAssemblerInputLayout: true
+      DenyGeometryShaderRootAccess: true
+
+# CHECK:  - Name:            RTS0
+# CHECK-NEXT:    Size:            96
+# CHECK-NEXT:    RootSignature:
+# CHECK-NEXT:      Version: 1
+# CHECK-NEXT:      NumRootParameters: 1
+# CHECK-NEXT:      RootParametersOffset: 24
+# CHECK-NEXT:      NumStaticSamplers: 0
+# CHECK-NEXT:      StaticSamplersOffset: 60
+# CHECK-NEXT:      Parameters:         
+# CHECK-NEXT:      - ParameterType: 2
+# CHECK-NEXT:        ShaderVisibility: 3
+# CHECK-NEXT:        Descriptor:
+# CHECK-NEXT:          RegisterSpace: 32
+# CHECK-NEXT:          ShaderRegister: 31
+# CHECK-NEXT:      AllowInputAssemblerInputLayout: true
+# CHECK-NEXT:      DenyGeometryShaderRootAccess: true
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.1.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.1.yaml
new file mode 100644
index 0000000000000..64e01c6836e32
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.1.yaml
@@ -0,0 +1,47 @@
+# 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:            89
+    RootSignature:
+      Version: 2
+      NumRootParameters: 1
+      RootParametersOffset: 24
+      NumStaticSamplers: 0
+      StaticSamplersOffset: 60
+      Parameters:         
+      - ParameterType: 2 # SRV
+        ShaderVisibility: 3 # Domain
+        Descriptor:
+          ShaderRegister: 31
+          RegisterSpace: 32
+          DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+      AllowInputAssemblerInputLayout: true
+      DenyGeometryShaderRootAccess: true
+
+# CHECK:  - Name:            RTS0
+# CHECK-NEXT:    Size:            89
+# CHECK-NEXT:    RootSignature:
+# CHECK-NEXT:      Version: 2
+# CHECK-NEXT:      NumRootParameters: 1
+# CHECK-NEXT:      RootParametersOffset: 24
+# CHECK-NEXT:      NumStaticSamplers: 0
+# CHECK-NEXT:      StaticSamplersOffset: 60
+# CHECK-NEXT:      Parameters:         
+# CHECK-NEXT:      - ParameterType: 2
+# CHECK-NEXT:        ShaderVisibility: 3
+# CHECK-NEXT:        Descriptor:
+# CHECK-NEXT:          RegisterSpace: 32
+# CHECK-NEXT:          ShaderRegister: 31
+# CHECK-NEXT:          DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+# CHECK-NEXT:      AllowInputAssemblerInputLayout: true
+# CHECK-NEXT:      DenyGeometryShaderRootAccess: true
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
index f366d71714359..debb459c3944e 100644
--- a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
@@ -11,10 +11,10 @@ Header:
   PartOffsets:     [ 60 ]
 Parts:
   - Name:            RTS0
-    Size:            80
+    Size:            96
     RootSignature:
       Version: 2
-      NumRootParameters: 2
+      NumRootParameters: 3
       RootParametersOffset: 24
       NumStaticSamplers: 0
       StaticSamplersOffset: 60
@@ -31,14 +31,20 @@ Parts:
           Num32BitValues: 21
           ShaderRegister: 22
           RegisterSpace: 23     
+      - ParameterType: 2 # SRV
+        ShaderVisibility: 3 # Domain
+        Descriptor:
+          ShaderRegister: 31
+          RegisterSpace: 32
+          DATA_STATIC_WHILE_SET_AT_EXECUTE: true
       AllowInputAssemblerInputLayout: true
       DenyGeometryShaderRootAccess: true
 
 # CHECK:  - Name:            RTS0
-# CHECK-NEXT:    Size:            80
+# CHECK-NEXT:    Size:            96
 # CHECK-NEXT:    RootSignature:
 # CHECK-NEXT:      Version:         2
-# CHECK-NEXT:      NumRootParameters: 2
+# CHECK-NEXT:      NumRootParameters: 3
 # CHECK-NEXT:      RootParametersOffset: 24
 # CHECK-NEXT:      NumStaticSamplers: 0
 # CHECK-NEXT:      StaticSamplersOffset: 60
@@ -55,5 +61,11 @@ Parts:
 # CHECK-NEXT:            Num32BitValues:  21
 # CHECK-NEXT:            RegisterSpace:   23
 # CHECK-NEXT:            ShaderRegister:  22
+# CHECK-NEXT:        - ParameterType:   2
+# CHECK-NEXT:          ShaderVisibility: 3
+# CHECK-NEXT:          Descriptor:
+# CHECK-NEXT:            RegisterSpace:   32
+# CHECK-NEXT:            ShaderRegister:  31
+# CHECK-NEXT:            DATA_STATIC_WHILE_SET_AT_EXECUTE: true
 # CHECK-NEXT:      AllowInputAssemblerInputLayout: true
 # CHECK-NEXT:      DenyGeometryShaderRootAccess: true
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 62ef8e385373f..ed43f6deaa951 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -959,3 +959,94 @@ TEST(RootSignature, ParseRootConstant) {
     ASSERT_EQ(Constants->Num32BitValues, 16u);
   }
 }
+
+TEST(RootSignature, ParseRootDescriptor) {
+  {
+    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,
+        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00};
+    DXContainer C =
+        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
+
+    auto MaybeRS = C.getRootSignature();
+    ASSERT_TRUE(MaybeRS.has_value());
+    const auto &RS = MaybeRS.value();
+    ASSERT_EQ(RS.getVersion(), 1u);
+    ASSERT_EQ(RS.getNumParameters(), 1u);
+    ASSERT_EQ(RS.getRootParametersOffset(), 24u);
+    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);
+    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);
+    ASSERT_EQ(RS.getFlags(), 17u);
+
+    auto RootParam = *RS.param_headers().begin();
+    ASSERT_EQ((unsigned)RootParam.ParameterType, 2u);
+    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);
+    auto ParamView = RS.getParameter(RootParam);
+    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
+
+    DirectX::RootDescriptorView_V1_0 *RootDescriptorView =
+        dyn_cast<DirectX::RootDescriptorView_V1_0>(&*ParamView);
+    ASSERT_TRUE(RootDescriptorView != nullptr);
+    auto Descriptor = RootDescriptorView->read();
+
+    ASSERT_THAT_ERROR(Descriptor.takeError(), Succeeded());
+
+    ASSERT_EQ(Descriptor->ShaderRegister, 31u);
+    ASSERT_EQ(Descriptor->RegisterSpace, 32u);
+  }
+
+  {
+    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,
+        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+        0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00};
+    DXContainer C =
+        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
+
+    auto MaybeRS = C.getRootSignature();
+    ASSERT_TRUE(MaybeRS.has_value());
+    const auto &RS = MaybeRS.value();
+    ASSERT_EQ(RS.getVersion(), 2u);
+    ASSERT_EQ(RS.getNumParameters(), 1u);
+    ASSERT_EQ(RS.getRootParametersOffset(), 24u);
+    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);
+    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);
+    ASSERT_EQ(RS.getFlags(), 17u);
+
+    auto RootParam = *RS.param_headers().begin();
+    ASSERT_EQ((unsigned)RootParam.ParameterType, 2u);
+    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);
+    auto ParamView = RS.getParameter(RootParam);
+    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
+
+    DirectX::RootDescriptorView_V1_1 *RootDescriptorView =
+        dyn_cast<DirectX::RootDescriptorView_V1_1>(&*ParamView);
+    ASSERT_TRUE(RootDescriptorView != nullptr);
+    auto Descriptor = RootDescriptorView->read();
+
+    ASSERT_THAT_ERROR(Descriptor.takeError(), Succeeded());
+
+    ASSERT_EQ(Descriptor->ShaderRegister, 31u);
+    ASSERT_EQ(Descriptor->RegisterSpace, 32u);
+    ASSERT_EQ(Descriptor->Flags, 4u);
+  }
+}
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index 61390049bc0df..b6a5cee24b29d 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -251,3 +251,106 @@ TEST(RootSignature, ParseRootConstants) {
   EXPECT_EQ(Storage.size(), 133u);
   EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
 }
+
+TEST(RootSignature, ParseRootDescriptorsV10) {
+  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:        133
+      PartCount:       1
+      PartOffsets:     [ 36 ]
+  Parts:
+  - Name:            RTS0
+    Size:            89
+    RootSignature:
+      Version: 1
+      NumRootParameters: 1
+      RootParametersOffset: 24
+      NumStaticSamplers: 0
+      StaticSamplersOffset: 60
+      Parameters:         
+      - ParameterType: 2 # SRV
+        ShaderVisibility: 3 # Domain
+        Descriptor:
+          ShaderRegister: 31
+          RegisterSpace: 32
+      AllowInputAssemblerInputLayout: true
+      DenyGeometryShaderRootAccess: 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,
+      0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+      0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+      0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+      0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00};
+
+  EXPECT_EQ(Storage.size(), 133u);
+  EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
+}
+
+TEST(RootSignature, ParseRootDescriptorsV11) {
+  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:        133
+      PartCount:       1
+      PartOffsets:     [ 36 ]
+  Parts:
+  - Name:            RTS0
+    Size:            89
+    RootSignature:
+      Version: 2
+      NumRootParameters: 1
+      RootParametersOffset: 24
+      NumStaticSamplers: 0
+      StaticSamplersOffset: 60
+      Parameters:         
+      - ParameterType: 2 # SRV
+        ShaderVisibility: 3 # Domain
+        Descriptor:
+          ShaderRegister: 31
+          RegisterSpace: 32
+          DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+      AllowInputAssemblerInputLayout: true
+      DenyGeometryShaderRootAccess: 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,
+      0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+      0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+      0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+      0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+      0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00};
+
+  EXPECT_EQ(Storage.size(), 133u);
+  EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
+}

>From 8b8c02a6107b2b01bbc9cc9d84504d71e2726523 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 24 Apr 2025 22:34:06 +0000
Subject: [PATCH 02/11] clean up

---
 llvm/include/llvm/BinaryFormat/DXContainer.h    | 2 ++
 llvm/include/llvm/MC/DXContainerRootSignature.h | 2 +-
 llvm/include/llvm/ObjectYAML/DXContainerYAML.h  | 2 +-
 llvm/lib/ObjectYAML/DXContainerYAML.cpp         | 1 -
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 439bf7b40f31b..3dbcfa82f3d7c 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -427,6 +427,7 @@ struct SignatureElement {
 
 static_assert(sizeof(SignatureElement) == 4 * sizeof(uint32_t),
               "PSV Signature elements must fit in 16 bytes.");
+
 } // namespace v0
 
 namespace v1 {
@@ -467,6 +468,7 @@ struct RuntimeInfo : public v0::RuntimeInfo {
       sys::swapByteOrder(GeomData.MaxVertexCount);
   }
 };
+
 } // namespace v1
 
 namespace v2 {
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index ac062a375818c..1f421d726bf38 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -27,7 +27,7 @@ struct RootSignatureDesc {
 
   uint32_t Version = 2U;
   uint32_t Flags = 0U;
-  uint32_t RootParameterOffset = 24U;
+  uint32_t RootParameterOffset = 0U;
   uint32_t StaticSamplersOffset = 0u;
   uint32_t NumStaticSamplers = 0u;
   SmallVector<mcdxbc::RootParameter> Parameters;
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index e86a869da99bc..c54c995acd263 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -95,7 +95,7 @@ struct RootParameterYamlDesc {
   uint32_t Type;
   uint32_t Visibility;
   uint32_t Offset;
-  RootParameterYamlDesc(){};
+  RootParameterYamlDesc() {};
   RootParameterYamlDesc(uint32_t T) : Type(T) {
     switch (T) {
 
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index ef86da85989e6..e49712852d612 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -15,7 +15,6 @@
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/BinaryFormat/DXContainer.h"
-#include "llvm/Object/DXContainer.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <cstdint>

>From 7ac964196fc9195165dc1128d0f889f6ff1a93b4 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 25 Apr 2025 22:28:48 +0000
Subject: [PATCH 03/11] addressing comments

---
 llvm/include/llvm/Object/DXContainer.h        | 50 +++++++------------
 .../include/llvm/ObjectYAML/DXContainerYAML.h |  6 +--
 llvm/lib/ObjectYAML/DXContainerYAML.cpp       | 17 ++-----
 llvm/unittests/Object/DXContainerTest.cpp     | 12 ++---
 4 files changed, 32 insertions(+), 53 deletions(-)

diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index ba261a9e42aea..e359d85f08bec 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -120,18 +120,20 @@ template <typename T> struct ViewArray {
 namespace DirectX {
 struct RootParameterView {
   const dxbc::RootParameterHeader &Header;
-  uint32_t Version;
   StringRef ParamData;
   RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
-      : Header(H), Version(V), ParamData(P) {}
+      : Header(H), ParamData(P) {}
 
-  template <typename T> Expected<T> readParameter() {
-    T Struct;
-    if (sizeof(T) != ParamData.size())
+  template <typename T, typename VersionT = T> Expected<T> readParameter() {
+    assert(sizeof(VersionT) <= sizeof(T) &&
+           "Parameter of higher version must inherit all previous version data "
+           "members");
+    if (sizeof(VersionT) != ParamData.size())
       return make_error<GenericBinaryError>(
           "Reading structure out of file bounds", object_error::parse_failed);
 
-    memcpy(&Struct, ParamData.data(), sizeof(T));
+    T Struct;
+    memcpy(&Struct, ParamData.data(), sizeof(VersionT));
     // DXContainer is always little endian
     if (sys::IsBigEndianHost)
       Struct.swapBytes();
@@ -150,34 +152,20 @@ struct RootConstantView : RootParameterView {
   }
 };
 
-struct RootDescriptorView_V1_0 : RootParameterView {
-  static bool classof(const RootParameterView *V) {
-    return (V->Version == 1 &&
-            (V->Header.ParameterType ==
-                 llvm::to_underlying(dxbc::RootParameterType::CBV) ||
-             V->Header.ParameterType ==
-                 llvm::to_underlying(dxbc::RootParameterType::SRV) ||
-             V->Header.ParameterType ==
-                 llvm::to_underlying(dxbc::RootParameterType::UAV)));
-  }
-
-  llvm::Expected<dxbc::RST0::v0::RootDescriptor> read() {
-    return readParameter<dxbc::RST0::v0::RootDescriptor>();
-  }
-};
-
-struct RootDescriptorView_V1_1 : RootParameterView {
+struct RootDescriptorView : RootParameterView {
   static bool classof(const RootParameterView *V) {
-    return (V->Version == 2 &&
-            (V->Header.ParameterType ==
-                 llvm::to_underlying(dxbc::RootParameterType::CBV) ||
-             V->Header.ParameterType ==
-                 llvm::to_underlying(dxbc::RootParameterType::SRV) ||
-             V->Header.ParameterType ==
-                 llvm::to_underlying(dxbc::RootParameterType::UAV)));
+    return (V->Header.ParameterType ==
+                llvm::to_underlying(dxbc::RootParameterType::CBV) ||
+            V->Header.ParameterType ==
+                llvm::to_underlying(dxbc::RootParameterType::SRV) ||
+            V->Header.ParameterType ==
+                llvm::to_underlying(dxbc::RootParameterType::UAV));
   }
 
-  llvm::Expected<dxbc::RST0::v1::RootDescriptor> read() {
+  llvm::Expected<dxbc::RST0::v1::RootDescriptor> read(uint32_t Version) {
+    if (Version == 1)
+      return readParameter<dxbc::RST0::v1::RootDescriptor,
+                           dxbc::RST0::v0::RootDescriptor>();
     return readParameter<dxbc::RST0::v1::RootDescriptor>();
   }
 };
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index c54c995acd263..8bb9da7884bed 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -79,7 +79,6 @@ struct RootConstantsYaml {
   uint32_t Num32BitValues;
 };
 
-#define ROOT_DESCRIPTOR_FLAG(Num, Val) bool Val = false;
 struct RootDescriptorYaml {
   RootDescriptorYaml() = default;
 
@@ -88,6 +87,7 @@ struct RootDescriptorYaml {
 
   uint32_t getEncodedFlags() const;
 
+#define ROOT_DESCRIPTOR_FLAG(Num, Val) bool Val = false;
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 };
 
@@ -95,7 +95,7 @@ struct RootParameterYamlDesc {
   uint32_t Type;
   uint32_t Visibility;
   uint32_t Offset;
-  RootParameterYamlDesc() {};
+  RootParameterYamlDesc(){};
   RootParameterYamlDesc(uint32_t T) : Type(T) {
     switch (T) {
 
@@ -116,7 +116,6 @@ struct RootParameterYamlDesc {
   };
 };
 
-#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
 struct RootSignatureYamlDesc {
   RootSignatureYamlDesc() = default;
 
@@ -137,6 +136,7 @@ struct RootSignatureYamlDesc {
   static llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
   create(const object::DirectX::RootSignature &Data);
 
+#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 };
 
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index e49712852d612..c9d2084226b7a 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Object/DXContainer.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <cstdint>
@@ -78,20 +79,10 @@ DXContainerYAML::RootSignatureYamlDesc::create(
       NewP.Constants.Num32BitValues = Constants.Num32BitValues;
       NewP.Constants.ShaderRegister = Constants.ShaderRegister;
       NewP.Constants.RegisterSpace = Constants.RegisterSpace;
-    } else if (auto *RDV = dyn_cast<object::DirectX::RootDescriptorView_V1_0>(
-                   &ParamView)) {
-      llvm::Expected<dxbc::RST0::v0::RootDescriptor> DescriptorOrErr =
-          RDV->read();
-      if (Error E = DescriptorOrErr.takeError())
-        return std::move(E);
-      auto Descriptor = *DescriptorOrErr;
-
-      NewP.Descriptor.ShaderRegister = Descriptor.ShaderRegister;
-      NewP.Descriptor.RegisterSpace = Descriptor.RegisterSpace;
-    } else if (auto *RDV = dyn_cast<object::DirectX::RootDescriptorView_V1_1>(
-                   &ParamView)) {
+    } else if (auto *RDV =
+                   dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) {
       llvm::Expected<dxbc::RST0::v1::RootDescriptor> DescriptorOrErr =
-          RDV->read();
+          RDV->read(Data.getVersion());
       if (Error E = DescriptorOrErr.takeError())
         return std::move(E);
       auto Descriptor = *DescriptorOrErr;
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index ed43f6deaa951..72f860a5039ff 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -994,10 +994,10 @@ TEST(RootSignature, ParseRootDescriptor) {
     auto ParamView = RS.getParameter(RootParam);
     ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
 
-    DirectX::RootDescriptorView_V1_0 *RootDescriptorView =
-        dyn_cast<DirectX::RootDescriptorView_V1_0>(&*ParamView);
+    DirectX::RootDescriptorView *RootDescriptorView =
+        dyn_cast<DirectX::RootDescriptorView>(&*ParamView);
     ASSERT_TRUE(RootDescriptorView != nullptr);
-    auto Descriptor = RootDescriptorView->read();
+    auto Descriptor = RootDescriptorView->read(RS.getVersion());
 
     ASSERT_THAT_ERROR(Descriptor.takeError(), Succeeded());
 
@@ -1038,10 +1038,10 @@ TEST(RootSignature, ParseRootDescriptor) {
     auto ParamView = RS.getParameter(RootParam);
     ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
 
-    DirectX::RootDescriptorView_V1_1 *RootDescriptorView =
-        dyn_cast<DirectX::RootDescriptorView_V1_1>(&*ParamView);
+    DirectX::RootDescriptorView *RootDescriptorView =
+        dyn_cast<DirectX::RootDescriptorView>(&*ParamView);
     ASSERT_TRUE(RootDescriptorView != nullptr);
-    auto Descriptor = RootDescriptorView->read();
+    auto Descriptor = RootDescriptorView->read(RS.getVersion());
 
     ASSERT_THAT_ERROR(Descriptor.takeError(), Succeeded());
 

>From c1054581e1a9973408991e863a5e7eec51e74f04 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Sat, 26 Apr 2025 01:45:29 +0000
Subject: [PATCH 04/11] formating

---
 llvm/include/llvm/ObjectYAML/DXContainerYAML.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 8bb9da7884bed..d9d43b40db299 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -95,7 +95,7 @@ struct RootParameterYamlDesc {
   uint32_t Type;
   uint32_t Visibility;
   uint32_t Offset;
-  RootParameterYamlDesc(){};
+  RootParameterYamlDesc() {};
   RootParameterYamlDesc(uint32_t T) : Type(T) {
     switch (T) {
 

>From efe76aafee2c07e5e1df69daa404d48682ed5434 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Sat, 26 Apr 2025 02:02:53 +0000
Subject: [PATCH 05/11] try fix test

---
 llvm/lib/ObjectYAML/DXContainerYAML.cpp                    | 7 +++++--
 .../DXContainer/RootSignature-Descriptor1.0.yaml           | 2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index c9d2084226b7a..18c1299d4b867 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -39,8 +39,9 @@ DXContainerYAML::RootSignatureYamlDesc::create(
     const object::DirectX::RootSignature &Data) {
 
   RootSignatureYamlDesc RootSigDesc;
+  uint32_t Version = Data.getVersion();
 
-  RootSigDesc.Version = Data.getVersion();
+  RootSigDesc.Version = Version;
   RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers();
   RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset();
   RootSigDesc.NumRootParameters = Data.getNumRootParameters();
@@ -82,17 +83,19 @@ DXContainerYAML::RootSignatureYamlDesc::create(
     } else if (auto *RDV =
                    dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) {
       llvm::Expected<dxbc::RST0::v1::RootDescriptor> DescriptorOrErr =
-          RDV->read(Data.getVersion());
+          RDV->read(Version);
       if (Error E = DescriptorOrErr.takeError())
         return std::move(E);
       auto Descriptor = *DescriptorOrErr;
       NewP.Descriptor.ShaderRegister = Descriptor.ShaderRegister;
       NewP.Descriptor.RegisterSpace = Descriptor.RegisterSpace;
+      if (Version > 1) {
 #define ROOT_DESCRIPTOR_FLAG(Num, Val)                                         \
   NewP.Descriptor.Val =                                                        \
       (Descriptor.Flags &                                                      \
        llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
 #include "llvm/BinaryFormat/DXContainerConstants.def"
+      }
     }
 
     RootSigDesc.Parameters.push_back(NewP);
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml
index 46cdf416ffcae..889eccf74001f 100644
--- a/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-Descriptor1.0.yaml
@@ -27,7 +27,7 @@ Parts:
       AllowInputAssemblerInputLayout: true
       DenyGeometryShaderRootAccess: true
 
-# CHECK:  - Name:            RTS0
+# CHECK: - Name:            RTS0
 # CHECK-NEXT:    Size:            96
 # CHECK-NEXT:    RootSignature:
 # CHECK-NEXT:      Version: 1

>From a928e9d9a12fd1114e2c1732094ad1f32ebc196c Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Sat, 26 Apr 2025 06:33:13 +0000
Subject: [PATCH 06/11] addressing comments

---
 .../include/llvm/MC/DXContainerRootSignature.h |  3 +--
 llvm/include/llvm/ObjectYAML/DXContainerYAML.h |  2 +-
 llvm/lib/MC/DXContainerRootSignature.cpp       | 18 ++++++------------
 llvm/lib/ObjectYAML/DXContainerEmitter.cpp     | 17 ++++-------------
 4 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 1f421d726bf38..44e26c81eedc1 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -19,8 +19,7 @@ struct RootParameter {
   dxbc::RootParameterHeader Header;
   union {
     dxbc::RootConstants Constants;
-    dxbc::RST0::v0::RootDescriptor Descriptor_V10;
-    dxbc::RST0::v1::RootDescriptor Descriptor_V11;
+    dxbc::RST0::v1::RootDescriptor Descriptor;
   };
 };
 struct RootSignatureDesc {
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index d9d43b40db299..8bb9da7884bed 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -95,7 +95,7 @@ struct RootParameterYamlDesc {
   uint32_t Type;
   uint32_t Visibility;
   uint32_t Offset;
-  RootParameterYamlDesc() {};
+  RootParameterYamlDesc(){};
   RootParameterYamlDesc(uint32_t T) : Type(T) {
     switch (T) {
 
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index a5210f4768f16..2693cb9943d5e 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -92,19 +92,13 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
     case llvm::to_underlying(dxbc::RootParameterType::CBV):
     case llvm::to_underlying(dxbc::RootParameterType::SRV):
     case llvm::to_underlying(dxbc::RootParameterType::UAV):
-      if (Version == 1) {
-        support::endian::write(BOS, P.Descriptor_V10.ShaderRegister,
-                               llvm::endianness::little);
-        support::endian::write(BOS, P.Descriptor_V10.RegisterSpace,
-                               llvm::endianness::little);
-      } else {
-        support::endian::write(BOS, P.Descriptor_V11.ShaderRegister,
-                               llvm::endianness::little);
-        support::endian::write(BOS, P.Descriptor_V11.RegisterSpace,
-                               llvm::endianness::little);
-        support::endian::write(BOS, P.Descriptor_V11.Flags,
+      support::endian::write(BOS, P.Descriptor.ShaderRegister,
+                             llvm::endianness::little);
+      support::endian::write(BOS, P.Descriptor.RegisterSpace,
+                             llvm::endianness::little);
+      if (Version > 1)
+        support::endian::write(BOS, P.Descriptor.Flags,
                                llvm::endianness::little);
-      }
     }
   }
   assert(Storage.size() == getSize());
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index be0e52fef04f5..239ee9e3de9b1 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -287,19 +287,10 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
         case llvm::to_underlying(dxbc::RootParameterType::SRV):
         case llvm::to_underlying(dxbc::RootParameterType::UAV):
         case llvm::to_underlying(dxbc::RootParameterType::CBV):
-          if (RS.Version == 1) {
-            NewParam.Descriptor_V10.RegisterSpace =
-                Param.Descriptor.RegisterSpace;
-            NewParam.Descriptor_V10.ShaderRegister =
-                Param.Descriptor.ShaderRegister;
-          } else {
-            NewParam.Descriptor_V11.RegisterSpace =
-                Param.Descriptor.RegisterSpace;
-            NewParam.Descriptor_V11.ShaderRegister =
-                Param.Descriptor.ShaderRegister;
-            NewParam.Descriptor_V11.Flags = Param.Descriptor.getEncodedFlags();
-          }
-
+          NewParam.Descriptor.RegisterSpace = Param.Descriptor.RegisterSpace;
+          NewParam.Descriptor.ShaderRegister = Param.Descriptor.ShaderRegister;
+          if (P.RootSignature->Version > 1)
+            NewParam.Descriptor.Flags = Param.Descriptor.getEncodedFlags();
           break;
         }
 

>From 15eb6f50b947f59b265fd092d6a97c51e5742e6b Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Mon, 5 May 2025 18:26:14 +0000
Subject: [PATCH 07/11] fix naming

---
 llvm/include/llvm/BinaryFormat/DXContainerConstants.def | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index bd9bd760547dc..db0379b90ef6b 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -73,7 +73,7 @@ ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
 #endif // ROOT_ELEMENT_FLAG
 
  
-// ROOT_ELEMENT_FLAG(bit offset for the flag, name).
+// ROOT_DESCRIPTOR_FLAG(bit offset for the flag, name).
 #ifdef ROOT_DESCRIPTOR_FLAG
 
 ROOT_DESCRIPTOR_FLAG(0, NONE)

>From 1b3e10ab85716e194ce16c273a6091e0136bf890 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 8 May 2025 21:44:55 +0000
Subject: [PATCH 08/11] addressing comments

---
 llvm/include/llvm/BinaryFormat/DXContainer.h  | 21 ++++++++-----
 .../llvm/MC/DXContainerRootSignature.h        |  2 +-
 llvm/include/llvm/Object/DXContainer.h        | 31 +++++++++++--------
 .../include/llvm/ObjectYAML/DXContainerYAML.h |  2 +-
 llvm/lib/MC/DXContainerRootSignature.cpp      |  4 +--
 llvm/lib/ObjectYAML/DXContainerYAML.cpp       |  2 +-
 6 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 3dbcfa82f3d7c..4fbc0cf1e5954 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -585,8 +585,8 @@ struct ProgramSignatureElement {
 
 static_assert(sizeof(ProgramSignatureElement) == 32,
               "ProgramSignatureElement is misaligned");
-namespace RST0 {
-namespace v0 {
+namespace RTS0 {
+namespace v1 {
 struct RootDescriptor {
   uint32_t ShaderRegister;
   uint32_t RegisterSpace;
@@ -595,18 +595,23 @@ struct RootDescriptor {
     sys::swapByteOrder(RegisterSpace);
   }
 };
-} // namespace v0
+} // namespace v1
 
-namespace v1 {
-struct RootDescriptor : public v0::RootDescriptor {
+namespace v2 {
+struct RootDescriptor : public v1::RootDescriptor {
   uint32_t Flags;
+
+  RootDescriptor() = default;
+  RootDescriptor(v1::RootDescriptor &Base)
+      : v1::RootDescriptor(Base), Flags(0u) {}
+
   void swapBytes() {
-    v0::RootDescriptor::swapBytes();
+    v1::RootDescriptor::swapBytes();
     sys::swapByteOrder(Flags);
   }
 };
-} // namespace v1
-} // namespace RST0
+} // namespace v2
+} // namespace RTS0
 // following dx12 naming
 // https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_root_constants
 struct RootConstants {
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 44e26c81eedc1..e3c4900ba175c 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -19,7 +19,7 @@ struct RootParameter {
   dxbc::RootParameterHeader Header;
   union {
     dxbc::RootConstants Constants;
-    dxbc::RST0::v1::RootDescriptor Descriptor;
+    dxbc::RTS0::v2::RootDescriptor Descriptor;
   };
 };
 struct RootSignatureDesc {
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e359d85f08bec..f23797149d377 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Support/Error.h"
@@ -124,16 +125,13 @@ struct RootParameterView {
   RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
       : Header(H), ParamData(P) {}
 
-  template <typename T, typename VersionT = T> Expected<T> readParameter() {
-    assert(sizeof(VersionT) <= sizeof(T) &&
-           "Parameter of higher version must inherit all previous version data "
-           "members");
-    if (sizeof(VersionT) != ParamData.size())
+  template <typename T> Expected<T> readParameter() {
+    if (sizeof(T) != ParamData.size())
       return make_error<GenericBinaryError>(
           "Reading structure out of file bounds", object_error::parse_failed);
 
     T Struct;
-    memcpy(&Struct, ParamData.data(), sizeof(VersionT));
+    memcpy(&Struct, ParamData.data(), sizeof(T));
     // DXContainer is always little endian
     if (sys::IsBigEndianHost)
       Struct.swapBytes();
@@ -162,11 +160,18 @@ struct RootDescriptorView : RootParameterView {
                 llvm::to_underlying(dxbc::RootParameterType::UAV));
   }
 
-  llvm::Expected<dxbc::RST0::v1::RootDescriptor> read(uint32_t Version) {
-    if (Version == 1)
-      return readParameter<dxbc::RST0::v1::RootDescriptor,
-                           dxbc::RST0::v0::RootDescriptor>();
-    return readParameter<dxbc::RST0::v1::RootDescriptor>();
+  llvm::Expected<dxbc::RTS0::v2::RootDescriptor> read(uint32_t Version) {
+    if (Version == 1) {
+      auto Descriptor = readParameter<dxbc::RTS0::v1::RootDescriptor>();
+      if (Error E = Descriptor.takeError())
+        return E;
+      return dxbc::RTS0::v2::RootDescriptor(*Descriptor);
+    }
+    if (Version != 2)
+      return make_error<GenericBinaryError>("Invalid Root Signature version: " +
+                                                Twine(Version),
+                                            object_error::parse_failed);
+    return readParameter<dxbc::RTS0::v2::RootDescriptor>();
   }
 };
 
@@ -217,9 +222,9 @@ class RootSignature {
     case dxbc::RootParameterType::SRV:
     case dxbc::RootParameterType::UAV:
       if (Version == 1)
-        DataSize = sizeof(dxbc::RST0::v0::RootDescriptor);
+        DataSize = sizeof(dxbc::RTS0::v1::RootDescriptor);
       else
-        DataSize = sizeof(dxbc::RST0::v1::RootDescriptor);
+        DataSize = sizeof(dxbc::RTS0::v2::RootDescriptor);
       break;
     }
     size_t EndOfSectionByte = getNumStaticSamplers() == 0
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 8bb9da7884bed..d9d43b40db299 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -95,7 +95,7 @@ struct RootParameterYamlDesc {
   uint32_t Type;
   uint32_t Visibility;
   uint32_t Offset;
-  RootParameterYamlDesc(){};
+  RootParameterYamlDesc() {};
   RootParameterYamlDesc(uint32_t T) : Type(T) {
     switch (T) {
 
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index 2693cb9943d5e..161711a79e467 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -41,9 +41,9 @@ size_t RootSignatureDesc::getSize() const {
     case llvm::to_underlying(dxbc::RootParameterType::SRV):
     case llvm::to_underlying(dxbc::RootParameterType::UAV):
       if (Version == 1)
-        Size += sizeof(dxbc::RST0::v0::RootDescriptor);
+        Size += sizeof(dxbc::RTS0::v1::RootDescriptor);
       else
-        Size += sizeof(dxbc::RST0::v1::RootDescriptor);
+        Size += sizeof(dxbc::RTS0::v2::RootDescriptor);
 
       break;
     }
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 18c1299d4b867..4c681d80b3358 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -82,7 +82,7 @@ DXContainerYAML::RootSignatureYamlDesc::create(
       NewP.Constants.RegisterSpace = Constants.RegisterSpace;
     } else if (auto *RDV =
                    dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) {
-      llvm::Expected<dxbc::RST0::v1::RootDescriptor> DescriptorOrErr =
+      llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr =
           RDV->read(Version);
       if (Error E = DescriptorOrErr.takeError())
         return std::move(E);

>From 1f3195784775b3244fd6c0d7447026d290605e85 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 8 May 2025 21:48:35 +0000
Subject: [PATCH 09/11] addressing comments

---
 llvm/include/llvm/Object/DXContainer.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index f23797149d377..c93c85e638f7b 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -25,6 +25,7 @@
 #include "llvm/TargetParser/Triple.h"
 #include <array>
 #include <cstddef>
+#include <cstdint>
 #include <variant>
 
 namespace llvm {
@@ -122,8 +123,10 @@ namespace DirectX {
 struct RootParameterView {
   const dxbc::RootParameterHeader &Header;
   StringRef ParamData;
+  uint32_t Version;
+
   RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
-      : Header(H), ParamData(P) {}
+      : Header(H), ParamData(P), Version(V) {}
 
   template <typename T> Expected<T> readParameter() {
     if (sizeof(T) != ParamData.size())

>From e8fbfce6d9c761a640534e8d9ed731a5a4ac986a Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 8 May 2025 22:03:45 +0000
Subject: [PATCH 10/11] clean up

---
 llvm/include/llvm/Object/DXContainer.h         | 2 +-
 llvm/include/llvm/ObjectYAML/DXContainerYAML.h | 1 -
 llvm/lib/ObjectYAML/DXContainerYAML.cpp        | 1 -
 3 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index c93c85e638f7b..985a4b0c49e5a 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -129,11 +129,11 @@ struct RootParameterView {
       : Header(H), ParamData(P), Version(V) {}
 
   template <typename T> Expected<T> readParameter() {
+    T Struct;
     if (sizeof(T) != ParamData.size())
       return make_error<GenericBinaryError>(
           "Reading structure out of file bounds", object_error::parse_failed);
 
-    T Struct;
     memcpy(&Struct, ParamData.data(), sizeof(T));
     // DXContainer is always little endian
     if (sys::IsBigEndianHost)
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index d9d43b40db299..73532fa392520 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -21,7 +21,6 @@
 #include "llvm/ObjectYAML/YAML.h"
 #include "llvm/Support/YAMLTraits.h"
 #include <array>
-#include <cstdint>
 #include <optional>
 #include <string>
 #include <vector>
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 4c681d80b3358..8964c913946f2 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -15,7 +15,6 @@
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/BinaryFormat/DXContainer.h"
-#include "llvm/Object/DXContainer.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <cstdint>

>From a31e5a5d14a2e81a411e30e2b50150a0ba85d409 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 9 May 2025 00:10:39 +0000
Subject: [PATCH 11/11] removing v parameter

---
 llvm/include/llvm/Object/DXContainer.h | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 985a4b0c49e5a..61bfa9411cc57 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -123,10 +123,9 @@ namespace DirectX {
 struct RootParameterView {
   const dxbc::RootParameterHeader &Header;
   StringRef ParamData;
-  uint32_t Version;
 
-  RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
-      : Header(H), ParamData(P), Version(V) {}
+  RootParameterView(const dxbc::RootParameterHeader &H, StringRef P)
+      : Header(H), ParamData(P) {}
 
   template <typename T> Expected<T> readParameter() {
     T Struct;
@@ -238,7 +237,7 @@ class RootSignature {
       return parseFailed("Reading structure out of file bounds");
 
     StringRef Buff = PartData.substr(Header.ParameterOffset, DataSize);
-    RootParameterView View = RootParameterView(Version, Header, Buff);
+    RootParameterView View = RootParameterView(Header, Buff);
     return View;
   }
 };



More information about the llvm-commits mailing list