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 IO.mapRequired(Key: "Resources", Val&: PSV.Resources);
378 if (PSV.Version == 0)
379 return;
380 IO.mapRequired(Key: "SigInputElements", Val&: PSV.SigInputElements);
381 IO.mapRequired(Key: "SigOutputElements", Val&: PSV.SigOutputElements);
382 IO.mapRequired(Key: "SigPatchOrPrimElements", Val&: PSV.SigPatchOrPrimElements);
383
384 Triple::EnvironmentType Stage = dxbc::getShaderStage(Kind: PSV.Info.ShaderStage);
385 if (PSV.Info.UsesViewID) {
386 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks(
387 PSV.OutputVectorMasks);
388 IO.mapRequired(Key: "OutputVectorMasks", Val&: MutableOutMasks);
389 if (Stage == Triple::EnvironmentType::Hull)
390 IO.mapRequired(Key: "PatchOrPrimMasks", Val&: PSV.PatchOrPrimMasks);
391 }
392 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap(
393 PSV.InputOutputMap);
394 IO.mapRequired(Key: "InputOutputMap", Val&: MutableIOMap);
395
396 if (Stage == Triple::EnvironmentType::Hull)
397 IO.mapRequired(Key: "InputPatchMap", Val&: PSV.InputPatchMap);
398
399 if (Stage == Triple::EnvironmentType::Domain)
400 IO.mapRequired(Key: "PatchOutputMap", Val&: PSV.PatchOutputMap);
401}
402
403void MappingTraits<DXContainerYAML::SignatureParameter>::mapping(
404 IO &IO, DXContainerYAML::SignatureParameter &S) {
405 IO.mapRequired(Key: "Stream", Val&: S.Stream);
406 IO.mapRequired(Key: "Name", Val&: S.Name);
407 IO.mapRequired(Key: "Index", Val&: S.Index);
408 IO.mapRequired(Key: "SystemValue", Val&: S.SystemValue);
409 IO.mapRequired(Key: "CompType", Val&: S.CompType);
410 IO.mapRequired(Key: "Register", Val&: S.Register);
411 IO.mapRequired(Key: "Mask", Val&: S.Mask);
412 IO.mapRequired(Key: "ExclusiveMask", Val&: S.ExclusiveMask);
413 IO.mapRequired(Key: "MinPrecision", Val&: S.MinPrecision);
414}
415
416void MappingTraits<DXContainerYAML::Signature>::mapping(
417 IO &IO, DXContainerYAML::Signature &S) {
418 IO.mapRequired(Key: "Parameters", Val&: S.Parameters);
419}
420
421void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
422 IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) {
423 IO.mapRequired(Key: "Version", Val&: S.Version);
424 IO.mapRequired(Key: "NumRootParameters", Val&: S.NumRootParameters);
425 IO.mapOptional(Key: "RootParametersOffset", Val&: S.RootParametersOffset, Default: std::nullopt);
426 IO.mapRequired(Key: "NumStaticSamplers", Val&: S.NumStaticSamplers);
427 IO.mapOptional(Key: "StaticSamplersOffset", Val&: S.StaticSamplersOffset, Default: std::nullopt);
428 IO.mapRequired(Key: "Parameters", Val&: S.Parameters.Locations, Ctx&: S);
429 IO.mapOptional(Key: "Samplers", Val&: S.StaticSamplers);
430#define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
431#include "llvm/BinaryFormat/DXContainerConstants.def"
432}
433
434void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
435 IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
436 IO.mapRequired(Key: "RangeType", Val&: R.RangeType);
437 // handling the edge case where NumDescriptors might be -1
438 if (IO.outputting()) {
439 if (R.NumDescriptors == UINT_MAX) {
440 int32_t NegOne = -1;
441 IO.mapRequired(Key: "NumDescriptors", Val&: NegOne);
442 } else
443 IO.mapRequired(Key: "NumDescriptors", Val&: R.NumDescriptors);
444 } else {
445 int32_t TmpNumDesc = 0;
446 IO.mapRequired(Key: "NumDescriptors", Val&: TmpNumDesc);
447 R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
448 }
449
450 IO.mapRequired(Key: "BaseShaderRegister", Val&: R.BaseShaderRegister);
451 IO.mapRequired(Key: "RegisterSpace", Val&: R.RegisterSpace);
452 IO.mapRequired(Key: "OffsetInDescriptorsFromTableStart",
453 Val&: R.OffsetInDescriptorsFromTableStart);
454#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \
455 IO.mapOptional(#Flag, R.Enum, false);
456#include "llvm/BinaryFormat/DXContainerConstants.def"
457}
458
459void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
460 IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
461 IO.mapRequired(Key: "NumRanges", Val&: T.NumRanges);
462 IO.mapOptional(Key: "RangesOffset", Val&: T.RangesOffset);
463 IO.mapRequired(Key: "Ranges", Val&: T.Ranges);
464}
465
466void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
467 DXContainerYAML::RootSignatureYamlDesc>::
468 mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
469 DXContainerYAML::RootSignatureYamlDesc &S) {
470 IO.mapRequired(Key: "ParameterType", Val&: L.Header.Type);
471 IO.mapRequired(Key: "ShaderVisibility", Val&: L.Header.Visibility);
472
473 switch (L.Header.Type) {
474 case dxbc::RootParameterType::Constants32Bit: {
475 DXContainerYAML::RootConstantsYaml &Constants =
476 S.Parameters.getOrInsertConstants(ParamDesc&: L);
477 IO.mapRequired(Key: "Constants", Val&: Constants);
478 break;
479 }
480 case dxbc::RootParameterType::CBV:
481 case dxbc::RootParameterType::SRV:
482 case dxbc::RootParameterType::UAV: {
483 DXContainerYAML::RootDescriptorYaml &Descriptor =
484 S.Parameters.getOrInsertDescriptor(ParamDesc&: L);
485 IO.mapRequired(Key: "Descriptor", Val&: Descriptor);
486 break;
487 }
488 case dxbc::RootParameterType::DescriptorTable: {
489 DXContainerYAML::DescriptorTableYaml &Table =
490 S.Parameters.getOrInsertTable(ParamDesc&: L);
491 IO.mapRequired(Key: "Table", Val&: Table);
492 break;
493 }
494 }
495}
496
497void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
498 IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) {
499 IO.mapRequired(Key: "Num32BitValues", Val&: C.Num32BitValues);
500 IO.mapRequired(Key: "RegisterSpace", Val&: C.RegisterSpace);
501 IO.mapRequired(Key: "ShaderRegister", Val&: C.ShaderRegister);
502}
503
504void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
505 IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
506 IO.mapRequired(Key: "RegisterSpace", Val&: D.RegisterSpace);
507 IO.mapRequired(Key: "ShaderRegister", Val&: D.ShaderRegister);
508#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \
509 IO.mapOptional(#Flag, D.Enum, false);
510#include "llvm/BinaryFormat/DXContainerConstants.def"
511}
512
513void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
514 IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {
515
516 IO.mapOptional(Key: "Filter", Val&: S.Filter);
517 IO.mapOptional(Key: "AddressU", Val&: S.AddressU);
518 IO.mapOptional(Key: "AddressV", Val&: S.AddressV);
519 IO.mapOptional(Key: "AddressW", Val&: S.AddressW);
520 IO.mapOptional(Key: "MipLODBias", Val&: S.MipLODBias);
521 IO.mapOptional(Key: "MaxAnisotropy", Val&: S.MaxAnisotropy);
522 IO.mapOptional(Key: "ComparisonFunc", Val&: S.ComparisonFunc);
523 IO.mapOptional(Key: "BorderColor", Val&: S.BorderColor);
524 IO.mapOptional(Key: "MinLOD", Val&: S.MinLOD);
525 IO.mapOptional(Key: "MaxLOD", Val&: S.MaxLOD);
526 IO.mapRequired(Key: "ShaderRegister", Val&: S.ShaderRegister);
527 IO.mapRequired(Key: "RegisterSpace", Val&: S.RegisterSpace);
528 IO.mapRequired(Key: "ShaderVisibility", Val&: S.ShaderVisibility);
529#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
530 IO.mapOptional(#Flag, S.Enum, false);
531#include "llvm/BinaryFormat/DXContainerConstants.def"
532}
533
534void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
535 DXContainerYAML::Part &P) {
536 IO.mapRequired(Key: "Name", Val&: P.Name);
537 IO.mapRequired(Key: "Size", Val&: P.Size);
538 IO.mapOptional(Key: "Program", Val&: P.Program);
539 IO.mapOptional(Key: "Flags", Val&: P.Flags);
540 IO.mapOptional(Key: "Hash", Val&: P.Hash);
541 IO.mapOptional(Key: "PSVInfo", Val&: P.Info);
542 IO.mapOptional(Key: "Signature", Val&: P.Signature);
543 IO.mapOptional(Key: "RootSignature", Val&: P.RootSignature);
544}
545
546void MappingTraits<DXContainerYAML::Object>::mapping(
547 IO &IO, DXContainerYAML::Object &Obj) {
548 IO.mapTag(Tag: "!dxcontainer", Default: true);
549 IO.mapRequired(Key: "Header", Val&: Obj.Header);
550 IO.mapRequired(Key: "Parts", Val&: Obj.Parts);
551}
552
553void MappingTraits<DXContainerYAML::ResourceFlags>::mapping(
554 IO &IO, DXContainerYAML::ResourceFlags &Flags) {
555#define RESOURCE_FLAG(FlagIndex, Enum) IO.mapRequired(#Enum, Flags.Bits.Enum);
556#include "llvm/BinaryFormat/DXContainerConstants.def"
557}
558
559void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
560 IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
561 IO.mapRequired(Key: "Type", Val&: Res.Type);
562 IO.mapRequired(Key: "Space", Val&: Res.Space);
563 IO.mapRequired(Key: "LowerBound", Val&: Res.LowerBound);
564 IO.mapRequired(Key: "UpperBound", Val&: Res.UpperBound);
565
566 const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
567 if (*PSVVersion < 2)
568 return;
569
570 IO.mapRequired(Key: "Kind", Val&: Res.Kind);
571 IO.mapRequired(Key: "Flags", Val&: Res.Flags);
572}
573
574void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
575 IO &IO, DXContainerYAML::SignatureElement &El) {
576 IO.mapRequired(Key: "Name", Val&: El.Name);
577 IO.mapRequired(Key: "Indices", Val&: El.Indices);
578 IO.mapRequired(Key: "StartRow", Val&: El.StartRow);
579 IO.mapRequired(Key: "Cols", Val&: El.Cols);
580 IO.mapRequired(Key: "StartCol", Val&: El.StartCol);
581 IO.mapRequired(Key: "Allocated", Val&: El.Allocated);
582 IO.mapRequired(Key: "Kind", Val&: El.Kind);
583 IO.mapRequired(Key: "ComponentType", Val&: El.Type);
584 IO.mapRequired(Key: "Interpolation", Val&: El.Mode);
585 IO.mapRequired(Key: "DynamicMask", Val&: El.DynamicMask);
586 IO.mapRequired(Key: "Stream", Val&: El.Stream);
587}
588
589void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration(
590 IO &IO, dxbc::PSV::SemanticKind &Value) {
591 for (const auto &E : dxbc::PSV::getSemanticKinds())
592 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
593}
594
595void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration(
596 IO &IO, dxbc::PSV::ComponentType &Value) {
597 for (const auto &E : dxbc::PSV::getComponentTypes())
598 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
599}
600
601void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration(
602 IO &IO, dxbc::PSV::InterpolationMode &Value) {
603 for (const auto &E : dxbc::PSV::getInterpolationModes())
604 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
605}
606
607void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration(
608 IO &IO, dxbc::PSV::ResourceType &Value) {
609 for (const auto &E : dxbc::PSV::getResourceTypes())
610 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
611}
612
613void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration(
614 IO &IO, dxbc::PSV::ResourceKind &Value) {
615 for (const auto &E : dxbc::PSV::getResourceKinds())
616 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
617}
618
619void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration(
620 IO &IO, dxbc::D3DSystemValue &Value) {
621 for (const auto &E : dxbc::getD3DSystemValues())
622 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
623}
624
625void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration(
626 IO &IO, dxbc::SigMinPrecision &Value) {
627 for (const auto &E : dxbc::getSigMinPrecisions())
628 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
629}
630
631void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration(
632 IO &IO, dxbc::SigComponentType &Value) {
633 for (const auto &E : dxbc::getSigComponentTypes())
634 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
635}
636
637void ScalarEnumerationTraits<dxbc::RootParameterType>::enumeration(
638 IO &IO, dxbc::RootParameterType &Value) {
639 for (const auto &E : dxbc::getRootParameterTypes())
640 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
641}
642
643void ScalarEnumerationTraits<dxil::ResourceClass>::enumeration(
644 IO &IO, dxil::ResourceClass &Value) {
645 const EnumEntry<dxil::ResourceClass> ResourceClasses[] = {
646 {"CBuffer", dxil::ResourceClass::CBuffer},
647 {"SRV", dxil::ResourceClass::SRV},
648 {"UAV", dxil::ResourceClass::UAV},
649 {"Sampler", dxil::ResourceClass::Sampler},
650 };
651
652 for (const auto &E : ResourceClasses)
653 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
654}
655
656void ScalarEnumerationTraits<dxbc::SamplerFilter>::enumeration(
657 IO &IO, dxbc::SamplerFilter &Value) {
658 for (const auto &E : dxbc::getSamplerFilters())
659 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
660}
661
662void ScalarEnumerationTraits<dxbc::StaticBorderColor>::enumeration(
663 IO &IO, dxbc::StaticBorderColor &Value) {
664 for (const auto &E : dxbc::getStaticBorderColors())
665 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
666}
667
668void ScalarEnumerationTraits<dxbc::TextureAddressMode>::enumeration(
669 IO &IO, dxbc::TextureAddressMode &Value) {
670 for (const auto &E : dxbc::getTextureAddressModes())
671 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
672}
673
674void ScalarEnumerationTraits<dxbc::ShaderVisibility>::enumeration(
675 IO &IO, dxbc::ShaderVisibility &Value) {
676 for (const auto &E : dxbc::getShaderVisibility())
677 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
678}
679
680void ScalarEnumerationTraits<dxbc::ComparisonFunc>::enumeration(
681 IO &IO, dxbc::ComparisonFunc &Value) {
682 for (const auto &E : dxbc::getComparisonFuncs())
683 IO.enumCase(Val&: Value, Str: E.Name, ConstVal: E.Value);
684}
685
686} // namespace yaml
687
688void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
689 dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo;
690 Triple::EnvironmentType Stage = dxbc::getShaderStage(Kind: Info.ShaderStage);
691
692 switch (Stage) {
693 case Triple::EnvironmentType::Pixel:
694 IO.mapRequired(Key: "DepthOutput", Val&: StageInfo.PS.DepthOutput);
695 IO.mapRequired(Key: "SampleFrequency", Val&: StageInfo.PS.SampleFrequency);
696 break;
697 case Triple::EnvironmentType::Vertex:
698 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.VS.OutputPositionPresent);
699 break;
700 case Triple::EnvironmentType::Geometry:
701 IO.mapRequired(Key: "InputPrimitive", Val&: StageInfo.GS.InputPrimitive);
702 IO.mapRequired(Key: "OutputTopology", Val&: StageInfo.GS.OutputTopology);
703 IO.mapRequired(Key: "OutputStreamMask", Val&: StageInfo.GS.OutputStreamMask);
704 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.GS.OutputPositionPresent);
705 break;
706 case Triple::EnvironmentType::Hull:
707 IO.mapRequired(Key: "InputControlPointCount",
708 Val&: StageInfo.HS.InputControlPointCount);
709 IO.mapRequired(Key: "OutputControlPointCount",
710 Val&: StageInfo.HS.OutputControlPointCount);
711 IO.mapRequired(Key: "TessellatorDomain", Val&: StageInfo.HS.TessellatorDomain);
712 IO.mapRequired(Key: "TessellatorOutputPrimitive",
713 Val&: StageInfo.HS.TessellatorOutputPrimitive);
714 break;
715 case Triple::EnvironmentType::Domain:
716 IO.mapRequired(Key: "InputControlPointCount",
717 Val&: StageInfo.DS.InputControlPointCount);
718 IO.mapRequired(Key: "OutputPositionPresent", Val&: StageInfo.DS.OutputPositionPresent);
719 IO.mapRequired(Key: "TessellatorDomain", Val&: StageInfo.DS.TessellatorDomain);
720 break;
721 case Triple::EnvironmentType::Mesh:
722 IO.mapRequired(Key: "GroupSharedBytesUsed", Val&: StageInfo.MS.GroupSharedBytesUsed);
723 IO.mapRequired(Key: "GroupSharedBytesDependentOnViewID",
724 Val&: StageInfo.MS.GroupSharedBytesDependentOnViewID);
725 IO.mapRequired(Key: "PayloadSizeInBytes", Val&: StageInfo.MS.PayloadSizeInBytes);
726 IO.mapRequired(Key: "MaxOutputVertices", Val&: StageInfo.MS.MaxOutputVertices);
727 IO.mapRequired(Key: "MaxOutputPrimitives", Val&: StageInfo.MS.MaxOutputPrimitives);
728 break;
729 case Triple::EnvironmentType::Amplification:
730 IO.mapRequired(Key: "PayloadSizeInBytes", Val&: StageInfo.AS.PayloadSizeInBytes);
731 break;
732 default:
733 break;
734 }
735
736 IO.mapRequired(Key: "MinimumWaveLaneCount", Val&: Info.MinimumWaveLaneCount);
737 IO.mapRequired(Key: "MaximumWaveLaneCount", Val&: Info.MaximumWaveLaneCount);
738
739 if (Version == 0)
740 return;
741
742 IO.mapRequired(Key: "UsesViewID", Val&: Info.UsesViewID);
743
744 switch (Stage) {
745 case Triple::EnvironmentType::Geometry:
746 IO.mapRequired(Key: "MaxVertexCount", Val&: Info.GeomData.MaxVertexCount);
747 break;
748 case Triple::EnvironmentType::Hull:
749 case Triple::EnvironmentType::Domain:
750 IO.mapRequired(Key: "SigPatchConstOrPrimVectors",
751 Val&: Info.GeomData.SigPatchConstOrPrimVectors);
752 break;
753 case Triple::EnvironmentType::Mesh:
754 IO.mapRequired(Key: "SigPrimVectors", Val&: Info.GeomData.MeshInfo.SigPrimVectors);
755 IO.mapRequired(Key: "MeshOutputTopology",
756 Val&: Info.GeomData.MeshInfo.MeshOutputTopology);
757 break;
758 default:
759 break;
760 }
761
762 IO.mapRequired(Key: "SigInputVectors", Val&: Info.SigInputVectors);
763 MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors);
764 IO.mapRequired(Key: "SigOutputVectors", Val&: Vec);
765
766 if (Version == 1)
767 return;
768
769 IO.mapRequired(Key: "NumThreadsX", Val&: Info.NumThreadsX);
770 IO.mapRequired(Key: "NumThreadsY", Val&: Info.NumThreadsY);
771 IO.mapRequired(Key: "NumThreadsZ", Val&: Info.NumThreadsZ);
772
773 if (Version == 2)
774 return;
775
776 IO.mapRequired(Key: "EntryName", Val&: EntryName);
777}
778
779} // namespace llvm
780