-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[DirectX] Adding support for Root Descriptors in obj2yaml/yaml2obj #137259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-directx Author: None (joaosaffran) Changescloses: 126634 Patch is 30.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137259.diff 13 Files Affected:
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/RootSignat...
[truncated]
|
@llvm/pr-subscribers-objectyaml Author: None (joaosaffran) Changescloses: 126634 Patch is 30.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137259.diff 13 Files Affected:
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/RootSignat...
[truncated]
|
@llvm/pr-subscribers-llvm-binary-utilities Author: None (joaosaffran) Changescloses: 126634 Patch is 30.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137259.diff 13 Files Affected:
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/RootSignat...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- llvm/include/llvm/BinaryFormat/DXContainer.h llvm/include/llvm/MC/DXContainerRootSignature.h llvm/include/llvm/Object/DXContainer.h llvm/include/llvm/ObjectYAML/DXContainerYAML.h llvm/lib/MC/DXContainerRootSignature.cpp llvm/lib/ObjectYAML/DXContainerEmitter.cpp llvm/lib/ObjectYAML/DXContainerYAML.cpp llvm/unittests/Object/DXContainerTest.cpp llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp View the diff from clang-format here.diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 8bb9da788..d9d43b40d 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) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits and then just thinking out loud, maybe we are now able to collapse the versioned view structs into one?
If we adjust readParameter
to only copy the first elements of the struct depending on version then it might be more easily extensible. Just putting an idea out there though.
}; | ||
}; | ||
|
||
#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think it is more clear to have the define right above the include it is used by (same with above)
@@ -580,7 +585,28 @@ struct ProgramSignatureElement { | |||
|
|||
static_assert(sizeof(ProgramSignatureElement) == 32, | |||
"ProgramSignatureElement is misaligned"); | |||
namespace RST0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think we can either remove this name space, or, we should have all the defined structs within it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but I will do it in a follow-up PR. I want to avoid noise for reviewers
dxbc::RST0::v0::RootDescriptor Descriptor_V10; | ||
dxbc::RST0::v1::RootDescriptor Descriptor_V11; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dxbc::RST0::v0::RootDescriptor Descriptor_V10; | |
dxbc::RST0::v1::RootDescriptor Descriptor_V11; | |
dxbc::RST0::v1::RootDescriptor Descriptor; |
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() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
template <typename T> Expected<T> readParameter() { | |
template <typename T, typename VersionT = T> Expected<T> readParameter() { | |
assert(sizeof(VersiontT) <= sizeof(T) && "Parameter of higher version must inherit all previous version data members"); |
and then below we would just copy the relevant data members:
memcpy(&Struct, ParamData.data(), sizeof(VersionT))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion, thanks
@@ -149,6 +150,38 @@ struct RootConstantView : RootParameterView { | |||
} | |||
}; | |||
|
|||
struct RootDescriptorView_V1_0 : RootParameterView { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, this was meant to be in the last review batch. But if we have one struct we could do something like this?
struct RootDescriptorView_V1_0 : RootParameterView { | |
struct RootDescriptorView : RootParameterView { | |
llvm::Expected<dxbc::RST0::v1::RootDescriptor> read(uint32_t Version) { | |
if (Version == 0) | |
return readParameter<dxbc::RST0::v1::RootDescriptor, dxbc::RST0::v0::RootDescriptor>(); | |
return readParameter<dxbc::RST0::v1::RootDescriptor>(); | |
} |
@@ -121,16 +121,19 @@ namespace DirectX { | |||
struct RootParameterView { | |||
const dxbc::RootParameterHeader &Header; | |||
StringRef ParamData; | |||
RootParameterView(const dxbc::RootParameterHeader &H, StringRef P) | |||
RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is V
used anywhere? What does the V
stand for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is used in RootDescriptorView
, it stands for Version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like other constructors have V
stand for "View".
But regardless, it is literally unused:
RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
: Header(H), ParamData(P) {}
RootDescriptorView does have a Version passed to its read method. But this V passed to the RootParameterView constructor is not used.
T Struct; | ||
memcpy(&Struct, ParamData.data(), sizeof(VersionT)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting pretty lost trying to read this and understand what T vs VersionT is meant to mean.
But it looks like we expect VersionT to be smaller than T. Which means that this memcpy won't overwrite everything in T, which means that the rest of it is uninitialized?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are correct.
@@ -580,7 +585,28 @@ struct ProgramSignatureElement { | |||
|
|||
static_assert(sizeof(ProgramSignatureElement) == 32, | |||
"ProgramSignatureElement is misaligned"); | |||
namespace RST0 { | |||
namespace v0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the v0 namespace corresponds to Version 1, and the v1 namespace is Version 2?
Any reason not to use the same numbering scheme for the versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems worthwhile to make the naming consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be good to get this addressed, but I'm fine with it in a different PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my biggest issue with this PR is the use of inheritance for the two RootDescriptor structs. The style of declaring the Child struct everywhere when it is sometimes the Base struct goes against normal style, and misleads the reader. This also leads to sometimes not fully initializing the Child struct using memcpy, leaving garbage in the uninitialized field.
Since in this style you are checking the version everywhere, you could write this code in a way which assumes the Base class and checks for the child class.
See example of what I mean: https://godbolt.org/z/6GnbGarz5
Also please add a description to the PR
@@ -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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this meant to say ROOT_DESCRIPTOR_FLAG?
@@ -580,7 +585,28 @@ struct ProgramSignatureElement { | |||
|
|||
static_assert(sizeof(ProgramSignatureElement) == 32, | |||
"ProgramSignatureElement is misaligned"); | |||
namespace RST0 { | |||
namespace v0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems worthwhile to make the naming consistent.
@@ -580,7 +585,28 @@ struct ProgramSignatureElement { | |||
|
|||
static_assert(sizeof(ProgramSignatureElement) == 32, | |||
"ProgramSignatureElement is misaligned"); | |||
namespace RST0 { | |||
namespace v0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use namespaces to distinguish these structs and not give them different names like 'RootDescriptorV1' and 'RootDescriptorV2'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is following the same pattern established in other parts of DXContainer, such as:
struct RuntimeInfo { |
My understating for this original decision is, newer versions of DXContainer are superset of previous versions, meaning, they add new fields, structs and flags, don't remove nor modify existing definition.
closes: 126634