1 //===- DXContainerYAML.h - DXContainer YAMLIO implementation ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file declares classes for handling the YAML representation
11 /// of DXContainer.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_OBJECTYAML_DXCONTAINERYAML_H
16 #define LLVM_OBJECTYAML_DXCONTAINERYAML_H
17
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/BinaryFormat/DXContainer.h"
20 #include "llvm/Object/DXContainer.h"
21 #include "llvm/ObjectYAML/YAML.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/YAMLTraits.h"
24 #include <array>
25 #include <optional>
26 #include <string>
27 #include <vector>
28
29 namespace llvm {
30 namespace DXContainerYAML {
31
32 struct VersionTuple {
33 uint16_t Major;
34 uint16_t Minor;
35 };
36
37 // The optional header fields are required in the binary and will be populated
38 // when reading from binary, but can be omitted in the YAML text because the
39 // emitter can calculate them.
40 struct FileHeader {
41 std::vector<llvm::yaml::Hex8> Hash;
42 VersionTuple Version;
43 std::optional<uint32_t> FileSize;
44 uint32_t PartCount;
45 std::optional<std::vector<uint32_t>> PartOffsets;
46 };
47
48 struct DXILProgram {
49 uint8_t MajorVersion;
50 uint8_t MinorVersion;
51 uint16_t ShaderKind;
52 std::optional<uint32_t> Size;
53 uint16_t DXILMajorVersion;
54 uint16_t DXILMinorVersion;
55 std::optional<uint32_t> DXILOffset;
56 std::optional<uint32_t> DXILSize;
57 std::optional<std::vector<llvm::yaml::Hex8>> DXIL;
58 };
59
60 #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) bool Val = false;
61 struct ShaderFeatureFlags {
62 ShaderFeatureFlags() = default;
63 LLVM_ABI ShaderFeatureFlags(uint64_t FlagData);
64 LLVM_ABI uint64_t getEncodedFlags();
65 #include "llvm/BinaryFormat/DXContainerConstants.def"
66 };
67
68 struct ShaderHash {
69 ShaderHash() = default;
70 LLVM_ABI ShaderHash(const dxbc::ShaderHash &Data);
71
72 bool IncludesSource;
73 std::vector<llvm::yaml::Hex8> Digest;
74 };
75
76 struct RootConstantsYaml {
77 uint32_t ShaderRegister;
78 uint32_t RegisterSpace;
79 uint32_t Num32BitValues;
80 };
81
82 struct RootDescriptorYaml {
83 RootDescriptorYaml() = default;
84
85 uint32_t ShaderRegister;
86 uint32_t RegisterSpace;
87
88 LLVM_ABI uint32_t getEncodedFlags() const;
89
90 #define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) bool Enum = false;
91 #include "llvm/BinaryFormat/DXContainerConstants.def"
92 };
93
94 struct DescriptorRangeYaml {
95 uint32_t RangeType;
96 uint32_t NumDescriptors;
97 uint32_t BaseShaderRegister;
98 uint32_t RegisterSpace;
99 uint32_t OffsetInDescriptorsFromTableStart;
100
101 LLVM_ABI uint32_t getEncodedFlags() const;
102
103 #define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) bool Enum = false;
104 #include "llvm/BinaryFormat/DXContainerConstants.def"
105 };
106
107 struct DescriptorTableYaml {
108 uint32_t NumRanges;
109 uint32_t RangesOffset;
110 SmallVector<DescriptorRangeYaml> Ranges;
111 };
112
113 struct RootParameterHeaderYaml {
114 uint32_t Type;
115 uint32_t Visibility;
116 uint32_t Offset;
117
RootParameterHeaderYamlRootParameterHeaderYaml118 RootParameterHeaderYaml(){};
RootParameterHeaderYamlRootParameterHeaderYaml119 RootParameterHeaderYaml(uint32_t T) : Type(T) {}
120 };
121
122 struct RootParameterLocationYaml {
123 RootParameterHeaderYaml Header;
124 std::optional<size_t> IndexInSignature;
125
RootParameterLocationYamlRootParameterLocationYaml126 RootParameterLocationYaml(){};
RootParameterLocationYamlRootParameterLocationYaml127 explicit RootParameterLocationYaml(RootParameterHeaderYaml Header)
128 : Header(Header) {}
129 };
130
131 struct RootParameterYamlDesc {
132 SmallVector<RootParameterLocationYaml> Locations;
133
134 SmallVector<RootConstantsYaml> Constants;
135 SmallVector<RootDescriptorYaml> Descriptors;
136 SmallVector<DescriptorTableYaml> Tables;
137
138 template <typename T>
getOrInsertImplRootParameterYamlDesc139 T &getOrInsertImpl(RootParameterLocationYaml &ParamDesc,
140 SmallVectorImpl<T> &Container) {
141 if (!ParamDesc.IndexInSignature) {
142 ParamDesc.IndexInSignature = Container.size();
143 Container.emplace_back();
144 }
145 return Container[*ParamDesc.IndexInSignature];
146 }
147
148 RootConstantsYaml &
getOrInsertConstantsRootParameterYamlDesc149 getOrInsertConstants(RootParameterLocationYaml &ParamDesc) {
150 return getOrInsertImpl(ParamDesc, Constants);
151 }
152
153 RootDescriptorYaml &
getOrInsertDescriptorRootParameterYamlDesc154 getOrInsertDescriptor(RootParameterLocationYaml &ParamDesc) {
155 return getOrInsertImpl(ParamDesc, Descriptors);
156 }
157
getOrInsertTableRootParameterYamlDesc158 DescriptorTableYaml &getOrInsertTable(RootParameterLocationYaml &ParamDesc) {
159 return getOrInsertImpl(ParamDesc, Tables);
160 }
161
insertLocationRootParameterYamlDesc162 void insertLocation(RootParameterLocationYaml &Location) {
163 Locations.push_back(Location);
164 }
165 };
166
167 struct StaticSamplerYamlDesc {
168 uint32_t Filter = llvm::to_underlying(dxbc::SamplerFilter::Anisotropic);
169 uint32_t AddressU = llvm::to_underlying(dxbc::TextureAddressMode::Wrap);
170 uint32_t AddressV = llvm::to_underlying(dxbc::TextureAddressMode::Wrap);
171 uint32_t AddressW = llvm::to_underlying(dxbc::TextureAddressMode::Wrap);
172 float MipLODBias = 0.f;
173 uint32_t MaxAnisotropy = 16u;
174 uint32_t ComparisonFunc =
175 llvm::to_underlying(dxbc::ComparisonFunc::LessEqual);
176 uint32_t BorderColor =
177 llvm::to_underlying(dxbc::StaticBorderColor::OpaqueWhite);
178 float MinLOD = 0.f;
179 float MaxLOD = std::numeric_limits<float>::max();
180 uint32_t ShaderRegister;
181 uint32_t RegisterSpace;
182 uint32_t ShaderVisibility;
183 };
184
185 struct RootSignatureYamlDesc {
186 RootSignatureYamlDesc() = default;
187
188 uint32_t Version;
189 uint32_t NumRootParameters;
190 uint32_t RootParametersOffset;
191 uint32_t NumStaticSamplers;
192 uint32_t StaticSamplersOffset;
193
194 RootParameterYamlDesc Parameters;
195 SmallVector<StaticSamplerYamlDesc> StaticSamplers;
196
197 LLVM_ABI uint32_t getEncodedFlags();
198
samplersRootSignatureYamlDesc199 iterator_range<StaticSamplerYamlDesc *> samplers() {
200 return make_range(StaticSamplers.begin(), StaticSamplers.end());
201 }
202
203 LLVM_ABI static llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
204 create(const object::DirectX::RootSignature &Data);
205
206 #define ROOT_SIGNATURE_FLAG(Num, Val) bool Val = false;
207 #include "llvm/BinaryFormat/DXContainerConstants.def"
208 };
209
210 using ResourceFlags = dxbc::PSV::ResourceFlags;
211 using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo;
212
213 struct SignatureElement {
214 SignatureElement() = default;
215
SignatureElementSignatureElement216 SignatureElement(dxbc::PSV::v0::SignatureElement El, StringRef StringTable,
217 ArrayRef<uint32_t> IdxTable)
218 : Name(StringTable.substr(El.NameOffset,
219 StringTable.find('\0', El.NameOffset) -
220 El.NameOffset)),
221 Indices(IdxTable.slice(El.IndicesOffset, El.Rows)),
222 StartRow(El.StartRow), Cols(El.Cols), StartCol(El.StartCol),
223 Allocated(El.Allocated != 0), Kind(El.Kind), Type(El.Type),
224 Mode(El.Mode), DynamicMask(El.DynamicMask), Stream(El.Stream) {}
225 StringRef Name;
226 SmallVector<uint32_t> Indices;
227
228 uint8_t StartRow;
229 uint8_t Cols;
230 uint8_t StartCol;
231 bool Allocated;
232 dxbc::PSV::SemanticKind Kind;
233
234 dxbc::PSV::ComponentType Type;
235 dxbc::PSV::InterpolationMode Mode;
236 llvm::yaml::Hex8 DynamicMask;
237 uint8_t Stream;
238 };
239
240 struct PSVInfo {
241 // The version field isn't actually encoded in the file, but it is inferred by
242 // the size of data regions. We include it in the yaml because it simplifies
243 // the format.
244 uint32_t Version;
245
246 dxbc::PSV::v3::RuntimeInfo Info;
247 uint32_t ResourceStride;
248 SmallVector<ResourceBindInfo> Resources;
249 SmallVector<SignatureElement> SigInputElements;
250 SmallVector<SignatureElement> SigOutputElements;
251 SmallVector<SignatureElement> SigPatchOrPrimElements;
252
253 using MaskVector = SmallVector<llvm::yaml::Hex32>;
254 std::array<MaskVector, 4> OutputVectorMasks;
255 MaskVector PatchOrPrimMasks;
256 std::array<MaskVector, 4> InputOutputMap;
257 MaskVector InputPatchMap;
258 MaskVector PatchOutputMap;
259
260 StringRef EntryName;
261
262 LLVM_ABI void mapInfoForVersion(yaml::IO &IO);
263
264 LLVM_ABI PSVInfo();
265 LLVM_ABI PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P, uint16_t Stage);
266 LLVM_ABI PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P);
267 LLVM_ABI PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P);
268 LLVM_ABI PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P, StringRef StringTable);
269 };
270
271 struct SignatureParameter {
272 uint32_t Stream;
273 std::string Name;
274 uint32_t Index;
275 dxbc::D3DSystemValue SystemValue;
276 dxbc::SigComponentType CompType;
277 uint32_t Register;
278 uint8_t Mask;
279 uint8_t ExclusiveMask;
280 dxbc::SigMinPrecision MinPrecision;
281 };
282
283 struct Signature {
284 llvm::SmallVector<SignatureParameter> Parameters;
285 };
286
287 struct Part {
288 Part() = default;
PartPart289 Part(std::string N, uint32_t S) : Name(N), Size(S) {}
290 std::string Name;
291 uint32_t Size;
292 std::optional<DXILProgram> Program;
293 std::optional<ShaderFeatureFlags> Flags;
294 std::optional<ShaderHash> Hash;
295 std::optional<PSVInfo> Info;
296 std::optional<DXContainerYAML::Signature> Signature;
297 std::optional<DXContainerYAML::RootSignatureYamlDesc> RootSignature;
298 };
299
300 struct Object {
301 FileHeader Header;
302 std::vector<Part> Parts;
303 };
304
305 } // namespace DXContainerYAML
306 } // namespace llvm
307
308 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo)309 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo)
310 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement)
311 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector)
312 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter)
313 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::RootParameterLocationYaml)
314 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::DescriptorRangeYaml)
315 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::StaticSamplerYamlDesc)
316 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind)
317 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType)
318 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode)
319 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ResourceType)
320 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ResourceKind)
321 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::D3DSystemValue)
322 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigComponentType)
323 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigMinPrecision)
324
325 namespace llvm {
326
327 class raw_ostream;
328
329 namespace yaml {
330
331 template <> struct MappingTraits<DXContainerYAML::VersionTuple> {
332 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::VersionTuple &Version);
333 };
334
335 template <> struct MappingTraits<DXContainerYAML::FileHeader> {
336 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::FileHeader &Header);
337 };
338
339 template <> struct MappingTraits<DXContainerYAML::DXILProgram> {
340 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::DXILProgram &Program);
341 };
342
343 template <> struct MappingTraits<DXContainerYAML::ShaderFeatureFlags> {
344 LLVM_ABI static void mapping(IO &IO,
345 DXContainerYAML::ShaderFeatureFlags &Flags);
346 };
347
348 template <> struct MappingTraits<DXContainerYAML::ShaderHash> {
349 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ShaderHash &Hash);
350 };
351
352 template <> struct MappingTraits<DXContainerYAML::PSVInfo> {
353 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::PSVInfo &PSV);
354 };
355
356 template <> struct MappingTraits<DXContainerYAML::Part> {
357 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::Part &Version);
358 };
359
360 template <> struct MappingTraits<DXContainerYAML::Object> {
361 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::Object &Obj);
362 };
363
364 template <> struct MappingTraits<DXContainerYAML::ResourceFlags> {
365 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ResourceFlags &Flags);
366 };
367
368 template <> struct MappingTraits<DXContainerYAML::ResourceBindInfo> {
369 LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res);
370 };
371
372 template <> struct MappingTraits<DXContainerYAML::SignatureElement> {
373 LLVM_ABI static void mapping(IO &IO,
374 llvm::DXContainerYAML::SignatureElement &El);
375 };
376
377 template <> struct MappingTraits<DXContainerYAML::SignatureParameter> {
378 LLVM_ABI static void mapping(IO &IO,
379 llvm::DXContainerYAML::SignatureParameter &El);
380 };
381
382 template <> struct MappingTraits<DXContainerYAML::Signature> {
383 LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El);
384 };
385
386 template <> struct MappingTraits<DXContainerYAML::RootSignatureYamlDesc> {
387 LLVM_ABI static void
388 mapping(IO &IO, DXContainerYAML::RootSignatureYamlDesc &RootSignature);
389 };
390
391 template <>
392 struct MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
393 DXContainerYAML::RootSignatureYamlDesc> {
394 LLVM_ABI static void
395 mapping(IO &IO, llvm::DXContainerYAML::RootParameterLocationYaml &L,
396 DXContainerYAML::RootSignatureYamlDesc &S);
397 };
398
399 template <> struct MappingTraits<llvm::DXContainerYAML::RootConstantsYaml> {
400 LLVM_ABI static void mapping(IO &IO,
401 llvm::DXContainerYAML::RootConstantsYaml &C);
402 };
403
404 template <> struct MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml> {
405 LLVM_ABI static void mapping(IO &IO,
406 llvm::DXContainerYAML::RootDescriptorYaml &D);
407 };
408
409 template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml> {
410 LLVM_ABI static void mapping(IO &IO,
411 llvm::DXContainerYAML::DescriptorTableYaml &D);
412 };
413
414 template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml> {
415 LLVM_ABI static void mapping(IO &IO,
416 llvm::DXContainerYAML::DescriptorRangeYaml &D);
417 };
418
419 template <> struct MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc> {
420 LLVM_ABI static void mapping(IO &IO,
421 llvm::DXContainerYAML::StaticSamplerYamlDesc &S);
422 };
423
424 } // namespace yaml
425
426 } // namespace llvm
427
428 #endif // LLVM_OBJECTYAML_DXCONTAINERYAML_H
429