1//===- DXContainerYAML.cpp - DXContainer YAMLIO implementation ------------===//
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// This file defines classes for handling the YAML representation of
10// DXContainerYAML.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/ObjectYAML/DXContainerYAML.h"
15#include "llvm/ADT/STLForwardCompat.h"
16#include "llvm/ADT/ScopeExit.h"
17#include "llvm/BinaryFormat/DXContainer.h"
18#include "llvm/Support/Error.h"
19#include "llvm/Support/ScopedPrinter.h"
20#include <cstdint>
21#include <system_error>
22
23namespace llvm {
24
25// This assert is duplicated here to leave a breadcrumb of the places that need
26// to be updated if flags grow past 64-bits.
27static_assert((uint64_t)dxbc::FeatureFlags::NextUnusedBit <= 1ull << 63,
28 "Shader flag bits exceed enum size.");
29
30DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
31#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
32 Val = (FlagData & (uint64_t)dxbc::FeatureFlags::Val) > 0;
33#include "llvm/BinaryFormat/DXContainerConstants.def"
34}
35
36template <typename T>
37static llvm::Error
38readDescriptorRanges(DXContainerYAML::RootParameterHeaderYaml &Header,
39 DXContainerYAML::RootSignatureYamlDesc &RootSigDesc,
40 object::DirectX::DescriptorTableView *DTV) {
41
42 llvm::Expected<object::DirectX::DescriptorTable<T>> TableOrErr =
43 DTV->read<T>();
44 if (Error E = TableOrErr.takeError())
45 return E;
46 auto Table = *TableOrErr;
47
48 DXContainerYAML::RootParameterLocationYaml Location(Header);
49 DXContainerYAML::DescriptorTableYaml &TableYaml =
50 RootSigDesc.Parameters.getOrInsertTable(ParamDesc&: Location);
51 RootSigDesc.Parameters.insertLocation(Location);
52
53 TableYaml.NumRanges = Table.NumRanges;
54 TableYaml.RangesOffset = Table.RangesOffset;
55
56 for (const auto &R : Table.Ranges) {
57 DXContainerYAML::DescriptorRangeYaml NewR;
58 NewR.OffsetInDescriptorsFromTableStart =
59 R.OffsetInDescriptorsFromTableStart;
60 NewR.NumDescriptors = R.NumDescriptors;
61 NewR.BaseShaderRegister = R.BaseShaderRegister;
62 NewR.RegisterSpace = R.RegisterSpace;
63 NewR.RangeType = R.RangeType;
64 if constexpr (std::is_same_v<T, dxbc::RTS0::v2::DescriptorRange>) {
65 // Set all flag fields for v2
66#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
67 NewR.Enum = \
68 (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlags::Enum)) != 0;
69#include "llvm/BinaryFormat/DXContainerConstants.def"
70 }
71 TableYaml.Ranges.push_back(Elt: NewR);
72 }
73
74 return Error::success();
75}
76
77llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
78DXContainerYAML::RootSignatureYamlDesc::create(
79 const object::DirectX::RootSignature &Data) {
80
81 RootSignatureYamlDesc RootSigDesc;
82 uint32_t Version = Data.getVersion();
83
84 RootSigDesc.Version = Version;
85 RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers();
86 RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset();
87 RootSigDesc.NumRootParameters = Data.getNumRootParameters();
88 RootSigDesc.RootParametersOffset = Data.getRootParametersOffset();
89
90 uint32_t Flags = Data.getFlags();
91 for (const dxbc::RTS0::v1::RootParameterHeader &PH : Data.param_headers()) {
92
93 if (!dxbc::isValidParameterType(V: PH.ParameterType))
94 return createStringError(EC: std::errc::invalid_argument,
95 Fmt: "Invalid value for parameter type");
96
97 RootParameterHeaderYaml Header(PH.ParameterType);
98 Header.Offset = PH.ParameterOffset;
99 Header.Type = PH.ParameterType;
100
101 if (!dxbc::isValidShaderVisibility(V: PH.ShaderVisibility))
102 return createStringError(EC: std::errc::invalid_argument,
103 Fmt: "Invalid value for shader visibility");
104
105 Header.Visibility = PH.ShaderVisibility;
106
107 llvm::Expected<object::DirectX::RootParameterView> ParamViewOrErr =
108 Data.getParameter(Header: PH);
109 if (Error E = ParamViewOrErr.takeError())
110 return std::move(E);
111 object::DirectX::RootParameterView ParamView = ParamViewOrErr.get();
112
113 if (auto *RCV = dyn_cast<object::DirectX::RootConstantView>(Val: &ParamView)) {
114 llvm::Expected<dxbc::RTS0::v1::RootConstants> ConstantsOrErr =
115 RCV->read();
116 if (Error E = ConstantsOrErr.takeError())
117 return std::move(E);
118
119 auto Constants = *ConstantsOrErr;
120 RootParameterLocationYaml Location(Header);
121 RootConstantsYaml &ConstantYaml =
122 RootSigDesc.Parameters.getOrInsertConstants(ParamDesc&: Location);
123 RootSigDesc.Parameters.insertLocation(Location);
124 ConstantYaml.Num32BitValues = Constants.Num32BitValues;
125 ConstantYaml.ShaderRegister = Constants.ShaderRegister;
126 ConstantYaml.RegisterSpace = Constants.RegisterSpace;
127
128 } else if (auto *RDV =
129 dyn_cast<object::DirectX::RootDescriptorView>(Val: &ParamView)) {
130 llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr =
131 RDV->read(Version);
132 if (Error E = DescriptorOrErr.takeError())
133 return std::move(E);
134 auto Descriptor = *DescriptorOrErr;
135 RootParameterLocationYaml Location(Header);
136 RootDescriptorYaml &YamlDescriptor =
137 RootSigDesc.Parameters.getOrInsertDescriptor(ParamDesc&: Location);
138 RootSigDesc.Parameters.insertLocation(Location);
139
140 YamlDescriptor.ShaderRegister = Descriptor.ShaderRegister;
141 YamlDescriptor.RegisterSpace = Descriptor.RegisterSpace;
142 if (Version > 1) {
143#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
144 YamlDescriptor.Enum = \
145 (Descriptor.Flags & \
146 llvm::to_underlying(dxbc::RootDescriptorFlags::Enum)) > 0;
147#include "llvm/BinaryFormat/DXContainerConstants.def"
148 }
149 } else if (auto *DTV =
150 dyn_cast<object::DirectX::DescriptorTableView>(Val: &ParamView)) {
151 if (Version == 1) {
152 if (Error E = readDescriptorRanges<dxbc::RTS0::v1::DescriptorRange>(
153 Header, RootSigDesc, DTV))
154 return std::move(E);
155 } else if (Version == 2) {
156 if (Error E = readDescriptorRanges<dxbc::RTS0::v2::DescriptorRange>(
157 Header, RootSigDesc, DTV))
158 return std::move(E);
159 } else
160 llvm_unreachable("Unknown version for DescriptorRanges");
161 }
162 }
163
164 for (const auto &S : Data.samplers()) {
165 StaticSamplerYamlDesc NewS;
166 NewS.Filter = S.Filter;
167 NewS.AddressU = S.AddressU;
168 NewS.AddressV = S.AddressV;
169 NewS.AddressW = S.AddressW;
170 NewS.MipLODBias = S.MipLODBias;
171 NewS.MaxAnisotropy = S.MaxAnisotropy;
172 NewS.ComparisonFunc = S.ComparisonFunc;
173 NewS.BorderColor = S.BorderColor;
174 NewS.MinLOD = S.MinLOD;
175 NewS.MaxLOD = S.MaxLOD;
176 NewS.ShaderRegister = S.ShaderRegister;
177 NewS.RegisterSpace = S.RegisterSpace;
178 NewS.ShaderVisibility = S.ShaderVisibility;
179
180 RootSigDesc.StaticSamplers.push_back(Elt: NewS);
181 }
182
183#define ROOT_SIGNATURE_FLAG(Num, Val) \
184 RootSigDesc.Val = (Flags & llvm::to_underlying(dxbc::RootFlags::Val)) > 0;
185#include "llvm/BinaryFormat/DXContainerConstants.def"
186 return RootSigDesc;
187}
188
189uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const {
190 uint64_t Flags = 0;
191#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
192 if (Enum) \
193 Flags |= (uint32_t)dxbc::RootDescriptorFlags::Enum;
194#include "llvm/BinaryFormat/DXContainerConstants.def"
195 return Flags;
196}
197
198uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
199 uint64_t Flag = 0;
200#define ROOT_SIGNATURE_FLAG(Num, Val) \
201 if (Val) \
202 Flag |= (uint32_t)dxbc::RootFlags::Val;
203#include "llvm/BinaryFormat/DXContainerConstants.def"
204 return Flag;
205}
206
207uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
208 uint64_t Flags = 0;
209#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
210 if (Enum) \
211 Flags |= (uint32_t)dxbc::DescriptorRangeFlags::Enum;
212#include "llvm/BinaryFormat/DXContainerConstants.def"
213 return Flags;
214}
215
216uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
217 uint64_t Flag = 0;
218#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
219 if (Val) \
220 Flag |= (uint64_t)dxbc::FeatureFlags::Val;
221#include "llvm/BinaryFormat/DXContainerConstants.def"
222 return Flag;
223}
224
225DXContainerYAML::ShaderHash::ShaderHash(const dxbc::ShaderHash &Data)
226 : IncludesSource((Data.Flags & static_cast<uint32_t>(
227 dxbc::HashFlags::IncludesSource)) != 0),
228 Digest(16, 0) {
229 memcpy(dest: Digest.data(), src: &Data.Digest[0], n: 16);
230}
231
232DXContainerYAML::PSVInfo::PSVInfo() : Version(0) {
233 memset(s: &Info, c: 0, n: sizeof(Info));
234}
235
236DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P,
237 uint16_t Stage)
238 : Version(0) {
239 memset(s: &Info, c: 0, n: sizeof(Info));
240 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v0::RuntimeInfo));
241
242 assert(Stage < std::numeric_limits<uint8_t>::max() &&
243 "Stage should be a very small number");
244 // We need to bring the stage in separately since it isn't part of the v1 data
245 // structure.
246 Info.ShaderStage = static_cast<uint8_t>(Stage);
247}
248
249DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P)
250 : Version(1) {
251 memset(s: &Info, c: 0, n: sizeof(Info));
252 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v1::RuntimeInfo));
253}
254
255DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P)
256 : Version(2) {
257 memset(s: &Info, c: 0, n: sizeof(Info));
258 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v2::RuntimeInfo));
259}
260
261DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P,
262 StringRef StringTable)
263 : Version(3),
264 EntryName(StringTable.substr(Start: P->EntryNameOffset,
265 N: StringTable.find(C: '\0', From: P->EntryNameOffset) -
266 P->EntryNameOffset)) {
267 memset(s: &Info, c: 0, n: sizeof(Info));
268 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v3::RuntimeInfo));
269}
270
271namespace yaml {
272
273void MappingTraits<DXContainerYAML::VersionTuple>::mapping(
274 IO &IO, DXContainerYAML::VersionTuple &Version) {
275 IO.mapRequired(Key: "Major", Val&: Version.Major);
276 IO.mapRequired(Key: "Minor", Val&: Version.Minor);
277}
278
279void MappingTraits<DXContainerYAML::FileHeader>::mapping(
280 IO &IO, DXContainerYAML::FileHeader &Header) {
281 IO.mapRequired(Key: "Hash", Val&: Header.Hash);
282 IO.mapRequired(Key: "Version", Val&: Header.Version);
283 IO.mapOptional(Key: "FileSize", Val&: Header.FileSize);
284 IO.mapRequired(Key: "PartCount", Val&: Header.PartCount);
285 IO.mapOptional(Key: "PartOffsets", Val&: Header.PartOffsets);
286}
287
288void MappingTraits<DXContainerYAML::DXILProgram>::mapping(
289 IO &IO, DXContainerYAML::DXILProgram &Program) {
290 IO.mapRequired(Key: "MajorVersion", Val&: Program.MajorVersion);
291 IO.mapRequired(Key: "MinorVersion", Val&: Program.MinorVersion);
292 IO.mapRequired(Key: "ShaderKind", Val&: Program.ShaderKind);
293 IO.mapOptional(Key: "Size", Val&: Program.Size);
294 IO.mapRequired(Key: "DXILMajorVersion", Val&: Program.DXILMajorVersion);
295 IO.mapRequired(Key: "DXILMinorVersion", Val&: Program.DXILMinorVersion);
296 IO.mapOptional(Key: "DXILSize", Val&: Program.DXILSize);
297 IO.mapOptional(Key: "DXIL", Val&: Program.DXIL);
298}
299
300void MappingTraits<DXContainerYAML::ShaderFeatureFlags>::mapping(
301 IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags) {
302#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
303 IO.mapRequired(#Val, Flags.Val);
304#include "llvm/BinaryFormat/DXContainerConstants.def"
305}
306
307void MappingTraits<DXContainerYAML::ShaderHash>::mapping(
308 IO &IO, DXContainerYAML::ShaderHash &Hash) {
309 IO.mapRequired(Key: "IncludesSource", Val&: Hash.IncludesSource);
310 IO.mapRequired(Key: "Digest", Val&: Hash.Digest);
311}
312
313void MappingTraits<DXContainerYAML::PSVInfo>::mapping(
314 IO &IO, DXContainerYAML::PSVInfo &PSV) {
315 IO.mapRequired(Key: "Version", Val&: PSV.Version);
316
317 // Store the PSV version in the YAML context.
318 void *OldContext = IO.getContext();
319 uint32_t Version = PSV.Version;
320 IO.setContext(&Version);
321
322 // Restore the YAML context on function exit.
323 auto RestoreContext = make_scope_exit(F: [&]() { IO.setContext(OldContext); });
324
325 // Shader stage is only included in binaries for v1 and later, but we always
326 // include it since it simplifies parsing and file construction.
327 IO.mapRequired(Key: "ShaderStage", Val&: PSV.Info.ShaderStage);
328 PSV.mapInfoForVersion(IO);
329
330 IO.mapRequired(Key: "ResourceStride", Val&: PSV.ResourceStride);
331 IO.mapRequired(Key: "Resources", Val&: PSV.Resources);
332 if (PSV.Version == 0)
333 return;
334 IO.mapRequired(Key: "SigInputElements", Val&: PSV.SigInputElements);
335 IO.mapRequired(Key: "SigOutputElements", Val&: PSV.SigOutputElements);
336 IO.mapRequired(Key: "SigPatchOrPrimElements", Val&: PSV.SigPatchOrPrimElements);
337
338 Triple::EnvironmentType Stage = dxbc::getShaderStage(Kind: PSV.Info.ShaderStage);
339 if (PSV.Info.UsesViewID) {
340 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks(
341 PSV.OutputVectorMasks);
342 IO.mapRequired(Key: "OutputVectorMasks", Val&: MutableOutMasks);
343 if (Stage == Triple::EnvironmentType::Hull)
344 IO.mapRequired(Key: "PatchOrPrimMasks", Val&: PSV.PatchOrPrimMasks);
345 }
346 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap(
347 PSV.InputOutputMap);
348 IO.mapRequired(Key: "InputOutputMap", Val&: MutableIOMap);
349
350 if (Stage == Triple::EnvironmentType::Hull)
351 IO.mapRequired(Key: "InputPatchMap", Val&: PSV.InputPatchMap);
352
353 if (Stage == Triple::EnvironmentType::Domain)
354 IO.mapRequired(Key: "PatchOutputMap", Val&: PSV.PatchOutputMap);
355}
356
357void MappingTraits<DXContainerYAML::SignatureParameter>::mapping(
358 IO &IO, DXContainerYAML::SignatureParameter &S) {
359 IO.mapRequired(Key: "Stream", Val&: S.Stream);
360 IO.mapRequired(Key: "Name", Val&: S.Name);
361 IO.mapRequired(Key: "Index", Val&: S.Index);
362 IO.mapRequired(Key: "SystemValue", Val&: S.SystemValue);
363 IO.mapRequired(Key: "CompType", Val&: S.CompType);
364 IO.mapRequired(Key: "Register", Val&: S.Register);
365 IO.mapRequired(Key: "Mask", Val&: S.Mask);
366 IO.mapRequired(Key: "ExclusiveMask", Val&: S.ExclusiveMask);
367 IO.mapRequired(Key: "MinPrecision", Val&: S.MinPrecision);
368}
369
370void MappingTraits<DXContainerYAML::Signature>::mapping(
371 IO &IO, DXContainerYAML::Signature &S) {
372 IO.mapRequired(Key: "Parameters", Val&: S.Parameters);
373}
374
375void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
376 IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) {
377 IO.mapRequired(Key: "Version", Val&: S.Version);
378 IO.mapRequired(Key: "NumRootParameters", Val&: S.NumRootParameters);
379 IO.mapRequired(Key: "RootParametersOffset", Val&: S.RootParametersOffset);
380 IO.mapRequired(Key: "NumStaticSamplers", Val&: S.NumStaticSamplers);
381 IO.mapRequired(Key: "StaticSamplersOffset", Val&: S.StaticSamplersOffset);
382 IO.mapRequired(Key: "Parameters", Val&: S.Parameters.Locations, Ctx&: S);
383 IO.mapOptional(Key: "Samplers", Val&: S.StaticSamplers);
384#define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
385#include "llvm/BinaryFormat/DXContainerConstants.def"
386}
387
388void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
389 IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
390 IO.mapRequired(Key: "RangeType", Val&: R.RangeType);
391 // handling the edge case where NumDescriptors might be -1
392 if (IO.outputting()) {
393 if (R.NumDescriptors == UINT_MAX) {
394 int32_t NegOne = -1;
395 IO.mapRequired(Key: "NumDescriptors", Val&: NegOne);
396 } else
397 IO.mapRequired(Key: "NumDescriptors", Val&: R.NumDescriptors);
398 } else {
399 int32_t TmpNumDesc = 0;
400 IO.mapRequired(Key: "NumDescriptors", Val&: TmpNumDesc);
401 R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
402 }
403
404 IO.mapRequired(Key: "BaseShaderRegister", Val&: R.BaseShaderRegister);
405 IO.mapRequired(Key: "RegisterSpace", Val&: R.RegisterSpace);
406 IO.mapRequired(Key: "OffsetInDescriptorsFromTableStart",
407 Val&: R.OffsetInDescriptorsFromTableStart);
408#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
409 IO.mapOptional(#Flag, R.Enum, false);
410#include "llvm/BinaryFormat/DXContainerConstants.def"
411}
412
413void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
414 IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
415 IO.mapRequired(Key: "NumRanges", Val&: T.NumRanges);
416 IO.mapOptional(Key: "RangesOffset", Val&: T.RangesOffset);
417 IO.mapRequired(Key: "Ranges", Val&: T.Ranges);
418}
419
420void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
421 DXContainerYAML::RootSignatureYamlDesc>::
422 mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
423 DXContainerYAML::RootSignatureYamlDesc &S) {
424 IO.mapRequired(Key: "ParameterType", Val&: L.Header.Type);
425 IO.mapRequired(Key: "ShaderVisibility", Val&: L.Header.Visibility);
426
427 switch (L.Header.Type) {
428 case llvm::to_underlying(E: dxbc::RootParameterType::Constants32Bit): {
429 DXContainerYAML::RootConstantsYaml &Constants =
430 S.Parameters.getOrInsertConstants(ParamDesc&: L);
431 IO.mapRequired(Key: "Constants", Val&: Constants);
432 break;
433 }
434 case llvm::to_underlying(E: dxbc::RootParameterType::CBV):
435 case llvm::to_underlying(E: dxbc::RootParameterType::SRV):
436 case llvm::to_underlying(E: dxbc::RootParameterType::UAV): {
437 DXContainerYAML::RootDescriptorYaml &Descriptor =
438 S.Parameters.getOrInsertDescriptor(ParamDesc&: L);
439 IO.mapRequired(Key: "Descriptor", Val&: Descriptor);
440 break;
441 }
442 case llvm::to_underlying(E: dxbc::RootParameterType::DescriptorTable): {
443 DXContainerYAML::DescriptorTableYaml &Table =
444 S.Parameters.getOrInsertTable(ParamDesc&: L);
445 IO.mapRequired(Key: "Table", Val&: Table);
446 break;
447 }
448 }
449}
450
451void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
452 IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) {
453 IO.mapRequired(Key: "Num32BitValues", Val&: C.Num32BitValues);
454 IO.mapRequired(Key: "RegisterSpace", Val&: C.RegisterSpace);
455 IO.mapRequired(Key: "ShaderRegister", Val&: C.ShaderRegister);
456}
457
458void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
459 IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
460 IO.mapRequired(Key: "RegisterSpace", Val&: D.RegisterSpace);
461 IO.mapRequired(Key: "ShaderRegister", Val&: D.ShaderRegister);
462#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
463 IO.mapOptional(#Flag, D.Enum, false);
464#include "llvm/BinaryFormat/DXContainerConstants.def"
465}
466
467void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
468 IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {
469
470 IO.mapOptional(Key: "Filter", Val&: S.Filter);
471 IO.mapOptional(Key: "AddressU", Val&: S.AddressU);
472 IO.mapOptional(Key: "AddressV", Val&: S.AddressV);
473 IO.mapOptional(Key: "AddressW", Val&: S.AddressW);
474 IO.mapOptional(Key: "MipLODBias", Val&: S.MipLODBias);
475 IO.mapOptional(Key: "MaxAnisotropy", Val&: S.MaxAnisotropy);
476 IO.mapOptional(Key: "ComparisonFunc", Val&: S.ComparisonFunc);
477 IO.mapOptional(Key: "BorderColor", Val&: S.BorderColor);
478 IO.mapOptional(Key: "MinLOD", Val&: S.MinLOD);
479 IO.mapOptional(Key: "MaxLOD", Val&: S.MaxLOD);
480 IO.mapRequired(Key: "ShaderRegister", Val&: S.ShaderRegister);
481 IO.mapRequired(Key: "RegisterSpace", Val&: S.RegisterSpace);
482 IO.mapRequired(Key: "ShaderVisibility", Val&: S.ShaderVisibility);
483}
484
485void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
486 DXContainerYAML::Part &P) {
487 IO.mapRequired(Key: "Name", Val&: P.Name);
488 IO.mapRequired(Key: "Size", Val&: P.Size);
489 IO.mapOptional(Key: "Program", Val&: P.Program);
490 IO.mapOptional(Key: "Flags", Val&: P.Flags);
491 IO.mapOptional(Key: "Hash", Val&: P.Hash);
492 IO.mapOptional(Key: "PSVInfo", Val&: P.Info);
493 IO.mapOptional(Key: "Signature", Val&: P.Signature);
494 IO.mapOptional(Key: "RootSignature", Val&: P.RootSignature);
495}
496
497void MappingTraits<DXContainerYAML::Object>::mapping(
498 IO &IO, DXContainerYAML::Object &Obj) {
499 IO.mapTag(Tag: "!dxcontainer", Default: true);
500 IO.mapRequired(Key: "Header", Val&: Obj.Header);
501 IO.mapRequired(Key: "Parts", Val&: Obj.Parts);
502}
503
504void MappingTraits<DXContainerYAML::ResourceFlags>::mapping(
505 IO &IO, DXContainerYAML::ResourceFlags &Flags) {
506#define RESOURCE_FLAG(FlagIndex, Enum) IO.mapRequired(#Enum, Flags.Bits.Enum);
507#include "llvm/BinaryFormat/DXContainerConstants.def"
508}
509
510void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
511 IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
512 IO.mapRequired(Key: "Type", Val&: Res.Type);
513 IO.mapRequired(Key: "Space", Val&: Res.Space);
514 IO.mapRequired(Key: "LowerBound", Val&: Res.LowerBound);
515 IO.mapRequired(Key: "UpperBound", Val&: Res.UpperBound);
516
517 const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
518 if (*PSVVersion < 2)
519 return;
520
521 IO.mapRequired(Key: "Kind", Val&: Res.Kind);
522 IO.mapRequired(Key: "Flags", Val&: Res.Flags);
523}
524
525void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
526 IO &IO, DXContainerYAML::SignatureElement &El) {
527 IO.mapRequired(Key: "Name", Val&: El.Name);
528 IO.mapRequired(Key: "Indices", Val&: El.Indices);
529 IO.mapRequired(Key: "StartRow", Val&: El.StartRow);
530 IO.mapRequired(Key: "Cols", Val&: El.Cols);
531 IO.mapRequired(Key: "StartCol", Val&: El.StartCol);
532 IO.mapRequired(Key: "Allocated", Val&: El.Allocated);
533 IO.mapRequired(Key: "Kind", Val&: El.Kind);
534 IO.mapRequired(Key: "ComponentType", Val&: El.Type);
535 IO.mapRequired(Key: "Interpolation", Val&: El.Mode);
536 IO.mapRequired(Key: "DynamicMask", Val&: El.DynamicMask);
537 IO.mapRequired(Key: "Stream", Val&: El.Stream);
538}
539
540void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration(
541 IO &IO, dxbc::PSV::SemanticKind &Value) {
542 for (const auto &E : dxbc::PSV::getSemanticKinds())
543 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
544}
545
546void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration(
547 IO &IO, dxbc::PSV::ComponentType &Value) {
548 for (const auto &E : dxbc::PSV::getComponentTypes())
549 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
550}
551
552void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration(
553 IO &IO, dxbc::PSV::InterpolationMode &Value) {
554 for (const auto &E : dxbc::PSV::getInterpolationModes())
555 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
556}
557
558void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration(
559 IO &IO, dxbc::PSV::ResourceType &Value) {
560 for (const auto &E : dxbc::PSV::getResourceTypes())
561 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
562}
563
564void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration(
565 IO &IO, dxbc::PSV::ResourceKind &Value) {
566 for (const auto &E : dxbc::PSV::getResourceKinds())
567 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
568}
569
570void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration(
571 IO &IO, dxbc::D3DSystemValue &Value) {
572 for (const auto &E : dxbc::getD3DSystemValues())
573 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
574}
575
576void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration(
577 IO &IO, dxbc::SigMinPrecision &Value) {
578 for (const auto &E : dxbc::getSigMinPrecisions())
579 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
580}
581
582void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration(
583 IO &IO, dxbc::SigComponentType &Value) {
584 for (const auto &E : dxbc::getSigComponentTypes())
585 IO.enumCase(Val&: Value, Str: E.Name.str().c_str(), ConstVal: E.Value);
586}
587
588} // namespace yaml
589
590void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
591 dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo;
592 Triple::EnvironmentType Stage = dxbc::getShaderStage(Kind: Info.ShaderStage);
593
594 switch (Stage) {
595 case Triple::EnvironmentType::Pixel:
596 IO.mapRequired(Key: "DepthOutput", Val&: StageInfo.PS.DepthOutput);
597 IO.mapRequired(Key: "SampleFrequency", Val&: StageInfo.PS.SampleFrequency);
598 break;
599 case Triple::EnvironmentType::Vertex:
600 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.VS.OutputPositionPresent);
601 break;
602 case Triple::EnvironmentType::Geometry:
603 IO.mapRequired(Key: "InputPrimitive", Val&: StageInfo.GS.InputPrimitive);
604 IO.mapRequired(Key: "OutputTopology", Val&: StageInfo.GS.OutputTopology);
605 IO.mapRequired(Key: "OutputStreamMask", Val&: StageInfo.GS.OutputStreamMask);
606 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.GS.OutputPositionPresent);
607 break;
608 case Triple::EnvironmentType::Hull:
609 IO.mapRequired(Key: "InputControlPointCount",
610 Val&: StageInfo.HS.InputControlPointCount);
611 IO.mapRequired(Key: "OutputControlPointCount",
612 Val&: StageInfo.HS.OutputControlPointCount);
613 IO.mapRequired(Key: "TessellatorDomain", Val&: StageInfo.HS.TessellatorDomain);
614 IO.mapRequired(Key: "TessellatorOutputPrimitive",
615 Val&: StageInfo.HS.TessellatorOutputPrimitive);
616 break;
617 case Triple::EnvironmentType::Domain:
618 IO.mapRequired(Key: "InputControlPointCount",
619 Val&: StageInfo.DS.InputControlPointCount);
620 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.DS.OutputPositionPresent);
621 IO.mapRequired(Key: "TessellatorDomain", Val&: StageInfo.DS.TessellatorDomain);
622 break;
623 case Triple::EnvironmentType::Mesh:
624 IO.mapRequired(Key: "GroupSharedBytesUsed", Val&: StageInfo.MS.GroupSharedBytesUsed);
625 IO.mapRequired(Key: "GroupSharedBytesDependentOnViewID",
626 Val&: StageInfo.MS.GroupSharedBytesDependentOnViewID);
627 IO.mapRequired(Key: "PayloadSizeInBytes", Val&: StageInfo.MS.PayloadSizeInBytes);
628 IO.mapRequired(Key: "MaxOutputVertices", Val&: StageInfo.MS.MaxOutputVertices);
629 IO.mapRequired(Key: "MaxOutputPrimitives", Val&: StageInfo.MS.MaxOutputPrimitives);
630 break;
631 case Triple::EnvironmentType::Amplification:
632 IO.mapRequired(Key: "PayloadSizeInBytes", Val&: StageInfo.AS.PayloadSizeInBytes);
633 break;
634 default:
635 break;
636 }
637
638 IO.mapRequired(Key: "MinimumWaveLaneCount", Val&: Info.MinimumWaveLaneCount);
639 IO.mapRequired(Key: "MaximumWaveLaneCount", Val&: Info.MaximumWaveLaneCount);
640
641 if (Version == 0)
642 return;
643
644 IO.mapRequired(Key: "UsesViewID", Val&: Info.UsesViewID);
645
646 switch (Stage) {
647 case Triple::EnvironmentType::Geometry:
648 IO.mapRequired(Key: "MaxVertexCount", Val&: Info.GeomData.MaxVertexCount);
649 break;
650 case Triple::EnvironmentType::Hull:
651 case Triple::EnvironmentType::Domain:
652 IO.mapRequired(Key: "SigPatchConstOrPrimVectors",
653 Val&: Info.GeomData.SigPatchConstOrPrimVectors);
654 break;
655 case Triple::EnvironmentType::Mesh:
656 IO.mapRequired(Key: "SigPrimVectors", Val&: Info.GeomData.MeshInfo.SigPrimVectors);
657 IO.mapRequired(Key: "MeshOutputTopology",
658 Val&: Info.GeomData.MeshInfo.MeshOutputTopology);
659 break;
660 default:
661 break;
662 }
663
664 IO.mapRequired(Key: "SigInputVectors", Val&: Info.SigInputVectors);
665 MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors);
666 IO.mapRequired(Key: "SigOutputVectors", Val&: Vec);
667
668 if (Version == 1)
669 return;
670
671 IO.mapRequired(Key: "NumThreadsX", Val&: Info.NumThreadsX);
672 IO.mapRequired(Key: "NumThreadsY", Val&: Info.NumThreadsY);
673 IO.mapRequired(Key: "NumThreadsZ", Val&: Info.NumThreadsZ);
674
675 if (Version == 2)
676 return;
677
678 IO.mapRequired(Key: "EntryName", Val&: EntryName);
679}
680
681} // namespace llvm
682