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 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 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> 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 189 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 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 207 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 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 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 232 DXContainerYAML::PSVInfo::PSVInfo() : Version(0) { 233 memset(&Info, 0, sizeof(Info)); 234 } 235 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 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 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 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 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 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 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 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 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 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 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 370 void MappingTraits<DXContainerYAML::Signature>::mapping( 371 IO &IO, DXContainerYAML::Signature &S) { 372 IO.mapRequired("Parameters", S.Parameters); 373 } 374 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 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 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>:: 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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