Skip to content

Commit 03d3e6d

Browse files
joaosaffranjoaosaffran
and
joaosaffran
authored
[DirectX] Adding support for Root Descriptors in obj2yaml/yaml2obj (#137259)
closes: [126634](#126634) --------- Co-authored-by: joaosaffran <[email protected]>
1 parent e4751d5 commit 03d3e6d

13 files changed

+487
-11
lines changed

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ enum class RootElementFlag : uint32_t {
158158
#include "DXContainerConstants.def"
159159
};
160160

161+
#define ROOT_DESCRIPTOR_FLAG(Num, Val) Val = 1ull << Num,
162+
enum class RootDescriptorFlag : uint32_t {
163+
#include "DXContainerConstants.def"
164+
};
165+
161166
#define ROOT_PARAMETER(Val, Enum) Enum = Val,
162167
enum class RootParameterType : uint32_t {
163168
#include "DXContainerConstants.def"
@@ -580,7 +585,33 @@ struct ProgramSignatureElement {
580585

581586
static_assert(sizeof(ProgramSignatureElement) == 32,
582587
"ProgramSignatureElement is misaligned");
588+
namespace RTS0 {
589+
namespace v1 {
590+
struct RootDescriptor {
591+
uint32_t ShaderRegister;
592+
uint32_t RegisterSpace;
593+
void swapBytes() {
594+
sys::swapByteOrder(ShaderRegister);
595+
sys::swapByteOrder(RegisterSpace);
596+
}
597+
};
598+
} // namespace v1
599+
600+
namespace v2 {
601+
struct RootDescriptor : public v1::RootDescriptor {
602+
uint32_t Flags;
603+
604+
RootDescriptor() = default;
605+
RootDescriptor(v1::RootDescriptor &Base)
606+
: v1::RootDescriptor(Base), Flags(0u) {}
583607

608+
void swapBytes() {
609+
v1::RootDescriptor::swapBytes();
610+
sys::swapByteOrder(Flags);
611+
}
612+
};
613+
} // namespace v2
614+
} // namespace RTS0
584615
// following dx12 naming
585616
// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_root_constants
586617
struct RootConstants {

llvm/include/llvm/BinaryFormat/DXContainerConstants.def

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,24 @@ ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
7474
#undef ROOT_ELEMENT_FLAG
7575
#endif // ROOT_ELEMENT_FLAG
7676

77+
78+
// ROOT_DESCRIPTOR_FLAG(bit offset for the flag, name).
79+
#ifdef ROOT_DESCRIPTOR_FLAG
80+
81+
ROOT_DESCRIPTOR_FLAG(0, NONE)
82+
ROOT_DESCRIPTOR_FLAG(1, DATA_VOLATILE)
83+
ROOT_DESCRIPTOR_FLAG(2, DATA_STATIC_WHILE_SET_AT_EXECUTE)
84+
ROOT_DESCRIPTOR_FLAG(3, DATA_STATIC)
85+
#undef ROOT_DESCRIPTOR_FLAG
86+
#endif // ROOT_DESCRIPTOR_FLAG
87+
88+
7789
#ifdef ROOT_PARAMETER
7890

7991
ROOT_PARAMETER(1, Constants32Bit)
92+
ROOT_PARAMETER(2, CBV)
93+
ROOT_PARAMETER(3, SRV)
94+
ROOT_PARAMETER(4, UAV)
8095
#undef ROOT_PARAMETER
8196
#endif // ROOT_PARAMETER
8297

llvm/include/llvm/MC/DXContainerRootSignature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct RootParameter {
1919
dxbc::RootParameterHeader Header;
2020
union {
2121
dxbc::RootConstants Constants;
22+
dxbc::RTS0::v2::RootDescriptor Descriptor;
2223
};
2324
};
2425
struct RootSignatureDesc {

llvm/include/llvm/Object/DXContainer.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717

1818
#include "llvm/ADT/SmallVector.h"
1919
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/ADT/Twine.h"
2021
#include "llvm/BinaryFormat/DXContainer.h"
2122
#include "llvm/Object/Error.h"
2223
#include "llvm/Support/Error.h"
2324
#include "llvm/Support/MemoryBufferRef.h"
2425
#include "llvm/TargetParser/Triple.h"
2526
#include <array>
2627
#include <cstddef>
28+
#include <cstdint>
2729
#include <variant>
2830

2931
namespace llvm {
@@ -121,6 +123,7 @@ namespace DirectX {
121123
struct RootParameterView {
122124
const dxbc::RootParameterHeader &Header;
123125
StringRef ParamData;
126+
124127
RootParameterView(const dxbc::RootParameterHeader &H, StringRef P)
125128
: Header(H), ParamData(P) {}
126129

@@ -149,6 +152,31 @@ struct RootConstantView : RootParameterView {
149152
}
150153
};
151154

155+
struct RootDescriptorView : RootParameterView {
156+
static bool classof(const RootParameterView *V) {
157+
return (V->Header.ParameterType ==
158+
llvm::to_underlying(dxbc::RootParameterType::CBV) ||
159+
V->Header.ParameterType ==
160+
llvm::to_underlying(dxbc::RootParameterType::SRV) ||
161+
V->Header.ParameterType ==
162+
llvm::to_underlying(dxbc::RootParameterType::UAV));
163+
}
164+
165+
llvm::Expected<dxbc::RTS0::v2::RootDescriptor> read(uint32_t Version) {
166+
if (Version == 1) {
167+
auto Descriptor = readParameter<dxbc::RTS0::v1::RootDescriptor>();
168+
if (Error E = Descriptor.takeError())
169+
return E;
170+
return dxbc::RTS0::v2::RootDescriptor(*Descriptor);
171+
}
172+
if (Version != 2)
173+
return make_error<GenericBinaryError>("Invalid Root Signature version: " +
174+
Twine(Version),
175+
object_error::parse_failed);
176+
return readParameter<dxbc::RTS0::v2::RootDescriptor>();
177+
}
178+
};
179+
152180
static Error parseFailed(const Twine &Msg) {
153181
return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
154182
}
@@ -192,6 +220,14 @@ class RootSignature {
192220
case dxbc::RootParameterType::Constants32Bit:
193221
DataSize = sizeof(dxbc::RootConstants);
194222
break;
223+
case dxbc::RootParameterType::CBV:
224+
case dxbc::RootParameterType::SRV:
225+
case dxbc::RootParameterType::UAV:
226+
if (Version == 1)
227+
DataSize = sizeof(dxbc::RTS0::v1::RootDescriptor);
228+
else
229+
DataSize = sizeof(dxbc::RTS0::v2::RootDescriptor);
230+
break;
195231
}
196232
size_t EndOfSectionByte = getNumStaticSamplers() == 0
197233
? PartData.size()

llvm/include/llvm/ObjectYAML/DXContainerYAML.h

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "llvm/ObjectYAML/YAML.h"
2222
#include "llvm/Support/YAMLTraits.h"
2323
#include <array>
24-
#include <cstdint>
2524
#include <optional>
2625
#include <string>
2726
#include <vector>
@@ -73,21 +72,46 @@ struct ShaderHash {
7372
std::vector<llvm::yaml::Hex8> Digest;
7473
};
7574

76-
#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
77-
7875
struct RootConstantsYaml {
7976
uint32_t ShaderRegister;
8077
uint32_t RegisterSpace;
8178
uint32_t Num32BitValues;
8279
};
8380

81+
struct RootDescriptorYaml {
82+
RootDescriptorYaml() = default;
83+
84+
uint32_t ShaderRegister;
85+
uint32_t RegisterSpace;
86+
87+
uint32_t getEncodedFlags() const;
88+
89+
#define ROOT_DESCRIPTOR_FLAG(Num, Val) bool Val = false;
90+
#include "llvm/BinaryFormat/DXContainerConstants.def"
91+
};
92+
8493
struct RootParameterYamlDesc {
8594
uint32_t Type;
8695
uint32_t Visibility;
8796
uint32_t Offset;
97+
RootParameterYamlDesc() {};
98+
RootParameterYamlDesc(uint32_t T) : Type(T) {
99+
switch (T) {
100+
101+
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
102+
Constants = RootConstantsYaml();
103+
break;
104+
case llvm::to_underlying(dxbc::RootParameterType::CBV):
105+
case llvm::to_underlying(dxbc::RootParameterType::SRV):
106+
case llvm::to_underlying(dxbc::RootParameterType::UAV):
107+
Descriptor = RootDescriptorYaml();
108+
break;
109+
}
110+
}
88111

89112
union {
90113
RootConstantsYaml Constants;
114+
RootDescriptorYaml Descriptor;
91115
};
92116
};
93117

@@ -111,6 +135,7 @@ struct RootSignatureYamlDesc {
111135
static llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
112136
create(const object::DirectX::RootSignature &Data);
113137

138+
#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
114139
#include "llvm/BinaryFormat/DXContainerConstants.def"
115140
};
116141

@@ -298,6 +323,10 @@ template <> struct MappingTraits<llvm::DXContainerYAML::RootConstantsYaml> {
298323
static void mapping(IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C);
299324
};
300325

326+
template <> struct MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml> {
327+
static void mapping(IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D);
328+
};
329+
301330
} // namespace yaml
302331

303332
} // namespace llvm

llvm/lib/MC/DXContainerRootSignature.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ size_t RootSignatureDesc::getSize() const {
3737
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
3838
Size += sizeof(dxbc::RootConstants);
3939
break;
40+
case llvm::to_underlying(dxbc::RootParameterType::CBV):
41+
case llvm::to_underlying(dxbc::RootParameterType::SRV):
42+
case llvm::to_underlying(dxbc::RootParameterType::UAV):
43+
if (Version == 1)
44+
Size += sizeof(dxbc::RTS0::v1::RootDescriptor);
45+
else
46+
Size += sizeof(dxbc::RTS0::v2::RootDescriptor);
47+
48+
break;
4049
}
4150
}
4251
return Size;
@@ -80,6 +89,16 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
8089
support::endian::write(BOS, P.Constants.Num32BitValues,
8190
llvm::endianness::little);
8291
break;
92+
case llvm::to_underlying(dxbc::RootParameterType::CBV):
93+
case llvm::to_underlying(dxbc::RootParameterType::SRV):
94+
case llvm::to_underlying(dxbc::RootParameterType::UAV):
95+
support::endian::write(BOS, P.Descriptor.ShaderRegister,
96+
llvm::endianness::little);
97+
support::endian::write(BOS, P.Descriptor.RegisterSpace,
98+
llvm::endianness::little);
99+
if (Version > 1)
100+
support::endian::write(BOS, P.Descriptor.Flags,
101+
llvm::endianness::little);
83102
}
84103
}
85104
assert(Storage.size() == getSize());

llvm/lib/ObjectYAML/DXContainerEmitter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,14 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
284284
NewParam.Constants.RegisterSpace = Param.Constants.RegisterSpace;
285285
NewParam.Constants.ShaderRegister = Param.Constants.ShaderRegister;
286286
break;
287+
case llvm::to_underlying(dxbc::RootParameterType::SRV):
288+
case llvm::to_underlying(dxbc::RootParameterType::UAV):
289+
case llvm::to_underlying(dxbc::RootParameterType::CBV):
290+
NewParam.Descriptor.RegisterSpace = Param.Descriptor.RegisterSpace;
291+
NewParam.Descriptor.ShaderRegister = Param.Descriptor.ShaderRegister;
292+
if (P.RootSignature->Version > 1)
293+
NewParam.Descriptor.Flags = Param.Descriptor.getEncodedFlags();
294+
break;
287295
}
288296

289297
RS.Parameters.push_back(NewParam);

llvm/lib/ObjectYAML/DXContainerYAML.cpp

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ DXContainerYAML::RootSignatureYamlDesc::create(
3838
const object::DirectX::RootSignature &Data) {
3939

4040
RootSignatureYamlDesc RootSigDesc;
41+
uint32_t Version = Data.getVersion();
4142

42-
RootSigDesc.Version = Data.getVersion();
43+
RootSigDesc.Version = Version;
4344
RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers();
4445
RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset();
4546
RootSigDesc.NumRootParameters = Data.getNumRootParameters();
@@ -48,13 +49,12 @@ DXContainerYAML::RootSignatureYamlDesc::create(
4849
uint32_t Flags = Data.getFlags();
4950
for (const dxbc::RootParameterHeader &PH : Data.param_headers()) {
5051

51-
RootParameterYamlDesc NewP;
52-
NewP.Offset = PH.ParameterOffset;
53-
5452
if (!dxbc::isValidParameterType(PH.ParameterType))
5553
return createStringError(std::errc::invalid_argument,
5654
"Invalid value for parameter type");
5755

56+
RootParameterYamlDesc NewP(PH.ParameterType);
57+
NewP.Offset = PH.ParameterOffset;
5858
NewP.Type = PH.ParameterType;
5959

6060
if (!dxbc::isValidShaderVisibility(PH.ShaderVisibility))
@@ -79,7 +79,24 @@ DXContainerYAML::RootSignatureYamlDesc::create(
7979
NewP.Constants.Num32BitValues = Constants.Num32BitValues;
8080
NewP.Constants.ShaderRegister = Constants.ShaderRegister;
8181
NewP.Constants.RegisterSpace = Constants.RegisterSpace;
82+
} else if (auto *RDV =
83+
dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) {
84+
llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr =
85+
RDV->read(Version);
86+
if (Error E = DescriptorOrErr.takeError())
87+
return std::move(E);
88+
auto Descriptor = *DescriptorOrErr;
89+
NewP.Descriptor.ShaderRegister = Descriptor.ShaderRegister;
90+
NewP.Descriptor.RegisterSpace = Descriptor.RegisterSpace;
91+
if (Version > 1) {
92+
#define ROOT_DESCRIPTOR_FLAG(Num, Val) \
93+
NewP.Descriptor.Val = \
94+
(Descriptor.Flags & \
95+
llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
96+
#include "llvm/BinaryFormat/DXContainerConstants.def"
97+
}
8298
}
99+
83100
RootSigDesc.Parameters.push_back(NewP);
84101
}
85102
#define ROOT_ELEMENT_FLAG(Num, Val) \
@@ -89,6 +106,15 @@ DXContainerYAML::RootSignatureYamlDesc::create(
89106
return RootSigDesc;
90107
}
91108

109+
uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const {
110+
uint64_t Flag = 0;
111+
#define ROOT_DESCRIPTOR_FLAG(Num, Val) \
112+
if (Val) \
113+
Flag |= (uint32_t)dxbc::RootDescriptorFlag::Val;
114+
#include "llvm/BinaryFormat/DXContainerConstants.def"
115+
return Flag;
116+
}
117+
92118
uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
93119
uint64_t Flag = 0;
94120
#define ROOT_ELEMENT_FLAG(Num, Val) \
@@ -276,6 +302,14 @@ void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
276302
IO.mapRequired("ShaderRegister", C.ShaderRegister);
277303
}
278304

305+
void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
306+
IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
307+
IO.mapRequired("RegisterSpace", D.RegisterSpace);
308+
IO.mapRequired("ShaderRegister", D.ShaderRegister);
309+
#define ROOT_DESCRIPTOR_FLAG(Num, Val) IO.mapOptional(#Val, D.Val, false);
310+
#include "llvm/BinaryFormat/DXContainerConstants.def"
311+
}
312+
279313
void MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc>::mapping(
280314
IO &IO, llvm::DXContainerYAML::RootParameterYamlDesc &P) {
281315
IO.mapRequired("ParameterType", P.Type);
@@ -285,6 +319,11 @@ void MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc>::mapping(
285319
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
286320
IO.mapRequired("Constants", P.Constants);
287321
break;
322+
case llvm::to_underlying(dxbc::RootParameterType::CBV):
323+
case llvm::to_underlying(dxbc::RootParameterType::SRV):
324+
case llvm::to_underlying(dxbc::RootParameterType::UAV):
325+
IO.mapRequired("Descriptor", P.Descriptor);
326+
break;
288327
}
289328
}
290329

0 commit comments

Comments
 (0)