xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DXContainerYAML.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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