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 if (!dxbc::isValidRangeType(V: R.RangeType))
64 return createStringError(EC: std::errc::invalid_argument,
65 Fmt: "Invalid value for descriptor range type");
66 NewR.RangeType = dxil::ResourceClass(R.RangeType);
67 if constexpr (std::is_same_v<T, dxbc::RTS0::v2::DescriptorRange>) {
68 // Set all flag fields for v2
69#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
70 NewR.Enum = \
71 (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlags::Enum)) != 0;
72#include "llvm/BinaryFormat/DXContainerConstants.def"
73 }
74 TableYaml.Ranges.push_back(Elt: NewR);
75 }
76
77 return Error::success();
78}
79
80llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
81DXContainerYAML::RootSignatureYamlDesc::create(
82 const object::DirectX::RootSignature &Data) {
83
84 RootSignatureYamlDesc RootSigDesc;
85 uint32_t Version = Data.getVersion();
86
87 RootSigDesc.Version = Version;
88 RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers();
89 RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset();
90 RootSigDesc.NumRootParameters = Data.getNumRootParameters();
91 RootSigDesc.RootParametersOffset = Data.getRootParametersOffset();
92
93 uint32_t Flags = Data.getFlags();
94 for (const dxbc::RTS0::v1::RootParameterHeader &PH : Data.param_headers()) {
95
96 if (!dxbc::isValidParameterType(V: PH.ParameterType))
97 return createStringError(EC: std::errc::invalid_argument,
98 Fmt: "Invalid value for parameter type");
99
100 RootParameterHeaderYaml Header(dxbc::RootParameterType(PH.ParameterType));
101 Header.Offset = PH.ParameterOffset;
102
103 if (!dxbc::isValidShaderVisibility(V: PH.ShaderVisibility))
104 return createStringError(EC: std::errc::invalid_argument,
105 Fmt: "Invalid value for shader visibility");
106
107 Header.Visibility = dxbc::ShaderVisibility(PH.ShaderVisibility);
108
109 llvm::Expected<object::DirectX::RootParameterView> ParamViewOrErr =
110 Data.getParameter(Header: PH);
111 if (Error E = ParamViewOrErr.takeError())
112 return std::move(E);
113 object::DirectX::RootParameterView ParamView = ParamViewOrErr.get();
114
115 if (auto *RCV = dyn_cast<object::DirectX::RootConstantView>(Val: &ParamView)) {
116 llvm::Expected<dxbc::RTS0::v1::RootConstants> ConstantsOrErr =
117 RCV->read();
118 if (Error E = ConstantsOrErr.takeError())
119 return std::move(E);
120
121 auto Constants = *ConstantsOrErr;
122 RootParameterLocationYaml Location(Header);
123 RootConstantsYaml &ConstantYaml =
124 RootSigDesc.Parameters.getOrInsertConstants(ParamDesc&: Location);
125 RootSigDesc.Parameters.insertLocation(Location);
126 ConstantYaml.Num32BitValues = Constants.Num32BitValues;
127 ConstantYaml.ShaderRegister = Constants.ShaderRegister;
128 ConstantYaml.RegisterSpace = Constants.RegisterSpace;
129
130 } else if (auto *RDV =
131 dyn_cast<object::DirectX::RootDescriptorView>(Val: &ParamView)) {
132 llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr =
133 RDV->read(Version);
134 if (Error E = DescriptorOrErr.takeError())
135 return std::move(E);
136 auto Descriptor = *DescriptorOrErr;
137 RootParameterLocationYaml Location(Header);
138 RootDescriptorYaml &YamlDescriptor =
139 RootSigDesc.Parameters.getOrInsertDescriptor(ParamDesc&: Location);
140 RootSigDesc.Parameters.insertLocation(Location);
141
142 YamlDescriptor.ShaderRegister = Descriptor.ShaderRegister;
143 YamlDescriptor.RegisterSpace = Descriptor.RegisterSpace;
144 if (Version > 1) {
145#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
146 YamlDescriptor.Enum = \
147 (Descriptor.Flags & \
148 llvm::to_underlying(dxbc::RootDescriptorFlags::Enum)) > 0;
149#include "llvm/BinaryFormat/DXContainerConstants.def"
150 }
151 } else if (auto *DTV =
152 dyn_cast<object::DirectX::DescriptorTableView>(Val: &ParamView)) {
153 if (Version == 1) {
154 if (Error E = readDescriptorRanges<dxbc::RTS0::v1::DescriptorRange>(
155 Header, RootSigDesc, DTV))
156 return std::move(E);
157 } else if (Version == 2 || Version == 3) {
158 if (Error E = readDescriptorRanges<dxbc::RTS0::v2::DescriptorRange>(
159 Header, RootSigDesc, DTV))
160 return std::move(E);
161 } else
162 llvm_unreachable("Unknown version for DescriptorRanges");
163 }
164 }
165
166 for (const auto &S : Data.samplers()) {
167 if (!dxbc::isValidSamplerFilter(V: S.Filter))
168 return createStringError(EC: std::errc::invalid_argument,
169 Fmt: "Invalid value for static sampler filter");
170
171 if (!dxbc::isValidAddress(V: S.AddressU))
172 return createStringError(EC: std::errc::invalid_argument,
173 Fmt: "Invalid value for static sampler AddressU");
174
175 if (!dxbc::isValidAddress(V: S.AddressV))
176 return createStringError(EC: std::errc::invalid_argument,
177 Fmt: "Invalid value for static sampler AddressV");
178
179 if (!dxbc::isValidAddress(V: S.AddressW))
180 return createStringError(EC: std::errc::invalid_argument,
181 Fmt: "Invalid value for static sampler AddressW");
182
183 if (!dxbc::isValidComparisonFunc(V: S.ComparisonFunc))
184 return createStringError(
185 EC: std::errc::invalid_argument,
186 Fmt: "Invalid value for static sampler ComparisonFunc");
187
188 if (!dxbc::isValidBorderColor(V: S.BorderColor))
189 return createStringError(EC: std::errc::invalid_argument,
190 Fmt: "Invalid value for static sampler BorderColor");
191
192 if (!dxbc::isValidShaderVisibility(V: S.ShaderVisibility))
193 return createStringError(
194 EC: std::errc::invalid_argument,
195 Fmt: "Invalid value for static sampler ShaderVisibility");
196
197 StaticSamplerYamlDesc NewS;
198 NewS.Filter = dxbc::SamplerFilter(S.Filter);
199 NewS.AddressU = dxbc::TextureAddressMode(S.AddressU);
200 NewS.AddressV = dxbc::TextureAddressMode(S.AddressV);
201 NewS.AddressW = dxbc::TextureAddressMode(S.AddressW);
202 NewS.MipLODBias = S.MipLODBias;
203 NewS.MaxAnisotropy = S.MaxAnisotropy;
204 NewS.ComparisonFunc = dxbc::ComparisonFunc(S.ComparisonFunc);
205 NewS.BorderColor = dxbc::StaticBorderColor(S.BorderColor);
206 NewS.MinLOD = S.MinLOD;
207 NewS.MaxLOD = S.MaxLOD;
208 NewS.ShaderRegister = S.ShaderRegister;
209 NewS.RegisterSpace = S.RegisterSpace;
210 NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);
211
212 if (Version > 2) {
213#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
214 NewS.Enum = (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum));
215#include "llvm/BinaryFormat/DXContainerConstants.def"
216 }
217 RootSigDesc.StaticSamplers.push_back(Elt: NewS);
218 }
219
220#define ROOT_SIGNATURE_FLAG(Num, Val) \
221 RootSigDesc.Val = (Flags & llvm::to_underlying(dxbc::RootFlags::Val)) > 0;
222#include "llvm/BinaryFormat/DXContainerConstants.def"
223 return RootSigDesc;
224}
225
226uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const {
227 uint64_t Flags = 0;
228#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
229 if (Enum) \
230 Flags |= (uint32_t)dxbc::RootDescriptorFlags::Enum;
231#include "llvm/BinaryFormat/DXContainerConstants.def"
232 return Flags;
233}
234
235uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
236 uint64_t Flag = 0;
237#define ROOT_SIGNATURE_FLAG(Num, Val) \
238 if (Val) \
239 Flag |= (uint32_t)dxbc::RootFlags::Val;
240#include "llvm/BinaryFormat/DXContainerConstants.def"
241 return Flag;
242}
243
244uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
245 uint64_t Flags = 0;
246#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
247 if (Enum) \
248 Flags |= (uint32_t)dxbc::DescriptorRangeFlags::Enum;
249#include "llvm/BinaryFormat/DXContainerConstants.def"
250 return Flags;
251}
252
253uint32_t DXContainerYAML::StaticSamplerYamlDesc::getEncodedFlags() const {
254 uint64_t Flags = 0;
255#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
256 if (Enum) \
257 Flags |= (uint32_t)dxbc::StaticSamplerFlags::Enum;
258#include "llvm/BinaryFormat/DXContainerConstants.def"
259 return Flags;
260}
261
262uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
263 uint64_t Flag = 0;
264#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
265 if (Val) \
266 Flag |= (uint64_t)dxbc::FeatureFlags::Val;
267#include "llvm/BinaryFormat/DXContainerConstants.def"
268 return Flag;
269}
270
271DXContainerYAML::ShaderHash::ShaderHash(const dxbc::ShaderHash &Data)
272 : IncludesSource((Data.Flags & static_cast<uint32_t>(
273 dxbc::HashFlags::IncludesSource)) != 0),
274 Digest(16, 0) {
275 memcpy(dest: Digest.data(), src: &Data.Digest[0], n: 16);
276}
277
278DXContainerYAML::PSVInfo::PSVInfo() : Version(0) {
279 memset(s: &Info, c: 0, n: sizeof(Info));
280}
281
282DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P,
283 uint16_t Stage)
284 : Version(0) {
285 memset(s: &Info, c: 0, n: sizeof(Info));
286 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v0::RuntimeInfo));
287
288 assert(Stage < std::numeric_limits<uint8_t>::max() &&
289 "Stage should be a very small number");
290 // We need to bring the stage in separately since it isn't part of the v1 data
291 // structure.
292 Info.ShaderStage = static_cast<uint8_t>(Stage);
293}
294
295DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P)
296 : Version(1) {
297 memset(s: &Info, c: 0, n: sizeof(Info));
298 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v1::RuntimeInfo));
299}
300
301DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P)
302 : Version(2) {
303 memset(s: &Info, c: 0, n: sizeof(Info));
304 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v2::RuntimeInfo));
305}
306
307DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P,
308 StringRef StringTable)
309 : Version(3),
310 EntryName(StringTable.substr(Start: P->EntryNameOffset,
311 N: StringTable.find(C: '\0', From: P->EntryNameOffset) -
312 P->EntryNameOffset)) {
313 memset(s: &Info, c: 0, n: sizeof(Info));
314 memcpy(dest: &Info, src: P, n: sizeof(dxbc::PSV::v3::RuntimeInfo));
315}
316
317namespace yaml {
318
319void MappingTraits<DXContainerYAML::VersionTuple>::mapping(
320 IO &IO, DXContainerYAML::VersionTuple &Version) {
321 IO.mapRequired(Key: "Major", Val&: Version.Major);
322 IO.mapRequired(Key: "Minor", Val&: Version.Minor);
323}
324
325void MappingTraits<DXContainerYAML::FileHeader>::mapping(
326 IO &IO, DXContainerYAML::FileHeader &Header) {
327 IO.mapRequired(Key: "Hash", Val&: Header.Hash);
328 IO.mapRequired(Key: "Version", Val&: Header.Version);
329 IO.mapOptional(Key: "FileSize", Val&: Header.FileSize);
330 IO.mapRequired(Key: "PartCount", Val&: Header.PartCount);
331 IO.mapOptional(Key: "PartOffsets", Val&: Header.PartOffsets);
332}
333
334void MappingTraits<DXContainerYAML::DXILProgram>::mapping(
335 IO &IO, DXContainerYAML::DXILProgram &Program) {
336 IO.mapRequired(Key: "MajorVersion", Val&: Program.MajorVersion);
337 IO.mapRequired(Key: "MinorVersion", Val&: Program.MinorVersion);
338 IO.mapRequired(Key: "ShaderKind", Val&: Program.ShaderKind);
339 IO.mapOptional(Key: "Size", Val&: Program.Size);
340 IO.mapRequired(Key: "DXILMajorVersion", Val&: Program.DXILMajorVersion);
341 IO.mapRequired(Key: "DXILMinorVersion", Val&: Program.DXILMinorVersion);
342 IO.mapOptional(Key: "DXILSize", Val&: Program.DXILSize);
343 IO.mapOptional(Key: "DXIL", Val&: Program.DXIL);
344}
345
346void MappingTraits<DXContainerYAML::ShaderFeatureFlags>::mapping(
347 IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags) {
348#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
349 IO.mapRequired(#Val, Flags.Val);
350#include "llvm/BinaryFormat/DXContainerConstants.def"
351}
352
353void MappingTraits<DXContainerYAML::ShaderHash>::mapping(
354 IO &IO, DXContainerYAML::ShaderHash &Hash) {
355 IO.mapRequired(Key: "IncludesSource", Val&: Hash.IncludesSource);
356 IO.mapRequired(Key: "Digest", Val&: Hash.Digest);
357}
358
359void MappingTraits<DXContainerYAML::PSVInfo>::mapping(
360 IO &IO, DXContainerYAML::PSVInfo &PSV) {
361 IO.mapRequired(Key: "Version", Val&: PSV.Version);
362
363 // Store the PSV version in the YAML context.
364 void *OldContext = IO.getContext();
365 uint32_t Version = PSV.Version;
366 IO.setContext(&Version);
367
368 // Restore the YAML context on function exit.
369 llvm::scope_exit RestoreContext([&]() { IO.setContext(OldContext); });
370
371 // Shader stage is only included in binaries for v1 and later, but we always
372 // include it since it simplifies parsing and file construction.
373 IO.mapRequired(Key: "ShaderStage", Val&: PSV.Info.ShaderStage);
374 PSV.mapInfoForVersion(IO);
375
376 IO.mapRequired(Key: "ResourceStride", Val&: PSV.ResourceStride);
377 if (PSV.Version > 0) {
378 IO.mapOptional(Key: "RuntimeInfoSize", Val&: PSV.RuntimeInfoSize);
379 IO.mapOptional(Key: "StringTable", Val&: PSV.StringTable);
380 }
381 IO.mapRequired(Key: "Resources", Val&: PSV.Resources);
382 if (PSV.Version == 0)
383 return;
384 IO.mapRequired(Key: "SigInputElements", Val&: PSV.SigInputElements);
385 IO.mapRequired(Key: "SigOutputElements", Val&: PSV.SigOutputElements);
386 IO.mapRequired(Key: "SigPatchOrPrimElements", Val&: PSV.SigPatchOrPrimElements);
387
388 Triple::EnvironmentType Stage = dxbc::getShaderStage(Kind: PSV.Info.ShaderStage);
389 if (PSV.Info.UsesViewID) {
390 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks(
391 PSV.OutputVectorMasks);
392 IO.mapRequired(Key: "OutputVectorMasks", Val&: MutableOutMasks);
393 if (Stage == Triple::EnvironmentType::Hull)
394 IO.mapRequired(Key: "PatchOrPrimMasks", Val&: PSV.PatchOrPrimMasks);
395 }
396 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap(
397 PSV.InputOutputMap);
398 IO.mapRequired(Key: "InputOutputMap", Val&: MutableIOMap);
399
400 if (Stage == Triple::EnvironmentType::Hull)
401 IO.mapRequired(Key: "InputPatchMap", Val&: PSV.InputPatchMap);
402
403 if (Stage == Triple::EnvironmentType::Domain)
404 IO.mapRequired(Key: "PatchOutputMap", Val&: PSV.PatchOutputMap);
405}
406
407void MappingTraits<DXContainerYAML::SignatureParameter>::mapping(
408 IO &IO, DXContainerYAML::SignatureParameter &S) {
409 IO.mapRequired(Key: "Stream", Val&: S.Stream);
410 IO.mapRequired(Key: "Name", Val&: S.Name);
411 IO.mapRequired(Key: "Index", Val&: S.Index);
412 IO.mapRequired(Key: "SystemValue", Val&: S.SystemValue);
413 IO.mapRequired(Key: "CompType", Val&: S.CompType);
414 IO.mapRequired(Key: "Register", Val&: S.Register);
415 IO.mapRequired(Key: "Mask", Val&: S.Mask);
416 IO.mapRequired(Key: "ExclusiveMask", Val&: S.ExclusiveMask);
417 IO.mapRequired(Key: "MinPrecision", Val&: S.MinPrecision);
418}
419
420void MappingTraits<DXContainerYAML::Signature>::mapping(
421 IO &IO, DXContainerYAML::Signature &S) {
422 IO.mapRequired(Key: "Parameters", Val&: S.Parameters);
423}
424
425void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
426 IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) {
427 IO.mapRequired(Key: "Version", Val&: S.Version);
428 IO.mapRequired(Key: "NumRootParameters", Val&: S.NumRootParameters);
429 IO.mapOptional(Key: "RootParametersOffset", Val&: S.RootParametersOffset, Default: std::nullopt);
430 IO.mapRequired(Key: "NumStaticSamplers", Val&: S.NumStaticSamplers);
431 IO.mapOptional(Key: "StaticSamplersOffset", Val&: S.StaticSamplersOffset, Default: std::nullopt);
432 IO.mapRequired(Key: "Parameters", Val&: S.Parameters.Locations, Ctx&: S);
433 IO.mapOptional(Key: "Samplers", Val&: S.StaticSamplers);
434#define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
435#include "llvm/BinaryFormat/DXContainerConstants.def"
436}
437
438void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
439 IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
440 IO.mapRequired(Key: "RangeType", Val&: R.RangeType);
441 // handling the edge case where NumDescriptors might be -1
442 if (IO.outputting()) {
443 if (R.NumDescriptors == UINT_MAX) {
444 int32_t NegOne = -1;
445 IO.mapRequired(Key: "NumDescriptors", Val&: NegOne);
446 } else
447 IO.mapRequired(Key: "NumDescriptors", Val&: R.NumDescriptors);
448 } else {
449 int32_t TmpNumDesc = 0;
450 IO.mapRequired(Key: "NumDescriptors", Val&: TmpNumDesc);
451 R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
452 }
453
454 IO.mapRequired(Key: "BaseShaderRegister", Val&: R.BaseShaderRegister);
455 IO.mapRequired(Key: "RegisterSpace", Val&: R.RegisterSpace);
456 IO.mapRequired(Key: "OffsetInDescriptorsFromTableStart",
457 Val&: R.OffsetInDescriptorsFromTableStart);
458#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
459 IO.mapOptional(#Flag, R.Enum, false);
460#include "llvm/BinaryFormat/DXContainerConstants.def"
461}
462
463void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
464 IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
465 IO.mapRequired(Key: "NumRanges", Val&: T.NumRanges);
466 IO.mapOptional(Key: "RangesOffset", Val&: T.RangesOffset);
467 IO.mapRequired(Key: "Ranges", Val&: T.Ranges);
468}
469
470void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
471 DXContainerYAML::RootSignatureYamlDesc>::
472 mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
473 DXContainerYAML::RootSignatureYamlDesc &S) {
474 IO.mapRequired(Key: "ParameterType", Val&: L.Header.Type);
475 IO.mapRequired(Key: "ShaderVisibility", Val&: L.Header.Visibility);
476
477 switch (L.Header.Type) {
478 case dxbc::RootParameterType::Constants32Bit: {
479 DXContainerYAML::RootConstantsYaml &Constants =
480 S.Parameters.getOrInsertConstants(ParamDesc&: L);
481 IO.mapRequired(Key: "Constants", Val&: Constants);
482 break;
483 }
484 case dxbc::RootParameterType::CBV:
485 case dxbc::RootParameterType::SRV:
486 case dxbc::RootParameterType::UAV: {
487 DXContainerYAML::RootDescriptorYaml &Descriptor =
488 S.Parameters.getOrInsertDescriptor(ParamDesc&: L);
489 IO.mapRequired(Key: "Descriptor", Val&: Descriptor);
490 break;
491 }
492 case dxbc::RootParameterType::DescriptorTable: {
493 DXContainerYAML::DescriptorTableYaml &Table =
494 S.Parameters.getOrInsertTable(ParamDesc&: L);
495 IO.mapRequired(Key: "Table", Val&: Table);
496 break;
497 }
498 }
499}
500
501void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
502 IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) {
503 IO.mapRequired(Key: "Num32BitValues", Val&: C.Num32BitValues);
504 IO.mapRequired(Key: "RegisterSpace", Val&: C.RegisterSpace);
505 IO.mapRequired(Key: "ShaderRegister", Val&: C.ShaderRegister);
506}
507
508void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
509 IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
510 IO.mapRequired(Key: "RegisterSpace", Val&: D.RegisterSpace);
511 IO.mapRequired(Key: "ShaderRegister", Val&: D.ShaderRegister);
512#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
513 IO.mapOptional(#Flag, D.Enum, false);
514#include "llvm/BinaryFormat/DXContainerConstants.def"
515}
516
517void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
518 IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {
519
520 IO.mapOptional(Key: "Filter", Val&: S.Filter);
521 IO.mapOptional(Key: "AddressU", Val&: S.AddressU);
522 IO.mapOptional(Key: "AddressV", Val&: S.AddressV);
523 IO.mapOptional(Key: "AddressW", Val&: S.AddressW);
524 IO.mapOptional(Key: "MipLODBias", Val&: S.MipLODBias);
525 IO.mapOptional(Key: "MaxAnisotropy", Val&: S.MaxAnisotropy);
526 IO.mapOptional(Key: "ComparisonFunc", Val&: S.ComparisonFunc);
527 IO.mapOptional(Key: "BorderColor", Val&: S.BorderColor);
528 IO.mapOptional(Key: "MinLOD", Val&: S.MinLOD);
529 IO.mapOptional(Key: "MaxLOD", Val&: S.MaxLOD);
530 IO.mapRequired(Key: "ShaderRegister", Val&: S.ShaderRegister);
531 IO.mapRequired(Key: "RegisterSpace", Val&: S.RegisterSpace);
532 IO.mapRequired(Key: "ShaderVisibility", Val&: S.ShaderVisibility);
533#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
534 IO.mapOptional(#Flag, S.Enum, false);
535#include "llvm/BinaryFormat/DXContainerConstants.def"
536}
537
538void MappingTraits<DXContainerYAML::DebugName>::mapping(
539 IO &IO, DXContainerYAML::DebugName &DebugName) {
540 IO.mapOptional(Key: "Flags", Val&: DebugName.Flags);
541 IO.mapOptional(Key: "NameLength", Val&: DebugName.NameLength);
542 IO.mapRequired(Key: "DebugName", Val&: DebugName.Filename);
543}
544
545void MappingTraits<DXContainerYAML::CompilerVersion>::mapping(
546 IO &IO, DXContainerYAML::CompilerVersion &CompilerVersion) {
547 IO.mapOptional(Key: "Major", Val&: CompilerVersion.Major);
548 IO.mapOptional(Key: "Minor", Val&: CompilerVersion.Minor);
549 IO.mapOptional(Key: "IsDebugBuild", Val&: CompilerVersion.IsDebugBuild);
550 IO.mapOptional(Key: "IsValidated", Val&: CompilerVersion.IsValidated);
551 IO.mapOptional(Key: "CommitCount", Val&: CompilerVersion.CommitCount);
552 IO.mapOptional(Key: "ContentSizeInBytes", Val&: CompilerVersion.ContentSizeInBytes);
553 IO.mapOptional(Key: "CommitSha", Val&: CompilerVersion.CommitSha);
554 IO.mapOptional(Key: "CustomVersionString", Val&: CompilerVersion.CustomVersionString);
555}
556
557void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
558 DXContainerYAML::Part &P) {
559 IO.mapRequired(Key: "Name", Val&: P.Name);
560 IO.mapRequired(Key: "Size", Val&: P.Size);
561 IO.mapOptional(Key: "Program", Val&: P.Program);
562 IO.mapOptional(Key: "Flags", Val&: P.Flags);
563 IO.mapOptional(Key: "Hash", Val&: P.Hash);
564 IO.mapOptional(Key: "PSVInfo", Val&: P.Info);
565 IO.mapOptional(Key: "Signature", Val&: P.Signature);
566 IO.mapOptional(Key: "RootSignature", Val&: P.RootSignature);
567 IO.mapOptional(Key: "DebugName", Val&: P.DebugName);
568 IO.mapOptional(Key: "CompilerVersion", Val&: P.CompilerVersion);
569 IO.mapOptional(Key: "SourceInfo", Val&: P.SourceInfo);
570 IO.mapOptional(Key: "PrivateData", Val&: P.PrivateData);
571}
572
573void MappingTraits<DXContainerYAML::Object>::mapping(
574 IO &IO, DXContainerYAML::Object &Obj) {
575 IO.mapTag(Tag: "!dxcontainer", Default: true);
576 IO.mapRequired(Key: "Header", Val&: Obj.Header);
577 IO.mapRequired(Key: "Parts", Val&: Obj.Parts);
578}
579
580void MappingTraits<DXContainerYAML::ResourceFlags>::mapping(
581 IO &IO, DXContainerYAML::ResourceFlags &Flags) {
582#define RESOURCE_FLAG(FlagIndex, Enum) IO.mapRequired(#Enum, Flags.Bits.Enum);
583#include "llvm/BinaryFormat/DXContainerConstants.def"
584}
585
586void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
587 IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
588 IO.mapRequired(Key: "Type", Val&: Res.Type);
589 IO.mapRequired(Key: "Space", Val&: Res.Space);
590 IO.mapRequired(Key: "LowerBound", Val&: Res.LowerBound);
591 IO.mapRequired(Key: "UpperBound", Val&: Res.UpperBound);
592
593 const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
594 if (*PSVVersion < 2)
595 return;
596
597 IO.mapRequired(Key: "Kind", Val&: Res.Kind);
598 IO.mapRequired(Key: "Flags", Val&: Res.Flags);
599}
600
601void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
602 IO &IO, DXContainerYAML::SignatureElement &El) {
603 IO.mapRequired(Key: "Name", Val&: El.Name);
604 IO.mapRequired(Key: "Indices", Val&: El.Indices);
605 IO.mapRequired(Key: "StartRow", Val&: El.StartRow);
606 IO.mapRequired(Key: "Cols", Val&: El.Cols);
607 IO.mapRequired(Key: "StartCol", Val&: El.StartCol);
608 IO.mapRequired(Key: "Allocated", Val&: El.Allocated);
609 IO.mapRequired(Key: "Kind", Val&: El.Kind);
610 IO.mapRequired(Key: "ComponentType", Val&: El.Type);
611 IO.mapRequired(Key: "Interpolation", Val&: El.Mode);
612 IO.mapRequired(Key: "DynamicMask", Val&: El.DynamicMask);
613 IO.mapRequired(Key: "Stream", Val&: El.Stream);
614}
615
616void MappingTraits<DXContainerYAML::StringTableEntry>::mapping(
617 IO &IO, DXContainerYAML::StringTableEntry &E) {
618 IO.mapRequired(Key: "String", Val&: E.String);
619 IO.mapRequired(Key: "Offset", Val&: E.Offset);
620}
621
622void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration(
623 IO &IO, dxbc::PSV::SemanticKind &Value) {
624 for (const auto &E : dxbc::PSV::getSemanticKinds())
625 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
626}
627
628void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration(
629 IO &IO, dxbc::PSV::ComponentType &Value) {
630 for (const auto &E : dxbc::PSV::getComponentTypes())
631 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
632}
633
634void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration(
635 IO &IO, dxbc::PSV::InterpolationMode &Value) {
636 for (const auto &E : dxbc::PSV::getInterpolationModes())
637 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
638}
639
640void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration(
641 IO &IO, dxbc::PSV::ResourceType &Value) {
642 for (const auto &E : dxbc::PSV::getResourceTypes())
643 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
644}
645
646void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration(
647 IO &IO, dxbc::PSV::ResourceKind &Value) {
648 for (const auto &E : dxbc::PSV::getResourceKinds())
649 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
650}
651
652void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration(
653 IO &IO, dxbc::D3DSystemValue &Value) {
654 for (const auto &E : dxbc::getD3DSystemValues())
655 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
656}
657
658void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration(
659 IO &IO, dxbc::SigMinPrecision &Value) {
660 for (const auto &E : dxbc::getSigMinPrecisions())
661 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
662}
663
664void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration(
665 IO &IO, dxbc::SigComponentType &Value) {
666 for (const auto &E : dxbc::getSigComponentTypes())
667 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
668}
669
670void ScalarEnumerationTraits<dxbc::RootParameterType>::enumeration(
671 IO &IO, dxbc::RootParameterType &Value) {
672 for (const auto &E : dxbc::getRootParameterTypes())
673 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
674}
675
676void ScalarEnumerationTraits<dxil::ResourceClass>::enumeration(
677 IO &IO, dxil::ResourceClass &Value) {
678 constexpr EnumStringDef<dxil::ResourceClass> ResourceClassDefs[] = {
679 {.Names: {"CBuffer"}, .Value: dxil::ResourceClass::CBuffer},
680 {.Names: {"SRV"}, .Value: dxil::ResourceClass::SRV},
681 {.Names: {"UAV"}, .Value: dxil::ResourceClass::UAV},
682 {.Names: {"Sampler"}, .Value: dxil::ResourceClass::Sampler},
683 };
684 static constexpr auto ResourceClasses = BUILD_ENUM_STRINGS(ResourceClassDefs);
685
686 for (const auto &E : EnumStrings(ResourceClasses))
687 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
688}
689
690void ScalarEnumerationTraits<dxbc::SamplerFilter>::enumeration(
691 IO &IO, dxbc::SamplerFilter &Value) {
692 for (const auto &E : dxbc::getSamplerFilters())
693 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
694}
695
696void ScalarEnumerationTraits<dxbc::StaticBorderColor>::enumeration(
697 IO &IO, dxbc::StaticBorderColor &Value) {
698 for (const auto &E : dxbc::getStaticBorderColors())
699 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
700}
701
702void ScalarEnumerationTraits<dxbc::TextureAddressMode>::enumeration(
703 IO &IO, dxbc::TextureAddressMode &Value) {
704 for (const auto &E : dxbc::getTextureAddressModes())
705 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
706}
707
708void ScalarEnumerationTraits<dxbc::ShaderVisibility>::enumeration(
709 IO &IO, dxbc::ShaderVisibility &Value) {
710 for (const auto &E : dxbc::getShaderVisibility())
711 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
712}
713
714void ScalarEnumerationTraits<dxbc::ComparisonFunc>::enumeration(
715 IO &IO, dxbc::ComparisonFunc &Value) {
716 for (const auto &E : dxbc::getComparisonFuncs())
717 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
718}
719
720void ScalarEnumerationTraits<llvm::dxbc::SourceInfo::SectionType>::enumeration(
721 IO &IO, llvm::dxbc::SourceInfo::SectionType &Value) {
722 for (const auto &E : dxbc::SourceInfo::getSectionTypes())
723 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
724}
725
726void ScalarEnumerationTraits<
727 llvm::dxbc::SourceInfo::Contents::CompressionType>::
728 enumeration(IO &IO,
729 llvm::dxbc::SourceInfo::Contents::CompressionType &Value) {
730 for (const auto &E : dxbc::SourceInfo::Contents::getCompressionTypes())
731 IO.enumCase(Val&: Value, Str: E.name(), ConstVal: E.value());
732}
733
734void MappingTraits<llvm::DXContainerYAML::SourceInfo::Header>::mapping(
735 IO &IO, llvm::DXContainerYAML::SourceInfo::Header &H) {
736 IO.mapOptional(Key: "AlignedSizeInBytes", Val&: H.AlignedSizeInBytes);
737 IO.mapOptional(Key: "Flags", Val&: H.Flags);
738 IO.mapOptional(Key: "SectionCount", Val&: H.SectionCount);
739}
740
741void MappingTraits<llvm::DXContainerYAML::SourceInfo::SectionHeader>::mapping(
742 IO &IO, llvm::DXContainerYAML::SourceInfo::SectionHeader &H) {
743 IO.mapOptional(Key: "AlignedSizeInBytes", Val&: H.AlignedSizeInBytes);
744 IO.mapOptional(Key: "Flags", Val&: H.Flags);
745 IO.mapOptional(Key: "Type", Val&: H.Type);
746}
747
748void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames::Header>::
749 mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames::Header &H) {
750 IO.mapOptional(Key: "Flags", Val&: H.Flags);
751 IO.mapOptional(Key: "Count", Val&: H.Count);
752 IO.mapOptional(Key: "EntriesSizeInBytes", Val&: H.EntriesSizeInBytes);
753}
754
755void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames::Entry>::
756 mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames::Entry &E) {
757 IO.mapOptional(Key: "AlignedSizeInBytes", Val&: E.AlignedSizeInBytes);
758 IO.mapOptional(Key: "Flags", Val&: E.Flags);
759 IO.mapOptional(Key: "NameSizeInBytes", Val&: E.NameSizeInBytes);
760 IO.mapOptional(Key: "ContentSizeInBytes", Val&: E.ContentSizeInBytes);
761 IO.mapRequired(Key: "FileName", Val&: E.FileName);
762}
763
764void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames>::mapping(
765 IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames &S) {
766 IO.mapRequired(Key: "SectionHeader", Val&: S.GenericHeader);
767 IO.mapRequired(Key: "Header", Val&: S.Parameters);
768 IO.mapRequired(Key: "Entries", Val&: S.Entries);
769}
770
771void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents::Header>::
772 mapping(IO &IO,
773 llvm::DXContainerYAML::SourceInfo::SourceContents::Header &H) {
774 IO.mapOptional(Key: "AlignedSizeInBytes", Val&: H.AlignedSizeInBytes);
775 IO.mapOptional(Key: "Flags", Val&: H.Flags);
776 IO.mapRequired(Key: "Type", Val&: H.Type);
777 IO.mapOptional(Key: "EntriesSizeInBytes", Val&: H.EntriesSizeInBytes);
778 IO.mapOptional(Key: "UncompressedEntriesSizeInBytes",
779 Val&: H.UncompressedEntriesSizeInBytes);
780 IO.mapOptional(Key: "Count", Val&: H.Count);
781}
782
783void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents::Entry>::
784 mapping(IO &IO,
785 llvm::DXContainerYAML::SourceInfo::SourceContents::Entry &E) {
786 IO.mapOptional(Key: "AlignedSizeInBytes", Val&: E.AlignedSizeInBytes);
787 IO.mapOptional(Key: "Flags", Val&: E.Flags);
788 IO.mapOptional(Key: "ContentSizeInBytes", Val&: E.ContentSizeInBytes);
789 IO.mapRequired(Key: "FileContent", Val&: E.FileContent);
790}
791
792void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents>::mapping(
793 IO &IO, llvm::DXContainerYAML::SourceInfo::SourceContents &S) {
794 IO.mapRequired(Key: "SectionHeader", Val&: S.GenericHeader);
795 IO.mapRequired(Key: "Header", Val&: S.Parameters);
796 IO.mapRequired(Key: "Entries", Val&: S.Entries);
797}
798
799void MappingTraits<llvm::DXContainerYAML::SourceInfo::ProgramArgs::Header>::
800 mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::ProgramArgs::Header &H) {
801 IO.mapOptional(Key: "Flags", Val&: H.Flags);
802 IO.mapOptional(Key: "SizeInBytes", Val&: H.SizeInBytes);
803 IO.mapOptional(Key: "Count", Val&: H.Count);
804}
805
806void MappingTraits<mcdxbc::SourceInfo::ProgramArgs::Entry>::mapping(
807 IO &IO, mcdxbc::SourceInfo::ProgramArgs::Entry &E) {
808 IO.mapRequired(Key: "Arg", Val&: E.first);
809 IO.mapRequired(Key: "Value", Val&: E.second);
810}
811
812void MappingTraits<llvm::DXContainerYAML::SourceInfo::ProgramArgs>::mapping(
813 IO &IO, llvm::DXContainerYAML::SourceInfo::ProgramArgs &S) {
814 IO.mapRequired(Key: "SectionHeader", Val&: S.GenericHeader);
815 IO.mapRequired(Key: "Header", Val&: S.Parameters);
816 IO.mapRequired(Key: "Args", Val&: S.Args);
817}
818
819void MappingTraits<llvm::DXContainerYAML::SourceInfo>::mapping(
820 IO &IO, llvm::DXContainerYAML::SourceInfo &S) {
821 IO.mapRequired(Key: "Header", Val&: S.Parameters);
822 IO.mapRequired(Key: "Names", Val&: S.Names);
823 IO.mapRequired(Key: "Contents", Val&: S.Contents);
824 IO.mapRequired(Key: "Args", Val&: S.Args);
825}
826
827} // namespace yaml
828
829void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
830 dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo;
831 Triple::EnvironmentType Stage = dxbc::getShaderStage(Kind: Info.ShaderStage);
832
833 switch (Stage) {
834 case Triple::EnvironmentType::Pixel:
835 IO.mapRequired(Key: "DepthOutput", Val&: StageInfo.PS.DepthOutput);
836 IO.mapRequired(Key: "SampleFrequency", Val&: StageInfo.PS.SampleFrequency);
837 break;
838 case Triple::EnvironmentType::Vertex:
839 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.VS.OutputPositionPresent);
840 break;
841 case Triple::EnvironmentType::Geometry:
842 IO.mapRequired(Key: "InputPrimitive", Val&: StageInfo.GS.InputPrimitive);
843 IO.mapRequired(Key: "OutputTopology", Val&: StageInfo.GS.OutputTopology);
844 IO.mapRequired(Key: "OutputStreamMask", Val&: StageInfo.GS.OutputStreamMask);
845 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.GS.OutputPositionPresent);
846 break;
847 case Triple::EnvironmentType::Hull:
848 IO.mapRequired(Key: "InputControlPointCount",
849 Val&: StageInfo.HS.InputControlPointCount);
850 IO.mapRequired(Key: "OutputControlPointCount",
851 Val&: StageInfo.HS.OutputControlPointCount);
852 IO.mapRequired(Key: "TessellatorDomain", Val&: StageInfo.HS.TessellatorDomain);
853 IO.mapRequired(Key: "TessellatorOutputPrimitive",
854 Val&: StageInfo.HS.TessellatorOutputPrimitive);
855 break;
856 case Triple::EnvironmentType::Domain:
857 IO.mapRequired(Key: "InputControlPointCount",
858 Val&: StageInfo.DS.InputControlPointCount);
859 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.DS.OutputPositionPresent);
860 IO.mapRequired(Key: "TessellatorDomain", Val&: StageInfo.DS.TessellatorDomain);
861 break;
862 case Triple::EnvironmentType::Mesh:
863 IO.mapRequired(Key: "GroupSharedBytesUsed", Val&: StageInfo.MS.GroupSharedBytesUsed);
864 IO.mapRequired(Key: "GroupSharedBytesDependentOnViewID",
865 Val&: StageInfo.MS.GroupSharedBytesDependentOnViewID);
866 IO.mapRequired(Key: "PayloadSizeInBytes", Val&: StageInfo.MS.PayloadSizeInBytes);
867 IO.mapRequired(Key: "MaxOutputVertices", Val&: StageInfo.MS.MaxOutputVertices);
868 IO.mapRequired(Key: "MaxOutputPrimitives", Val&: StageInfo.MS.MaxOutputPrimitives);
869 break;
870 case Triple::EnvironmentType::Amplification:
871 IO.mapRequired(Key: "PayloadSizeInBytes", Val&: StageInfo.AS.PayloadSizeInBytes);
872 break;
873 default:
874 break;
875 }
876
877 IO.mapRequired(Key: "MinimumWaveLaneCount", Val&: Info.MinimumWaveLaneCount);
878 IO.mapRequired(Key: "MaximumWaveLaneCount", Val&: Info.MaximumWaveLaneCount);
879
880 if (Version == 0)
881 return;
882
883 IO.mapRequired(Key: "UsesViewID", Val&: Info.UsesViewID);
884
885 switch (Stage) {
886 case Triple::EnvironmentType::Geometry:
887 IO.mapRequired(Key: "MaxVertexCount", Val&: Info.GeomData.MaxVertexCount);
888 break;
889 case Triple::EnvironmentType::Hull:
890 case Triple::EnvironmentType::Domain:
891 IO.mapRequired(Key: "SigPatchConstOrPrimVectors",
892 Val&: Info.GeomData.SigPatchConstOrPrimVectors);
893 break;
894 case Triple::EnvironmentType::Mesh:
895 IO.mapRequired(Key: "SigPrimVectors", Val&: Info.GeomData.MeshInfo.SigPrimVectors);
896 IO.mapRequired(Key: "MeshOutputTopology",
897 Val&: Info.GeomData.MeshInfo.MeshOutputTopology);
898 break;
899 default:
900 break;
901 }
902
903 IO.mapRequired(Key: "SigInputVectors", Val&: Info.SigInputVectors);
904 MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors);
905 IO.mapRequired(Key: "SigOutputVectors", Val&: Vec);
906
907 if (Version == 1)
908 return;
909
910 IO.mapRequired(Key: "NumThreadsX", Val&: Info.NumThreadsX);
911 IO.mapRequired(Key: "NumThreadsY", Val&: Info.NumThreadsY);
912 IO.mapRequired(Key: "NumThreadsZ", Val&: Info.NumThreadsZ);
913
914 if (Version == 2)
915 return;
916
917 IO.mapRequired(Key: "EntryName", Val&: EntryName);
918}
919
920static DXContainerYAML::Signature
921dumpSignature(const object::DirectX::Signature &Sig) {
922 DXContainerYAML::Signature YAML;
923 for (auto Param : Sig)
924 YAML.Parameters.push_back(Elt: DXContainerYAML::SignatureParameter{
925 .Stream: Param.Stream, .Name: Sig.getName(Offset: Param.NameOffset).str(), .Index: Param.Index,
926 .SystemValue: Param.SystemValue, .CompType: Param.CompType, .Register: Param.Register, .Mask: Param.Mask,
927 .ExclusiveMask: Param.ExclusiveMask, .MinPrecision: Param.MinPrecision});
928 return YAML;
929}
930
931static void assign(DXContainerYAML::SourceInfo::SectionHeader &Dst,
932 const dxbc::SourceInfo::SectionHeader &Src) {
933 Dst.AlignedSizeInBytes = Src.AlignedSizeInBytes;
934 Dst.Flags = Src.Flags;
935 Dst.Type = Src.Type;
936}
937
938Expected<std::unique_ptr<DXContainerYAML::Object>>
939DXContainerYAML::fromDXContainer(object::DXContainer &Container) {
940 std::unique_ptr<DXContainerYAML::Object> Obj =
941 std::make_unique<DXContainerYAML::Object>();
942
943 for (uint8_t Byte : Container.getHeader().FileHash.Digest)
944 Obj->Header.Hash.push_back(x: Byte);
945 Obj->Header.Version.Major = Container.getHeader().Version.Major;
946 Obj->Header.Version.Minor = Container.getHeader().Version.Minor;
947 Obj->Header.FileSize = Container.getHeader().FileSize;
948 Obj->Header.PartCount = Container.getHeader().PartCount;
949
950 Obj->Header.PartOffsets = std::vector<uint32_t>();
951 for (const auto P : Container) {
952 Obj->Header.PartOffsets->push_back(x: P.Offset);
953 Obj->Parts.push_back(
954 x: DXContainerYAML::Part(P.Part.getName().str(), P.Part.Size));
955 DXContainerYAML::Part &NewPart = Obj->Parts.back();
956 dxbc::PartType PT = dxbc::parsePartType(S: P.Part.getName());
957 switch (PT) {
958 case dxbc::PartType::DXIL:
959 case dxbc::PartType::ILDB: {
960 std::optional<object::DXContainer::DXILData> DXIL =
961 Container.getDXIL(Debug: dxbc::isDebugProgramPart(PT));
962 assert(DXIL && "Since we are iterating and found a DXIL/ILDB part, "
963 "this should never not have a value");
964 NewPart.Program = DXContainerYAML::DXILProgram{
965 .MajorVersion: DXIL->first.getMajorVersion(),
966 .MinorVersion: DXIL->first.getMinorVersion(),
967 .ShaderKind: DXIL->first.ShaderKind,
968 .Size: DXIL->first.Size,
969 .DXILMajorVersion: DXIL->first.Bitcode.MajorVersion,
970 .DXILMinorVersion: DXIL->first.Bitcode.MinorVersion,
971 .DXILOffset: DXIL->first.Bitcode.Offset,
972 .DXILSize: DXIL->first.Bitcode.Size,
973 .DXIL: std::vector<llvm::yaml::Hex8>(
974 DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)};
975 break;
976 }
977 case dxbc::PartType::ILDN: {
978 std::optional<mcdxbc::DebugName> DebugName = Container.getDebugName();
979 assert(DebugName && "Since we are iterating and found a ILDN part, this "
980 "should never not have a value");
981 NewPart.DebugName = DXContainerYAML::DebugName{
982 .Flags: DebugName->Parameters.Flags, .NameLength: DebugName->Parameters.NameLength,
983 .Filename: DebugName->Filename.str()};
984 break;
985 }
986 case dxbc::PartType::PRIV: {
987 std::optional<StringRef> PrivateData = Container.getPrivateData();
988 assert(PrivateData && "Since we are iterating and found a PRIV part, "
989 "this should never not have a value");
990 NewPart.PrivateData.emplace(args: PrivateData->data(),
991 args: PrivateData->data() + PrivateData->size());
992 break;
993 }
994 case dxbc::PartType::SFI0: {
995 std::optional<uint64_t> Flags = Container.getShaderFeatureFlags();
996 // Omit the flags in the YAML if they are missing or zero.
997 if (Flags && *Flags > 0)
998 NewPart.Flags = DXContainerYAML::ShaderFeatureFlags(*Flags);
999 break;
1000 }
1001 case dxbc::PartType::HASH: {
1002 std::optional<dxbc::ShaderHash> Hash = Container.getShaderHash();
1003 if (Hash && Hash->isPopulated())
1004 NewPart.Hash = DXContainerYAML::ShaderHash(*Hash);
1005 break;
1006 }
1007 case dxbc::PartType::PSV0: {
1008 const auto &PSVInfo = Container.getPSVInfo();
1009 if (!PSVInfo)
1010 break;
1011 if (const auto *P =
1012 std::get_if<dxbc::PSV::v0::RuntimeInfo>(ptr: &PSVInfo->getInfo())) {
1013 std::optional<uint16_t> ShaderKind = Container.getShaderKind();
1014 if (!ShaderKind)
1015 break;
1016 NewPart.Info = DXContainerYAML::PSVInfo(P, *ShaderKind);
1017 } else if (const auto *P = std::get_if<dxbc::PSV::v1::RuntimeInfo>(
1018 ptr: &PSVInfo->getInfo()))
1019 NewPart.Info = DXContainerYAML::PSVInfo(P);
1020 else if (const auto *P =
1021 std::get_if<dxbc::PSV::v2::RuntimeInfo>(ptr: &PSVInfo->getInfo()))
1022 NewPart.Info = DXContainerYAML::PSVInfo(P);
1023 else if (const auto *P =
1024 std::get_if<dxbc::PSV::v3::RuntimeInfo>(ptr: &PSVInfo->getInfo()))
1025 NewPart.Info = DXContainerYAML::PSVInfo(P, PSVInfo->getStringTable());
1026 NewPart.Info->ResourceStride = PSVInfo->getResourceStride();
1027 NewPart.Info->RuntimeInfoSize = PSVInfo->getSize();
1028 if (PSVInfo->getVersion() > 0) {
1029 StringRef ST = PSVInfo->getStringTable();
1030 size_t Pos = 0;
1031 while (Pos < ST.size()) {
1032 size_t End = ST.find(C: '\0', From: Pos);
1033 if (End == StringRef::npos)
1034 End = ST.size();
1035 if (End > Pos)
1036 NewPart.Info->StringTable.push_back(
1037 Elt: {.String: ST.slice(Start: Pos, End), .Offset: static_cast<uint32_t>(Pos)});
1038 Pos = End + 1;
1039 }
1040 }
1041 for (auto Res : PSVInfo->getResources())
1042 NewPart.Info->Resources.push_back(Elt: Res);
1043
1044 for (auto El : PSVInfo->getSigInputElements())
1045 NewPart.Info->SigInputElements.push_back(
1046 Elt: DXContainerYAML::SignatureElement(
1047 El, PSVInfo->getStringTable(),
1048 PSVInfo->getSemanticIndexTable()));
1049 for (auto El : PSVInfo->getSigOutputElements())
1050 NewPart.Info->SigOutputElements.push_back(
1051 Elt: DXContainerYAML::SignatureElement(
1052 El, PSVInfo->getStringTable(),
1053 PSVInfo->getSemanticIndexTable()));
1054 for (auto El : PSVInfo->getSigPatchOrPrimElements())
1055 NewPart.Info->SigPatchOrPrimElements.push_back(
1056 Elt: DXContainerYAML::SignatureElement(
1057 El, PSVInfo->getStringTable(),
1058 PSVInfo->getSemanticIndexTable()));
1059
1060 if (PSVInfo->usesViewID()) {
1061 for (int I = 0; I < 4; ++I)
1062 for (auto Mask : PSVInfo->getOutputVectorMasks(Idx: I))
1063 NewPart.Info->OutputVectorMasks[I].push_back(Elt: Mask);
1064 for (auto Mask : PSVInfo->getPatchOrPrimMasks())
1065 NewPart.Info->PatchOrPrimMasks.push_back(Elt: Mask);
1066 }
1067
1068 for (int I = 0; I < 4; ++I)
1069 for (auto Mask : PSVInfo->getInputOutputMap(Idx: I))
1070 NewPart.Info->InputOutputMap[I].push_back(Elt: Mask);
1071
1072 for (auto Mask : PSVInfo->getInputPatchMap())
1073 NewPart.Info->InputPatchMap.push_back(Elt: Mask);
1074
1075 for (auto Mask : PSVInfo->getPatchOutputMap())
1076 NewPart.Info->PatchOutputMap.push_back(Elt: Mask);
1077
1078 break;
1079 }
1080 case dxbc::PartType::ISG1:
1081 NewPart.Signature = dumpSignature(Sig: Container.getInputSignature());
1082 break;
1083 case dxbc::PartType::OSG1:
1084 NewPart.Signature = dumpSignature(Sig: Container.getOutputSignature());
1085 break;
1086 case dxbc::PartType::PSG1:
1087 NewPart.Signature = dumpSignature(Sig: Container.getPatchConstantSignature());
1088 break;
1089 case dxbc::PartType::Unknown:
1090 break;
1091 case dxbc::PartType::RTS0: {
1092 std::optional<object::DirectX::RootSignature> RS =
1093 Container.getRootSignature();
1094 if (RS.has_value()) {
1095 auto RootSigDescOrErr =
1096 DXContainerYAML::RootSignatureYamlDesc::create(Data: *RS);
1097 if (Error E = RootSigDescOrErr.takeError())
1098 return std::move(E);
1099 NewPart.RootSignature = RootSigDescOrErr.get();
1100 }
1101 break;
1102 }
1103 case dxbc::PartType::SRCI: {
1104 std::optional<mcdxbc::SourceInfo> SourceInfo = Container.getSourceInfo();
1105 assert(SourceInfo && "Since we are iterating and found a SRCI part, this "
1106 "should never not have a value");
1107 auto &SourceInfoYAML = NewPart.SourceInfo.emplace();
1108 SourceInfoYAML.Parameters.AlignedSizeInBytes =
1109 SourceInfo->Parameters.AlignedSizeInBytes;
1110 SourceInfoYAML.Parameters.Flags = SourceInfo->Parameters.Flags;
1111 SourceInfoYAML.Parameters.SectionCount =
1112 SourceInfo->Parameters.SectionCount;
1113
1114 auto &NamesYAML = SourceInfoYAML.Names;
1115 auto &Names = SourceInfo->Names;
1116 assign(Dst&: NamesYAML.GenericHeader, Src: SourceInfo->Names.GenericHeader);
1117 NamesYAML.Parameters.Flags = Names.Parameters.Flags;
1118 NamesYAML.Parameters.Count = Names.Parameters.Count;
1119 NamesYAML.Parameters.EntriesSizeInBytes =
1120 Names.Parameters.EntriesSizeInBytes;
1121 NamesYAML.Entries.reserve(N: Names.Entries.size());
1122 for (const auto &NameEntry : Names.Entries) {
1123 DXContainerYAML::SourceInfo::SourceNames::Entry NameEntryYAML;
1124 NameEntryYAML.AlignedSizeInBytes =
1125 NameEntry.Parameters.AlignedSizeInBytes;
1126 NameEntryYAML.Flags = NameEntry.Parameters.Flags;
1127 NameEntryYAML.NameSizeInBytes = NameEntry.Parameters.NameSizeInBytes;
1128 NameEntryYAML.ContentSizeInBytes =
1129 NameEntry.Parameters.ContentSizeInBytes;
1130 NameEntryYAML.FileName = NameEntry.FileName;
1131 NamesYAML.Entries.emplace_back(Args&: NameEntryYAML);
1132 }
1133
1134 auto &ContentsYAML = SourceInfoYAML.Contents;
1135 auto &Contents = SourceInfo->Contents;
1136 assign(Dst&: ContentsYAML.GenericHeader, Src: Contents.GenericHeader);
1137 ContentsYAML.Parameters.AlignedSizeInBytes =
1138 Contents.Parameters.AlignedSizeInBytes;
1139 ContentsYAML.Parameters.Flags = Contents.Parameters.Flags;
1140 ContentsYAML.Parameters.Type = Contents.Parameters.Type;
1141 ContentsYAML.Parameters.EntriesSizeInBytes =
1142 Contents.Parameters.EntriesSizeInBytes;
1143 ContentsYAML.Parameters.UncompressedEntriesSizeInBytes =
1144 Contents.Parameters.UncompressedEntriesSizeInBytes;
1145 ContentsYAML.Parameters.Count = Contents.Parameters.Count;
1146 ContentsYAML.Entries.reserve(N: Contents.Entries.size());
1147 for (const auto &ContentEntry : Contents.Entries) {
1148 DXContainerYAML::SourceInfo::SourceContents::Entry ContentEntryYAML;
1149 ContentEntryYAML.AlignedSizeInBytes =
1150 ContentEntry.Parameters.AlignedSizeInBytes;
1151 ContentEntryYAML.Flags = ContentEntry.Parameters.Flags;
1152 ContentEntryYAML.ContentSizeInBytes =
1153 ContentEntry.Parameters.ContentSizeInBytes;
1154 ContentEntryYAML.FileContent = ContentEntry.FileContent;
1155 ContentsYAML.Entries.emplace_back(Args&: ContentEntryYAML);
1156 }
1157
1158 auto &ArgsYAML = SourceInfoYAML.Args;
1159 auto &Args = SourceInfo->Args;
1160 assign(Dst&: ArgsYAML.GenericHeader, Src: Args.GenericHeader);
1161 ArgsYAML.Parameters.Flags = Args.Parameters.Flags;
1162 ArgsYAML.Parameters.SizeInBytes = Args.Parameters.SizeInBytes;
1163 ArgsYAML.Parameters.Count = Args.Parameters.Count;
1164 ArgsYAML.Args = Args.Args;
1165 break;
1166 }
1167 case dxbc::PartType::VERS: {
1168 std::optional<mcdxbc::CompilerVersion> Version =
1169 Container.getCompilerVersionInfo();
1170 assert(Version && "Since we are iterating and found a VERS part, this "
1171 "should never not have a value");
1172 NewPart.CompilerVersion.emplace(args: DXContainerYAML::CompilerVersion{
1173 .Major: Version->Parameters.Major, .Minor: Version->Parameters.Minor,
1174 .IsDebugBuild: !!(Version->Parameters.Flags & dxbc::CompilerVersionFlags::Debug),
1175 .IsValidated: !!(Version->Parameters.Flags & dxbc::CompilerVersionFlags::Internal),
1176 .CommitCount: Version->Parameters.CommitCount,
1177 .ContentSizeInBytes: Version->Parameters.ContentSizeInBytes, .CommitSha: Version->CommitSha.str(),
1178 .CustomVersionString: Version->CustomVersionString.str()});
1179 break;
1180 }
1181 }
1182 }
1183 return std::move(Obj);
1184}
1185
1186} // namespace llvm
1187