Skip to content

Commit 53eae22

Browse files
joaosaffranjoaosaffran
andauthored
[DirectX] adding support in obj2yaml and yaml2obj to root constants (#127840)
Adding support for Root Constant in MC, Object and obj2yaml and yaml2obj, this PR adds: - new structures to dxbc definition. - serialize and desirialize logic from dxcontainer to yaml - tests validating against dxc - adding support to multiple parts. Closes: #126633 --------- Co-authored-by: joaosaffran <[email protected]>
1 parent 6b8d072 commit 53eae22

20 files changed

+764
-105
lines changed

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_BINARYFORMAT_DXCONTAINER_H
1515

1616
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/Support/Error.h"
1718
#include "llvm/Support/SwapByteOrder.h"
1819
#include "llvm/TargetParser/Triple.h"
1920

@@ -157,6 +158,40 @@ enum class RootElementFlag : uint32_t {
157158
#include "DXContainerConstants.def"
158159
};
159160

161+
#define ROOT_PARAMETER(Val, Enum) Enum = Val,
162+
enum class RootParameterType : uint32_t {
163+
#include "DXContainerConstants.def"
164+
};
165+
166+
ArrayRef<EnumEntry<RootParameterType>> getRootParameterTypes();
167+
168+
#define ROOT_PARAMETER(Val, Enum) \
169+
case Val: \
170+
return true;
171+
inline bool isValidParameterType(uint32_t V) {
172+
switch (V) {
173+
#include "DXContainerConstants.def"
174+
}
175+
return false;
176+
}
177+
178+
#define SHADER_VISIBILITY(Val, Enum) Enum = Val,
179+
enum class ShaderVisibility : uint32_t {
180+
#include "DXContainerConstants.def"
181+
};
182+
183+
ArrayRef<EnumEntry<ShaderVisibility>> getShaderVisibility();
184+
185+
#define SHADER_VISIBILITY(Val, Enum) \
186+
case Val: \
187+
return true;
188+
inline bool isValidShaderVisibility(uint32_t V) {
189+
switch (V) {
190+
#include "DXContainerConstants.def"
191+
}
192+
return false;
193+
}
194+
160195
PartType parsePartType(StringRef S);
161196

162197
struct VertexPSVInfo {
@@ -546,15 +581,49 @@ struct ProgramSignatureElement {
546581
static_assert(sizeof(ProgramSignatureElement) == 32,
547582
"ProgramSignatureElement is misaligned");
548583

549-
struct RootSignatureValidations {
584+
// following dx12 naming
585+
// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_root_constants
586+
struct RootConstants {
587+
uint32_t ShaderRegister;
588+
uint32_t RegisterSpace;
589+
uint32_t Num32BitValues;
590+
591+
void swapBytes() {
592+
sys::swapByteOrder(ShaderRegister);
593+
sys::swapByteOrder(RegisterSpace);
594+
sys::swapByteOrder(Num32BitValues);
595+
}
596+
};
550597

551-
static bool isValidRootFlag(uint32_t Flags) { return (Flags & ~0xfff) == 0; }
598+
struct RootParameterHeader {
599+
uint32_t ParameterType;
600+
uint32_t ShaderVisibility;
601+
uint32_t ParameterOffset;
552602

553-
static bool isValidVersion(uint32_t Version) {
554-
return (Version == 1 || Version == 2);
603+
void swapBytes() {
604+
sys::swapByteOrder(ParameterType);
605+
sys::swapByteOrder(ShaderVisibility);
606+
sys::swapByteOrder(ParameterOffset);
555607
}
556608
};
557609

610+
struct RootSignatureHeader {
611+
uint32_t Version;
612+
uint32_t NumParameters;
613+
uint32_t ParametersOffset;
614+
uint32_t NumStaticSamplers;
615+
uint32_t StaticSamplerOffset;
616+
uint32_t Flags;
617+
618+
void swapBytes() {
619+
sys::swapByteOrder(Version);
620+
sys::swapByteOrder(NumParameters);
621+
sys::swapByteOrder(ParametersOffset);
622+
sys::swapByteOrder(NumStaticSamplers);
623+
sys::swapByteOrder(StaticSamplerOffset);
624+
sys::swapByteOrder(Flags);
625+
}
626+
};
558627
} // namespace dxbc
559628
} // namespace llvm
560629

llvm/include/llvm/BinaryFormat/DXContainerConstants.def

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@ ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
7272
#undef ROOT_ELEMENT_FLAG
7373
#endif // ROOT_ELEMENT_FLAG
7474

75+
#ifdef ROOT_PARAMETER
76+
77+
ROOT_PARAMETER(1, Constants32Bit)
78+
#undef ROOT_PARAMETER
79+
#endif // ROOT_PARAMETER
80+
81+
#ifdef SHADER_VISIBILITY
82+
83+
SHADER_VISIBILITY(0, All)
84+
SHADER_VISIBILITY(1, Vertex)
85+
SHADER_VISIBILITY(2, Hull)
86+
SHADER_VISIBILITY(3, Domain)
87+
SHADER_VISIBILITY(4, Geometry)
88+
SHADER_VISIBILITY(5, Pixel)
89+
SHADER_VISIBILITY(6, Amplification)
90+
SHADER_VISIBILITY(7, Mesh)
91+
#undef SHADER_VISIBILITY
92+
#endif // SHADER_VISIBILITY
7593

7694
#ifdef DXIL_MODULE_FLAG
7795

llvm/include/llvm/MC/DXContainerRootSignature.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,33 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "llvm/BinaryFormat/DXContainer.h"
910
#include <cstdint>
1011
#include <limits>
1112

1213
namespace llvm {
1314

1415
class raw_ostream;
15-
1616
namespace mcdxbc {
17+
18+
struct RootParameter {
19+
dxbc::RootParameterHeader Header;
20+
union {
21+
dxbc::RootConstants Constants;
22+
};
23+
};
1724
struct RootSignatureDesc {
18-
uint32_t Version = 2;
19-
uint32_t NumParameters = 0;
20-
uint32_t RootParametersOffset = 0;
21-
uint32_t NumStaticSamplers = 0;
22-
uint32_t StaticSamplersOffset = 0;
23-
uint32_t Flags = 0;
25+
26+
uint32_t Version = 2U;
27+
uint32_t Flags = 0U;
28+
uint32_t RootParameterOffset = 0U;
29+
uint32_t StaticSamplersOffset = 0u;
30+
uint32_t NumStaticSamplers = 0u;
31+
SmallVector<mcdxbc::RootParameter> Parameters;
2432

2533
void write(raw_ostream &OS) const;
34+
35+
size_t getSize() const;
2636
};
2737
} // namespace mcdxbc
2838
} // namespace llvm

llvm/include/llvm/Object/DXContainer.h

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
#include "llvm/ADT/SmallVector.h"
1919
#include "llvm/ADT/StringRef.h"
2020
#include "llvm/BinaryFormat/DXContainer.h"
21+
#include "llvm/Object/Error.h"
2122
#include "llvm/Support/Error.h"
2223
#include "llvm/Support/MemoryBufferRef.h"
2324
#include "llvm/TargetParser/Triple.h"
2425
#include <array>
26+
#include <cstddef>
2527
#include <variant>
2628

2729
namespace llvm {
@@ -116,6 +118,40 @@ template <typename T> struct ViewArray {
116118
};
117119

118120
namespace DirectX {
121+
struct RootParameterView {
122+
const dxbc::RootParameterHeader &Header;
123+
StringRef ParamData;
124+
RootParameterView(const dxbc::RootParameterHeader &H, StringRef P)
125+
: Header(H), ParamData(P) {}
126+
127+
template <typename T> Expected<T> readParameter() {
128+
T Struct;
129+
if (sizeof(T) != ParamData.size())
130+
return make_error<GenericBinaryError>(
131+
"Reading structure out of file bounds", object_error::parse_failed);
132+
133+
memcpy(&Struct, ParamData.data(), sizeof(T));
134+
// DXContainer is always little endian
135+
if (sys::IsBigEndianHost)
136+
Struct.swapBytes();
137+
return Struct;
138+
}
139+
};
140+
141+
struct RootConstantView : RootParameterView {
142+
static bool classof(const RootParameterView *V) {
143+
return V->Header.ParameterType ==
144+
(uint32_t)dxbc::RootParameterType::Constants32Bit;
145+
}
146+
147+
llvm::Expected<dxbc::RootConstants> read() {
148+
return readParameter<dxbc::RootConstants>();
149+
}
150+
};
151+
152+
static Error parseFailed(const Twine &Msg) {
153+
return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
154+
}
119155

120156
class RootSignature {
121157
private:
@@ -125,17 +161,49 @@ class RootSignature {
125161
uint32_t NumStaticSamplers;
126162
uint32_t StaticSamplersOffset;
127163
uint32_t Flags;
164+
ViewArray<dxbc::RootParameterHeader> ParametersHeaders;
165+
StringRef PartData;
166+
167+
using param_header_iterator = ViewArray<dxbc::RootParameterHeader>::iterator;
128168

129169
public:
130-
RootSignature() {}
170+
RootSignature(StringRef PD) : PartData(PD) {}
131171

132-
Error parse(StringRef Data);
172+
Error parse();
133173
uint32_t getVersion() const { return Version; }
134174
uint32_t getNumParameters() const { return NumParameters; }
135175
uint32_t getRootParametersOffset() const { return RootParametersOffset; }
136176
uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
137177
uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
178+
uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
179+
llvm::iterator_range<param_header_iterator> param_headers() const {
180+
return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
181+
}
138182
uint32_t getFlags() const { return Flags; }
183+
184+
llvm::Expected<RootParameterView>
185+
getParameter(const dxbc::RootParameterHeader &Header) const {
186+
size_t DataSize;
187+
188+
if (!dxbc::isValidParameterType(Header.ParameterType))
189+
return parseFailed("invalid parameter type");
190+
191+
switch (static_cast<dxbc::RootParameterType>(Header.ParameterType)) {
192+
case dxbc::RootParameterType::Constants32Bit:
193+
DataSize = sizeof(dxbc::RootConstants);
194+
break;
195+
}
196+
size_t EndOfSectionByte = getNumStaticSamplers() == 0
197+
? PartData.size()
198+
: getStaticSamplersOffset();
199+
200+
if (Header.ParameterOffset + DataSize > EndOfSectionByte)
201+
return parseFailed("Reading structure out of file bounds");
202+
203+
StringRef Buff = PartData.substr(Header.ParameterOffset, DataSize);
204+
RootParameterView View = RootParameterView(Header, Buff);
205+
return View;
206+
}
139207
};
140208

141209
class PSVRuntimeInfo {

llvm/include/llvm/ObjectYAML/DXContainerYAML.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,43 @@ struct ShaderHash {
7474
};
7575

7676
#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
77+
78+
struct RootConstantsYaml {
79+
uint32_t ShaderRegister;
80+
uint32_t RegisterSpace;
81+
uint32_t Num32BitValues;
82+
};
83+
84+
struct RootParameterYamlDesc {
85+
uint32_t Type;
86+
uint32_t Visibility;
87+
uint32_t Offset;
88+
89+
union {
90+
RootConstantsYaml Constants;
91+
};
92+
};
93+
7794
struct RootSignatureYamlDesc {
7895
RootSignatureYamlDesc() = default;
79-
RootSignatureYamlDesc(const object::DirectX::RootSignature &Data);
8096

8197
uint32_t Version;
82-
uint32_t NumParameters;
98+
uint32_t NumRootParameters;
8399
uint32_t RootParametersOffset;
84100
uint32_t NumStaticSamplers;
85101
uint32_t StaticSamplersOffset;
86102

103+
SmallVector<RootParameterYamlDesc> Parameters;
104+
87105
uint32_t getEncodedFlags();
88106

107+
iterator_range<RootParameterYamlDesc *> params() {
108+
return make_range(Parameters.begin(), Parameters.end());
109+
}
110+
111+
static llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
112+
create(const object::DirectX::RootSignature &Data);
113+
89114
#include "llvm/BinaryFormat/DXContainerConstants.def"
90115
};
91116

@@ -192,6 +217,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo)
192217
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement)
193218
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector)
194219
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter)
220+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::RootParameterYamlDesc)
195221
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind)
196222
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType)
197223
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode)
@@ -264,6 +290,14 @@ template <> struct MappingTraits<DXContainerYAML::RootSignatureYamlDesc> {
264290
DXContainerYAML::RootSignatureYamlDesc &RootSignature);
265291
};
266292

