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
23 namespace 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.
27 static_assert((uint64_t)dxbc::FeatureFlags::NextUnusedBit <= 1ull << 63,
28 "Shader flag bits exceed enum size.");
29
ShaderFeatureFlags(uint64_t FlagData)30 DXContainerYAML::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
36 template <typename T>
37 static llvm::Error
readDescriptorRanges(DXContainerYAML::RootParameterHeaderYaml & Header,DXContainerYAML::RootSignatureYamlDesc & RootSigDesc,object::DirectX::DescriptorTableView * DTV)38 readDescriptorRanges(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(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(NewR);
72 }
73
74 return Error::success();
75 }
76
77 llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
create(const object::DirectX::RootSignature & Data)78 DXContainerYAML::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(PH.ParameterType))
94 return createStringError(std::errc::invalid_argument,
95 "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(PH.ShaderVisibility))
102 return createStringError(std::errc::invalid_argument,
103 "Invalid value for shader visibility");
104
105 Header.Visibility = PH.ShaderVisibility;
106
107 llvm::Expected<object::DirectX::RootParameterView> ParamViewOrErr =
108 Data.getParameter(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>(&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(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>(&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(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>(&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(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
getEncodedFlags() const189 uint32_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
getEncodedFlags()198 uint32_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
getEncodedFlags() const207 uint32_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
getEncodedFlags()216 uint64_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
ShaderHash(const dxbc::ShaderHash & Data)225 DXContainerYAML::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(Digest.data(), &Data.Digest[0], 16);
230 }
231
PSVInfo()232 DXContainerYAML::PSVInfo::PSVInfo() : Version(0) {
233 memset(&Info, 0, sizeof(Info));
234 }
235
PSVInfo(const dxbc::PSV::v0::RuntimeInfo * P,uint16_t Stage)236 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P,
237 uint16_t Stage)
238 : Version(0) {
239 memset(&Info, 0, sizeof(Info));
240 memcpy(&Info, P, 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
PSVInfo(const dxbc::PSV::v1::RuntimeInfo * P)249 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P)
250 : Version(1) {
251 memset(&Info, 0, sizeof(Info));
252 memcpy(&Info, P, sizeof(dxbc::PSV::v1::RuntimeInfo));
253 }
254
PSVInfo(const dxbc::PSV::v2::RuntimeInfo * P)255 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P)
256 : Version(2) {
257 memset(&Info, 0, sizeof(Info));
258 memcpy(&Info, P, sizeof(dxbc::PSV::v2::RuntimeInfo));
259 }
260
PSVInfo(const dxbc::PSV::v3::RuntimeInfo * P,StringRef StringTable)261 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P,
262 StringRef StringTable)
263 : Version(3),
264 EntryName(StringTable.substr(P->EntryNameOffset,
265 StringTable.find('\0', P->EntryNameOffset) -
266 P->EntryNameOffset)) {
267 memset(&Info, 0, sizeof(Info));
268 memcpy(&Info, P, sizeof(dxbc::PSV::v3::RuntimeInfo));
269 }
270
271 namespace yaml {
272
mapping(IO & IO,DXContainerYAML::VersionTuple & Version)273 void MappingTraits<DXContainerYAML::VersionTuple>::mapping(
274 IO &IO, DXContainerYAML::VersionTuple &Version) {
275 IO.mapRequired("Major", Version.Major);
276 IO.mapRequired("Minor", Version.Minor);
277 }
278
mapping(IO & IO,DXContainerYAML::FileHeader & Header)279 void MappingTraits<DXContainerYAML::FileHeader>::mapping(
280 IO &IO, DXContainerYAML::FileHeader &Header) {
281 IO.mapRequired("Hash", Header.Hash);
282 IO.mapRequired("Version", Header.Version);
283 IO.mapOptional("FileSize", Header.FileSize);
284 IO.mapRequired("PartCount", Header.PartCount);
285 IO.mapOptional("PartOffsets", Header.PartOffsets);
286 }
287
mapping(IO & IO,DXContainerYAML::DXILProgram & Program)288 void MappingTraits<DXContainerYAML::DXILProgram>::mapping(
289 IO &IO, DXContainerYAML::DXILProgram &Program) {
290 IO.mapRequired("MajorVersion", Program.MajorVersion);
291 IO.mapRequired("MinorVersion", Program.MinorVersion);
292 IO.mapRequired("ShaderKind", Program.ShaderKind);
293 IO.mapOptional("Size", Program.Size);
294 IO.mapRequired("DXILMajorVersion", Program.DXILMajorVersion);
295 IO.mapRequired("DXILMinorVersion", Program.DXILMinorVersion);
296 IO.mapOptional("DXILSize", Program.DXILSize);
297 IO.mapOptional("DXIL", Program.DXIL);
298 }
299
mapping(IO & IO,DXContainerYAML::ShaderFeatureFlags & Flags)300 void 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
mapping(IO & IO,DXContainerYAML::ShaderHash & Hash)307 void MappingTraits<DXContainerYAML::ShaderHash>::mapping(
308 IO &IO, DXContainerYAML::ShaderHash &Hash) {
309 IO.mapRequired("IncludesSource", Hash.IncludesSource);
310 IO.mapRequired("Digest", Hash.Digest);
311 }
312
mapping(IO & IO,DXContainerYAML::PSVInfo & PSV)313 void MappingTraits<DXContainerYAML::PSVInfo>::mapping(
314 IO &IO, DXContainerYAML::PSVInfo &PSV) {
315 IO.mapRequired("Version", 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([&]() { 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("ShaderStage", PSV.Info.ShaderStage);
328 PSV.mapInfoForVersion(IO);
329
330 IO.mapRequired("ResourceStride", PSV.ResourceStride);
331 IO.mapRequired("Resources", PSV.Resources);
332 if (PSV.Version == 0)
333 return;
334 IO.mapRequired("SigInputElements", PSV.SigInputElements);
335 IO.mapRequired("SigOutputElements", PSV.SigOutputElements);
336 IO.mapRequired("SigPatchOrPrimElements", PSV.SigPatchOrPrimElements);
337
338 Triple::EnvironmentType Stage = dxbc::getShaderStage(PSV.Info.ShaderStage);
339 if (PSV.Info.UsesViewID) {
340 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks(
341 PSV.OutputVectorMasks);
342 IO.mapRequired("OutputVectorMasks", MutableOutMasks);
343 if (Stage == Triple::EnvironmentType::Hull)
344 IO.mapRequired("PatchOrPrimMasks", PSV.PatchOrPrimMasks);
345 }
346 MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap(
347 PSV.InputOutputMap);
348 IO.mapRequired("InputOutputMap", MutableIOMap);
349
350 if (Stage == Triple::EnvironmentType::Hull)
351 IO.mapRequired("InputPatchMap", PSV.InputPatchMap);
352
353 if (Stage == Triple::EnvironmentType::Domain)
354 IO.mapRequired("PatchOutputMap", PSV.PatchOutputMap);
355 }
356
mapping(IO & IO,DXContainerYAML::SignatureParameter & S)357 void MappingTraits<DXContainerYAML::SignatureParameter>::mapping(
358 IO &IO, DXContainerYAML::SignatureParameter &S) {
359 IO.mapRequired("Stream", S.Stream);
360 IO.mapRequired("Name", S.Name);
361 IO.mapRequired("Index", S.Index);
362 IO.mapRequired("SystemValue", S.SystemValue);
363 IO.mapRequired("CompType", S.CompType);
364 IO.mapRequired("Register", S.Register);
365 IO.mapRequired("Mask", S.Mask);
366 IO.mapRequired("ExclusiveMask", S.ExclusiveMask);
367 IO.mapRequired("MinPrecision", S.MinPrecision);
368 }
369
mapping(IO & IO,DXContainerYAML::Signature & S)370 void MappingTraits<DXContainerYAML::Signature>::mapping(
371 IO &IO, DXContainerYAML::Signature &S) {
372 IO.mapRequired("Parameters", S.Parameters);
373 }
374
mapping(IO & IO,DXContainerYAML::RootSignatureYamlDesc & S)375 void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
376 IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) {
377 IO.mapRequired("Version", S.Version);
378 IO.mapRequired("NumRootParameters", S.NumRootParameters);
379 IO.mapRequired("RootParametersOffset", S.RootParametersOffset);
380 IO.mapRequired("NumStaticSamplers", S.NumStaticSamplers);
381 IO.mapRequired("StaticSamplersOffset", S.StaticSamplersOffset);
382 IO.mapRequired("Parameters", S.Parameters.Locations, S);
383 IO.mapOptional("Samplers", S.StaticSamplers);
384 #define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
385 #include "llvm/BinaryFormat/DXContainerConstants.def"
386 }
387
mapping(IO & IO,llvm::DXContainerYAML::DescriptorRangeYaml & R)388 void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
389 IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
390 IO.mapRequired("RangeType", 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("NumDescriptors", NegOne);
396 } else
397 IO.mapRequired("NumDescriptors", R.NumDescriptors);
398 } else {
399 int32_t TmpNumDesc = 0;
400 IO.mapRequired("NumDescriptors", TmpNumDesc);
401 R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
402 }
403
404 IO.mapRequired("BaseShaderRegister", R.BaseShaderRegister);
405 IO.mapRequired("RegisterSpace", R.RegisterSpace);
406 IO.mapRequired("OffsetInDescriptorsFromTableStart",
407 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
mapping(IO & IO,llvm::DXContainerYAML::DescriptorTableYaml & T)413 void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
414 IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
415 IO.mapRequired("NumRanges", T.NumRanges);
416 IO.mapOptional("RangesOffset", T.RangesOffset);
417 IO.mapRequired("Ranges", T.Ranges);
418 }
419
420 void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
421 DXContainerYAML::RootSignatureYamlDesc>::
mapping(IO & IO,DXContainerYAML::RootParameterLocationYaml & L,DXContainerYAML::RootSignatureYamlDesc & S)422 mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
423 DXContainerYAML::RootSignatureYamlDesc &S) {
424 IO.mapRequired("ParameterType", L.Header.Type);
425 IO.mapRequired("ShaderVisibility", L.Header.Visibility);
426
427 switch (L.Header.Type) {
428 case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
429 DXContainerYAML::RootConstantsYaml &Constants =
430 S.Parameters.getOrInsertConstants(L);
431 IO.mapRequired("Constants", Constants);
432 break;
433 }
434 case llvm::to_underlying(dxbc::RootParameterType::CBV):
435 case llvm::to_underlying(dxbc::RootParameterType::SRV):
436 case llvm::to_underlying(dxbc::RootParameterType::UAV): {
437 DXContainerYAML::RootDescriptorYaml &Descriptor =
438 S.Parameters.getOrInsertDescriptor(L);
439 IO.mapRequired("Descriptor", Descriptor);
440 break;
441 }
442 case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
443 DXContainerYAML::DescriptorTableYaml &Table =
444 S.Parameters.getOrInsertTable(L);
445 IO.mapRequired("Table", Table);
446 break;
447 }
448 }
449 }
450
mapping(IO & IO,llvm::DXContainerYAML::RootConstantsYaml & C)451 void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
452 IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) {
453 IO.mapRequired("Num32BitValues", C.Num32BitValues);
454 IO.mapRequired("RegisterSpace", C.RegisterSpace);
455 IO.mapRequired("ShaderRegister", C.ShaderRegister);
456 }
457
mapping(IO & IO,llvm::DXContainerYAML::RootDescriptorYaml & D)458 void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
459 IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
460 IO.mapRequired("RegisterSpace", D.RegisterSpace);
461 IO.mapRequired("ShaderRegister", 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
mapping(IO & IO,llvm::DXContainerYAML::StaticSamplerYamlDesc & S)467 void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
468 IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {
469
470 IO.mapOptional("Filter", S.Filter);
471 IO.mapOptional("AddressU", S.AddressU);
472 IO.mapOptional("AddressV", S.AddressV);
473 IO.mapOptional("AddressW", S.AddressW);
474 IO.mapOptional("MipLODBias", S.MipLODBias);
475 IO.mapOptional("MaxAnisotropy", S.MaxAnisotropy);
476 IO.mapOptional("ComparisonFunc", S.ComparisonFunc);
477 IO.mapOptional("BorderColor", S.BorderColor);
478 IO.mapOptional("MinLOD", S.MinLOD);
479 IO.mapOptional("MaxLOD", S.MaxLOD);
480 IO.mapRequired("ShaderRegister", S.ShaderRegister);
481 IO.mapRequired("RegisterSpace", S.RegisterSpace);
482 IO.mapRequired("ShaderVisibility", S.ShaderVisibility);
483 }
484
mapping(IO & IO,DXContainerYAML::Part & P)485 void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
486 DXContainerYAML::Part &P) {
487 IO.mapRequired("Name", P.Name);
488 IO.mapRequired("Size", P.Size);
489 IO.mapOptional("Program", P.Program);
490 IO.mapOptional("Flags", P.Flags);
491 IO.mapOptional("Hash", P.Hash);
492 IO.mapOptional("PSVInfo", P.Info);
493 IO.mapOptional("Signature", P.Signature);
494 IO.mapOptional("RootSignature", P.RootSignature);
495 }
496
mapping(IO & IO,DXContainerYAML::Object & Obj)497 void MappingTraits<DXContainerYAML::Object>::mapping(
498 IO &IO, DXContainerYAML::Object &Obj) {
499 IO.mapTag("!dxcontainer", true);
500 IO.mapRequired("Header", Obj.Header);
501 IO.mapRequired("Parts", Obj.Parts);
502 }
503
mapping(IO & IO,DXContainerYAML::ResourceFlags & Flags)504 void 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
mapping(IO & IO,DXContainerYAML::ResourceBindInfo & Res)510 void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
511 IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
512 IO.mapRequired("Type", Res.Type);
513 IO.mapRequired("Space", Res.Space);
514 IO.mapRequired("LowerBound", Res.LowerBound);
515 IO.mapRequired("UpperBound", Res.UpperBound);
516
517 const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
518 if (*PSVVersion < 2)
519 return;
520
521 IO.mapRequired("Kind", Res.Kind);
522 IO.mapRequired("Flags", Res.Flags);
523 }
524
mapping(IO & IO,DXContainerYAML::SignatureElement & El)525 void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
526 IO &IO, DXContainerYAML::SignatureElement &El) {
527 IO.mapRequired("Name", El.Name);
528 IO.mapRequired("Indices", El.Indices);
529 IO.mapRequired("StartRow", El.StartRow);
530 IO.mapRequired("Cols", El.Cols);
531 IO.mapRequired("StartCol", El.StartCol);
532 IO.mapRequired("Allocated", El.Allocated);
533 IO.mapRequired("Kind", El.Kind);
534 IO.mapRequired("ComponentType", El.Type);
535 IO.mapRequired("Interpolation", El.Mode);
536 IO.mapRequired("DynamicMask", El.DynamicMask);
537 IO.mapRequired("Stream", El.Stream);
538 }
539
enumeration(IO & IO,dxbc::PSV::SemanticKind & Value)540 void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration(
541 IO &IO, dxbc::PSV::SemanticKind &Value) {
542 for (const auto &E : dxbc::PSV::getSemanticKinds())
543 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
544 }
545
enumeration(IO & IO,dxbc::PSV::ComponentType & Value)546 void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration(
547 IO &IO, dxbc::PSV::ComponentType &Value) {
548 for (const auto &E : dxbc::PSV::getComponentTypes())
549 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
550 }
551
enumeration(IO & IO,dxbc::PSV::InterpolationMode & Value)552 void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration(
553 IO &IO, dxbc::PSV::InterpolationMode &Value) {
554 for (const auto &E : dxbc::PSV::getInterpolationModes())
555 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
556 }
557
enumeration(IO & IO,dxbc::PSV::ResourceType & Value)558 void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration(
559 IO &IO, dxbc::PSV::ResourceType &Value) {
560 for (const auto &E : dxbc::PSV::getResourceTypes())
561 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
562 }
563
enumeration(IO & IO,dxbc::PSV::ResourceKind & Value)564 void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration(
565 IO &IO, dxbc::PSV::ResourceKind &Value) {
566 for (const auto &E : dxbc::PSV::getResourceKinds())
567 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
568 }
569
enumeration(IO & IO,dxbc::D3DSystemValue & Value)570 void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration(
571 IO &IO, dxbc::D3DSystemValue &Value) {
572 for (const auto &E : dxbc::getD3DSystemValues())
573 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
574 }
575
enumeration(IO & IO,dxbc::SigMinPrecision & Value)576 void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration(
577 IO &IO, dxbc::SigMinPrecision &Value) {
578 for (const auto &E : dxbc::getSigMinPrecisions())
579 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
580 }
581
enumeration(IO & IO,dxbc::SigComponentType & Value)582 void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration(
583 IO &IO, dxbc::SigComponentType &Value) {
584 for (const auto &E : dxbc::getSigComponentTypes())
585 IO.enumCase(Value, E.Name.str().c_str(), E.Value);
586 }
587
588 } // namespace yaml
589
mapInfoForVersion(yaml::IO & IO)590 void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
591 dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo;
592 Triple::EnvironmentType Stage = dxbc::getShaderStage(Info.ShaderStage);
593
594 switch (Stage) {
595 case Triple::EnvironmentType::Pixel:
596 IO.mapRequired("DepthOutput", StageInfo.PS.DepthOutput);
597 IO.mapRequired("SampleFrequency", StageInfo.PS.SampleFrequency);
598 break;
599 case Triple::EnvironmentType::Vertex:
600 IO.mapRequired("OutputPositionPresent", StageInfo.VS.OutputPositionPresent);
601 break;
602 case Triple::EnvironmentType::Geometry:
603 IO.mapRequired("InputPrimitive", StageInfo.GS.InputPrimitive);
604 IO.mapRequired("OutputTopology", StageInfo.GS.OutputTopology);
605 IO.mapRequired("OutputStreamMask", StageInfo.GS.OutputStreamMask);
606 IO.mapRequired("OutputPositionPresent", StageInfo.GS.OutputPositionPresent);
607 break;
608 case Triple::EnvironmentType::Hull:
609 IO.mapRequired("InputControlPointCount",
610 StageInfo.HS.InputControlPointCount);
611 IO.mapRequired("OutputControlPointCount",
612 StageInfo.HS.OutputControlPointCount);
613 IO.mapRequired("TessellatorDomain", StageInfo.HS.TessellatorDomain);
614 IO.mapRequired("TessellatorOutputPrimitive",
615 StageInfo.HS.TessellatorOutputPrimitive);
616 break;
617 case Triple::EnvironmentType::Domain:
618 IO.mapRequired("InputControlPointCount",
619 StageInfo.DS.InputControlPointCount);
620 IO.mapRequired("OutputPositionPresent", StageInfo.DS.OutputPositionPresent);
621 IO.mapRequired("TessellatorDomain", StageInfo.DS.TessellatorDomain);
622 break;
623 case Triple::EnvironmentType::Mesh:
624 IO.mapRequired("GroupSharedBytesUsed", StageInfo.MS.GroupSharedBytesUsed);
625 IO.mapRequired("GroupSharedBytesDependentOnViewID",
626 StageInfo.MS.GroupSharedBytesDependentOnViewID);
627 IO.mapRequired("PayloadSizeInBytes", StageInfo.MS.PayloadSizeInBytes);
628 IO.mapRequired("MaxOutputVertices", StageInfo.MS.MaxOutputVertices);
629 IO.mapRequired("MaxOutputPrimitives", StageInfo.MS.MaxOutputPrimitives);
630 break;
631 case Triple::EnvironmentType::Amplification:
632 IO.mapRequired("PayloadSizeInBytes", StageInfo.AS.PayloadSizeInBytes);
633 break;
634 default:
635 break;
636 }
637
638 IO.mapRequired("MinimumWaveLaneCount", Info.MinimumWaveLaneCount);
639 IO.mapRequired("MaximumWaveLaneCount", Info.MaximumWaveLaneCount);
640
641 if (Version == 0)
642 return;
643
644 IO.mapRequired("UsesViewID", Info.UsesViewID);
645
646 switch (Stage) {
647 case Triple::EnvironmentType::Geometry:
648 IO.mapRequired("MaxVertexCount", Info.GeomData.MaxVertexCount);
649 break;
650 case Triple::EnvironmentType::Hull:
651 case Triple::EnvironmentType::Domain:
652 IO.mapRequired("SigPatchConstOrPrimVectors",
653 Info.GeomData.SigPatchConstOrPrimVectors);
654 break;
655 case Triple::EnvironmentType::Mesh:
656 IO.mapRequired("SigPrimVectors", Info.GeomData.MeshInfo.SigPrimVectors);
657 IO.mapRequired("MeshOutputTopology",
658 Info.GeomData.MeshInfo.MeshOutputTopology);
659 break;
660 default:
661 break;
662 }
663
664 IO.mapRequired("SigInputVectors", Info.SigInputVectors);
665 MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors);
666 IO.mapRequired("SigOutputVectors", Vec);
667
668 if (Version == 1)
669 return;
670
671 IO.mapRequired("NumThreadsX", Info.NumThreadsX);
672 IO.mapRequired("NumThreadsY", Info.NumThreadsY);
673 IO.mapRequired("NumThreadsZ", Info.NumThreadsZ);
674
675 if (Version == 2)
676 return;
677
678 IO.mapRequired("EntryName", EntryName);
679 }
680
681 } // namespace llvm
682