293+
template <> struct MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc> {
294+
static void mapping(IO &IO, llvm::DXContainerYAML::RootParameterYamlDesc &P);
295+
};
296+
297+
template <> struct MappingTraits<llvm::DXContainerYAML::RootConstantsYaml> {
298+
static void mapping(IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C);
299+
};
300+
267301
} // namespace yaml
268302

269303
} // namespace llvm

llvm/lib/BinaryFormat/DXContainer.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,26 @@ ArrayRef<EnumEntry<SigComponentType>> dxbc::getSigComponentTypes() {
6060
return ArrayRef(SigComponentTypes);
6161
}
6262

63+
#define SHADER_VISIBILITY(Val, Enum) {#Enum, ShaderVisibility::Enum},
64+
65+
static const EnumEntry<ShaderVisibility> ShaderVisibilityValues[] = {
66+
#include "llvm/BinaryFormat/DXContainerConstants.def"
67+
};
68+
69+
ArrayRef<EnumEntry<ShaderVisibility>> dxbc::getShaderVisibility() {
70+
return ArrayRef(ShaderVisibilityValues);
71+
}
72+
73+
#define ROOT_PARAMETER(Val, Enum) {#Enum, RootParameterType::Enum},
74+
75+
static const EnumEntry<RootParameterType> RootParameterTypes[] = {
76+
#include "llvm/BinaryFormat/DXContainerConstants.def"
77+
};
78+
79+
ArrayRef<EnumEntry<RootParameterType>> dxbc::getRootParameterTypes() {
80+
return ArrayRef(RootParameterTypes);
81+
}
82+
6383
#define SEMANTIC_KIND(Val, Enum) {#Enum, PSV::SemanticKind::Enum},
6484

6585
static const EnumEntry<PSV::SemanticKind> SemanticKindNames[] = {

0 commit comments

Comments
 (0)