| //===- DXContainerYAML.cpp - DXContainer YAMLIO implementation ------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines classes for handling the YAML representation of |
| // DXContainerYAML. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/ObjectYAML/DXContainerYAML.h" |
| #include "llvm/ADT/STLForwardCompat.h" |
| #include "llvm/ADT/ScopeExit.h" |
| #include "llvm/BinaryFormat/DXContainer.h" |
| #include "llvm/Support/Error.h" |
| #include "llvm/Support/ScopedPrinter.h" |
| #include <cstdint> |
| #include <system_error> |
| |
| namespace llvm { |
| |
| // This assert is duplicated here to leave a breadcrumb of the places that need |
| // to be updated if flags grow past 64-bits. |
| static_assert((uint64_t)dxbc::FeatureFlags::NextUnusedBit <= 1ull << 63, |
| "Shader flag bits exceed enum size."); |
| |
| DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) { |
| #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \ |
| Val = (FlagData & (uint64_t)dxbc::FeatureFlags::Val) > 0; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| template <typename T> |
| static llvm::Error |
| readDescriptorRanges(DXContainerYAML::RootParameterHeaderYaml &Header, |
| DXContainerYAML::RootSignatureYamlDesc &RootSigDesc, |
| object::DirectX::DescriptorTableView *DTV) { |
| |
| llvm::Expected<object::DirectX::DescriptorTable<T>> TableOrErr = |
| DTV->read<T>(); |
| if (Error E = TableOrErr.takeError()) |
| return E; |
| auto Table = *TableOrErr; |
| |
| DXContainerYAML::RootParameterLocationYaml Location(Header); |
| DXContainerYAML::DescriptorTableYaml &TableYaml = |
| RootSigDesc.Parameters.getOrInsertTable(Location); |
| RootSigDesc.Parameters.insertLocation(Location); |
| |
| TableYaml.NumRanges = Table.NumRanges; |
| TableYaml.RangesOffset = Table.RangesOffset; |
| |
| for (const auto &R : Table.Ranges) { |
| DXContainerYAML::DescriptorRangeYaml NewR; |
| NewR.OffsetInDescriptorsFromTableStart = |
| R.OffsetInDescriptorsFromTableStart; |
| NewR.NumDescriptors = R.NumDescriptors; |
| NewR.BaseShaderRegister = R.BaseShaderRegister; |
| NewR.RegisterSpace = R.RegisterSpace; |
| if (!dxbc::isValidRangeType(R.RangeType)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for descriptor range type"); |
| NewR.RangeType = dxil::ResourceClass(R.RangeType); |
| if constexpr (std::is_same_v<T, dxbc::RTS0::v2::DescriptorRange>) { |
| // Set all flag fields for v2 |
| #define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \ |
| NewR.Enum = \ |
| (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlags::Enum)) != 0; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| TableYaml.Ranges.push_back(NewR); |
| } |
| |
| return Error::success(); |
| } |
| |
| llvm::Expected<DXContainerYAML::RootSignatureYamlDesc> |
| DXContainerYAML::RootSignatureYamlDesc::create( |
| const object::DirectX::RootSignature &Data) { |
| |
| RootSignatureYamlDesc RootSigDesc; |
| uint32_t Version = Data.getVersion(); |
| |
| RootSigDesc.Version = Version; |
| RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers(); |
| RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset(); |
| RootSigDesc.NumRootParameters = Data.getNumRootParameters(); |
| RootSigDesc.RootParametersOffset = Data.getRootParametersOffset(); |
| |
| uint32_t Flags = Data.getFlags(); |
| for (const dxbc::RTS0::v1::RootParameterHeader &PH : Data.param_headers()) { |
| |
| if (!dxbc::isValidParameterType(PH.ParameterType)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for parameter type"); |
| |
| RootParameterHeaderYaml Header(dxbc::RootParameterType(PH.ParameterType)); |
| Header.Offset = PH.ParameterOffset; |
| |
| if (!dxbc::isValidShaderVisibility(PH.ShaderVisibility)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for shader visibility"); |
| |
| Header.Visibility = dxbc::ShaderVisibility(PH.ShaderVisibility); |
| |
| llvm::Expected<object::DirectX::RootParameterView> ParamViewOrErr = |
| Data.getParameter(PH); |
| if (Error E = ParamViewOrErr.takeError()) |
| return std::move(E); |
| object::DirectX::RootParameterView ParamView = ParamViewOrErr.get(); |
| |
| if (auto *RCV = dyn_cast<object::DirectX::RootConstantView>(&ParamView)) { |
| llvm::Expected<dxbc::RTS0::v1::RootConstants> ConstantsOrErr = |
| RCV->read(); |
| if (Error E = ConstantsOrErr.takeError()) |
| return std::move(E); |
| |
| auto Constants = *ConstantsOrErr; |
| RootParameterLocationYaml Location(Header); |
| RootConstantsYaml &ConstantYaml = |
| RootSigDesc.Parameters.getOrInsertConstants(Location); |
| RootSigDesc.Parameters.insertLocation(Location); |
| ConstantYaml.Num32BitValues = Constants.Num32BitValues; |
| ConstantYaml.ShaderRegister = Constants.ShaderRegister; |
| ConstantYaml.RegisterSpace = Constants.RegisterSpace; |
| |
| } else if (auto *RDV = |
| dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) { |
| llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr = |
| RDV->read(Version); |
| if (Error E = DescriptorOrErr.takeError()) |
| return std::move(E); |
| auto Descriptor = *DescriptorOrErr; |
| RootParameterLocationYaml Location(Header); |
| RootDescriptorYaml &YamlDescriptor = |
| RootSigDesc.Parameters.getOrInsertDescriptor(Location); |
| RootSigDesc.Parameters.insertLocation(Location); |
| |
| YamlDescriptor.ShaderRegister = Descriptor.ShaderRegister; |
| YamlDescriptor.RegisterSpace = Descriptor.RegisterSpace; |
| if (Version > 1) { |
| #define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \ |
| YamlDescriptor.Enum = \ |
| (Descriptor.Flags & \ |
| llvm::to_underlying(dxbc::RootDescriptorFlags::Enum)) > 0; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| } else if (auto *DTV = |
| dyn_cast<object::DirectX::DescriptorTableView>(&ParamView)) { |
| if (Version == 1) { |
| if (Error E = readDescriptorRanges<dxbc::RTS0::v1::DescriptorRange>( |
| Header, RootSigDesc, DTV)) |
| return std::move(E); |
| } else if (Version == 2 || Version == 3) { |
| if (Error E = readDescriptorRanges<dxbc::RTS0::v2::DescriptorRange>( |
| Header, RootSigDesc, DTV)) |
| return std::move(E); |
| } else |
| llvm_unreachable("Unknown version for DescriptorRanges"); |
| } |
| } |
| |
| for (const auto &S : Data.samplers()) { |
| if (!dxbc::isValidSamplerFilter(S.Filter)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for static sampler filter"); |
| |
| if (!dxbc::isValidAddress(S.AddressU)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for static sampler AddressU"); |
| |
| if (!dxbc::isValidAddress(S.AddressV)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for static sampler AddressV"); |
| |
| if (!dxbc::isValidAddress(S.AddressW)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for static sampler AddressW"); |
| |
| if (!dxbc::isValidComparisonFunc(S.ComparisonFunc)) |
| return createStringError( |
| std::errc::invalid_argument, |
| "Invalid value for static sampler ComparisonFunc"); |
| |
| if (!dxbc::isValidBorderColor(S.BorderColor)) |
| return createStringError(std::errc::invalid_argument, |
| "Invalid value for static sampler BorderColor"); |
| |
| if (!dxbc::isValidShaderVisibility(S.ShaderVisibility)) |
| return createStringError( |
| std::errc::invalid_argument, |
| "Invalid value for static sampler ShaderVisibility"); |
| |
| StaticSamplerYamlDesc NewS; |
| NewS.Filter = dxbc::SamplerFilter(S.Filter); |
| NewS.AddressU = dxbc::TextureAddressMode(S.AddressU); |
| NewS.AddressV = dxbc::TextureAddressMode(S.AddressV); |
| NewS.AddressW = dxbc::TextureAddressMode(S.AddressW); |
| NewS.MipLODBias = S.MipLODBias; |
| NewS.MaxAnisotropy = S.MaxAnisotropy; |
| NewS.ComparisonFunc = dxbc::ComparisonFunc(S.ComparisonFunc); |
| NewS.BorderColor = dxbc::StaticBorderColor(S.BorderColor); |
| NewS.MinLOD = S.MinLOD; |
| NewS.MaxLOD = S.MaxLOD; |
| NewS.ShaderRegister = S.ShaderRegister; |
| NewS.RegisterSpace = S.RegisterSpace; |
| NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility); |
| |
| if (Version > 2) { |
| #define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \ |
| NewS.Enum = (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| RootSigDesc.StaticSamplers.push_back(NewS); |
| } |
| |
| #define ROOT_SIGNATURE_FLAG(Num, Val) \ |
| RootSigDesc.Val = (Flags & llvm::to_underlying(dxbc::RootFlags::Val)) > 0; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| return RootSigDesc; |
| } |
| |
| uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const { |
| uint64_t Flags = 0; |
| #define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \ |
| if (Enum) \ |
| Flags |= (uint32_t)dxbc::RootDescriptorFlags::Enum; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| return Flags; |
| } |
| |
| uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() { |
| uint64_t Flag = 0; |
| #define ROOT_SIGNATURE_FLAG(Num, Val) \ |
| if (Val) \ |
| Flag |= (uint32_t)dxbc::RootFlags::Val; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| return Flag; |
| } |
| |
| uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const { |
| uint64_t Flags = 0; |
| #define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \ |
| if (Enum) \ |
| Flags |= (uint32_t)dxbc::DescriptorRangeFlags::Enum; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| return Flags; |
| } |
| |
| uint32_t DXContainerYAML::StaticSamplerYamlDesc::getEncodedFlags() const { |
| uint64_t Flags = 0; |
| #define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \ |
| if (Enum) \ |
| Flags |= (uint32_t)dxbc::StaticSamplerFlags::Enum; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| return Flags; |
| } |
| |
| uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() { |
| uint64_t Flag = 0; |
| #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \ |
| if (Val) \ |
| Flag |= (uint64_t)dxbc::FeatureFlags::Val; |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| return Flag; |
| } |
| |
| DXContainerYAML::ShaderHash::ShaderHash(const dxbc::ShaderHash &Data) |
| : IncludesSource((Data.Flags & static_cast<uint32_t>( |
| dxbc::HashFlags::IncludesSource)) != 0), |
| Digest(16, 0) { |
| memcpy(Digest.data(), &Data.Digest[0], 16); |
| } |
| |
| DXContainerYAML::PSVInfo::PSVInfo() : Version(0) { |
| memset(&Info, 0, sizeof(Info)); |
| } |
| |
| DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P, |
| uint16_t Stage) |
| : Version(0) { |
| memset(&Info, 0, sizeof(Info)); |
| memcpy(&Info, P, sizeof(dxbc::PSV::v0::RuntimeInfo)); |
| |
| assert(Stage < std::numeric_limits<uint8_t>::max() && |
| "Stage should be a very small number"); |
| // We need to bring the stage in separately since it isn't part of the v1 data |
| // structure. |
| Info.ShaderStage = static_cast<uint8_t>(Stage); |
| } |
| |
| DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P) |
| : Version(1) { |
| memset(&Info, 0, sizeof(Info)); |
| memcpy(&Info, P, sizeof(dxbc::PSV::v1::RuntimeInfo)); |
| } |
| |
| DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P) |
| : Version(2) { |
| memset(&Info, 0, sizeof(Info)); |
| memcpy(&Info, P, sizeof(dxbc::PSV::v2::RuntimeInfo)); |
| } |
| |
| DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P, |
| StringRef StringTable) |
| : Version(3), |
| EntryName(StringTable.substr(P->EntryNameOffset, |
| StringTable.find('\0', P->EntryNameOffset) - |
| P->EntryNameOffset)) { |
| memset(&Info, 0, sizeof(Info)); |
| memcpy(&Info, P, sizeof(dxbc::PSV::v3::RuntimeInfo)); |
| } |
| |
| namespace yaml { |
| |
| void MappingTraits<DXContainerYAML::VersionTuple>::mapping( |
| IO &IO, DXContainerYAML::VersionTuple &Version) { |
| IO.mapRequired("Major", Version.Major); |
| IO.mapRequired("Minor", Version.Minor); |
| } |
| |
| void MappingTraits<DXContainerYAML::FileHeader>::mapping( |
| IO &IO, DXContainerYAML::FileHeader &Header) { |
| IO.mapRequired("Hash", Header.Hash); |
| IO.mapRequired("Version", Header.Version); |
| IO.mapOptional("FileSize", Header.FileSize); |
| IO.mapRequired("PartCount", Header.PartCount); |
| IO.mapOptional("PartOffsets", Header.PartOffsets); |
| } |
| |
| void MappingTraits<DXContainerYAML::DXILProgram>::mapping( |
| IO &IO, DXContainerYAML::DXILProgram &Program) { |
| IO.mapRequired("MajorVersion", Program.MajorVersion); |
| IO.mapRequired("MinorVersion", Program.MinorVersion); |
| IO.mapRequired("ShaderKind", Program.ShaderKind); |
| IO.mapOptional("Size", Program.Size); |
| IO.mapRequired("DXILMajorVersion", Program.DXILMajorVersion); |
| IO.mapRequired("DXILMinorVersion", Program.DXILMinorVersion); |
| IO.mapOptional("DXILSize", Program.DXILSize); |
| IO.mapOptional("DXIL", Program.DXIL); |
| } |
| |
| void MappingTraits<DXContainerYAML::ShaderFeatureFlags>::mapping( |
| IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags) { |
| #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \ |
| IO.mapRequired(#Val, Flags.Val); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| void MappingTraits<DXContainerYAML::ShaderHash>::mapping( |
| IO &IO, DXContainerYAML::ShaderHash &Hash) { |
| IO.mapRequired("IncludesSource", Hash.IncludesSource); |
| IO.mapRequired("Digest", Hash.Digest); |
| } |
| |
| void MappingTraits<DXContainerYAML::PSVInfo>::mapping( |
| IO &IO, DXContainerYAML::PSVInfo &PSV) { |
| IO.mapRequired("Version", PSV.Version); |
| |
| // Store the PSV version in the YAML context. |
| void *OldContext = IO.getContext(); |
| uint32_t Version = PSV.Version; |
| IO.setContext(&Version); |
| |
| // Restore the YAML context on function exit. |
| llvm::scope_exit RestoreContext([&]() { IO.setContext(OldContext); }); |
| |
| // Shader stage is only included in binaries for v1 and later, but we always |
| // include it since it simplifies parsing and file construction. |
| IO.mapRequired("ShaderStage", PSV.Info.ShaderStage); |
| PSV.mapInfoForVersion(IO); |
| |
| IO.mapRequired("ResourceStride", PSV.ResourceStride); |
| if (PSV.Version > 0) { |
| IO.mapOptional("RuntimeInfoSize", PSV.RuntimeInfoSize); |
| IO.mapOptional("StringTable", PSV.StringTable); |
| } |
| IO.mapRequired("Resources", PSV.Resources); |
| if (PSV.Version == 0) |
| return; |
| IO.mapRequired("SigInputElements", PSV.SigInputElements); |
| IO.mapRequired("SigOutputElements", PSV.SigOutputElements); |
| IO.mapRequired("SigPatchOrPrimElements", PSV.SigPatchOrPrimElements); |
| |
| Triple::EnvironmentType Stage = dxbc::getShaderStage(PSV.Info.ShaderStage); |
| if (PSV.Info.UsesViewID) { |
| MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks( |
| PSV.OutputVectorMasks); |
| IO.mapRequired("OutputVectorMasks", MutableOutMasks); |
| if (Stage == Triple::EnvironmentType::Hull) |
| IO.mapRequired("PatchOrPrimMasks", PSV.PatchOrPrimMasks); |
| } |
| MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap( |
| PSV.InputOutputMap); |
| IO.mapRequired("InputOutputMap", MutableIOMap); |
| |
| if (Stage == Triple::EnvironmentType::Hull) |
| IO.mapRequired("InputPatchMap", PSV.InputPatchMap); |
| |
| if (Stage == Triple::EnvironmentType::Domain) |
| IO.mapRequired("PatchOutputMap", PSV.PatchOutputMap); |
| } |
| |
| void MappingTraits<DXContainerYAML::SignatureParameter>::mapping( |
| IO &IO, DXContainerYAML::SignatureParameter &S) { |
| IO.mapRequired("Stream", S.Stream); |
| IO.mapRequired("Name", S.Name); |
| IO.mapRequired("Index", S.Index); |
| IO.mapRequired("SystemValue", S.SystemValue); |
| IO.mapRequired("CompType", S.CompType); |
| IO.mapRequired("Register", S.Register); |
| IO.mapRequired("Mask", S.Mask); |
| IO.mapRequired("ExclusiveMask", S.ExclusiveMask); |
| IO.mapRequired("MinPrecision", S.MinPrecision); |
| } |
| |
| void MappingTraits<DXContainerYAML::Signature>::mapping( |
| IO &IO, DXContainerYAML::Signature &S) { |
| IO.mapRequired("Parameters", S.Parameters); |
| } |
| |
| void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping( |
| IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) { |
| IO.mapRequired("Version", S.Version); |
| IO.mapRequired("NumRootParameters", S.NumRootParameters); |
| IO.mapOptional("RootParametersOffset", S.RootParametersOffset, std::nullopt); |
| IO.mapRequired("NumStaticSamplers", S.NumStaticSamplers); |
| IO.mapOptional("StaticSamplersOffset", S.StaticSamplersOffset, std::nullopt); |
| IO.mapRequired("Parameters", S.Parameters.Locations, S); |
| IO.mapOptional("Samplers", S.StaticSamplers); |
| #define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping( |
| IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) { |
| IO.mapRequired("RangeType", R.RangeType); |
| // handling the edge case where NumDescriptors might be -1 |
| if (IO.outputting()) { |
| if (R.NumDescriptors == UINT_MAX) { |
| int32_t NegOne = -1; |
| IO.mapRequired("NumDescriptors", NegOne); |
| } else |
| IO.mapRequired("NumDescriptors", R.NumDescriptors); |
| } else { |
| int32_t TmpNumDesc = 0; |
| IO.mapRequired("NumDescriptors", TmpNumDesc); |
| R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc); |
| } |
| |
| IO.mapRequired("BaseShaderRegister", R.BaseShaderRegister); |
| IO.mapRequired("RegisterSpace", R.RegisterSpace); |
| IO.mapRequired("OffsetInDescriptorsFromTableStart", |
| R.OffsetInDescriptorsFromTableStart); |
| #define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) \ |
| IO.mapOptional(#Flag, R.Enum, false); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping( |
| IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) { |
| IO.mapRequired("NumRanges", T.NumRanges); |
| IO.mapOptional("RangesOffset", T.RangesOffset); |
| IO.mapRequired("Ranges", T.Ranges); |
| } |
| |
| void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml, |
| DXContainerYAML::RootSignatureYamlDesc>:: |
| mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L, |
| DXContainerYAML::RootSignatureYamlDesc &S) { |
| IO.mapRequired("ParameterType", L.Header.Type); |
| IO.mapRequired("ShaderVisibility", L.Header.Visibility); |
| |
| switch (L.Header.Type) { |
| case dxbc::RootParameterType::Constants32Bit: { |
| DXContainerYAML::RootConstantsYaml &Constants = |
| S.Parameters.getOrInsertConstants(L); |
| IO.mapRequired("Constants", Constants); |
| break; |
| } |
| case dxbc::RootParameterType::CBV: |
| case dxbc::RootParameterType::SRV: |
| case dxbc::RootParameterType::UAV: { |
| DXContainerYAML::RootDescriptorYaml &Descriptor = |
| S.Parameters.getOrInsertDescriptor(L); |
| IO.mapRequired("Descriptor", Descriptor); |
| break; |
| } |
| case dxbc::RootParameterType::DescriptorTable: { |
| DXContainerYAML::DescriptorTableYaml &Table = |
| S.Parameters.getOrInsertTable(L); |
| IO.mapRequired("Table", Table); |
| break; |
| } |
| } |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping( |
| IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) { |
| IO.mapRequired("Num32BitValues", C.Num32BitValues); |
| IO.mapRequired("RegisterSpace", C.RegisterSpace); |
| IO.mapRequired("ShaderRegister", C.ShaderRegister); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping( |
| IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) { |
| IO.mapRequired("RegisterSpace", D.RegisterSpace); |
| IO.mapRequired("ShaderRegister", D.ShaderRegister); |
| #define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) \ |
| IO.mapOptional(#Flag, D.Enum, false); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping( |
| IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) { |
| |
| IO.mapOptional("Filter", S.Filter); |
| IO.mapOptional("AddressU", S.AddressU); |
| IO.mapOptional("AddressV", S.AddressV); |
| IO.mapOptional("AddressW", S.AddressW); |
| IO.mapOptional("MipLODBias", S.MipLODBias); |
| IO.mapOptional("MaxAnisotropy", S.MaxAnisotropy); |
| IO.mapOptional("ComparisonFunc", S.ComparisonFunc); |
| IO.mapOptional("BorderColor", S.BorderColor); |
| IO.mapOptional("MinLOD", S.MinLOD); |
| IO.mapOptional("MaxLOD", S.MaxLOD); |
| IO.mapRequired("ShaderRegister", S.ShaderRegister); |
| IO.mapRequired("RegisterSpace", S.RegisterSpace); |
| IO.mapRequired("ShaderVisibility", S.ShaderVisibility); |
| #define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \ |
| IO.mapOptional(#Flag, S.Enum, false); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| void MappingTraits<DXContainerYAML::DebugName>::mapping( |
| IO &IO, DXContainerYAML::DebugName &DebugName) { |
| IO.mapOptional("Flags", DebugName.Flags); |
| IO.mapOptional("NameLength", DebugName.NameLength); |
| IO.mapRequired("DebugName", DebugName.Filename); |
| } |
| |
| void MappingTraits<DXContainerYAML::CompilerVersion>::mapping( |
| IO &IO, DXContainerYAML::CompilerVersion &CompilerVersion) { |
| IO.mapOptional("Major", CompilerVersion.Major); |
| IO.mapOptional("Minor", CompilerVersion.Minor); |
| IO.mapOptional("IsDebugBuild", CompilerVersion.IsDebugBuild); |
| IO.mapOptional("IsValidated", CompilerVersion.IsValidated); |
| IO.mapOptional("CommitCount", CompilerVersion.CommitCount); |
| IO.mapOptional("ContentSizeInBytes", CompilerVersion.ContentSizeInBytes); |
| IO.mapOptional("CommitSha", CompilerVersion.CommitSha); |
| IO.mapOptional("CustomVersionString", CompilerVersion.CustomVersionString); |
| } |
| |
| void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO, |
| DXContainerYAML::Part &P) { |
| IO.mapRequired("Name", P.Name); |
| IO.mapRequired("Size", P.Size); |
| IO.mapOptional("Program", P.Program); |
| IO.mapOptional("Flags", P.Flags); |
| IO.mapOptional("Hash", P.Hash); |
| IO.mapOptional("PSVInfo", P.Info); |
| IO.mapOptional("Signature", P.Signature); |
| IO.mapOptional("RootSignature", P.RootSignature); |
| IO.mapOptional("DebugName", P.DebugName); |
| IO.mapOptional("CompilerVersion", P.CompilerVersion); |
| IO.mapOptional("SourceInfo", P.SourceInfo); |
| IO.mapOptional("PrivateData", P.PrivateData); |
| } |
| |
| void MappingTraits<DXContainerYAML::Object>::mapping( |
| IO &IO, DXContainerYAML::Object &Obj) { |
| IO.mapTag("!dxcontainer", true); |
| IO.mapRequired("Header", Obj.Header); |
| IO.mapRequired("Parts", Obj.Parts); |
| } |
| |
| void MappingTraits<DXContainerYAML::ResourceFlags>::mapping( |
| IO &IO, DXContainerYAML::ResourceFlags &Flags) { |
| #define RESOURCE_FLAG(FlagIndex, Enum) IO.mapRequired(#Enum, Flags.Bits.Enum); |
| #include "llvm/BinaryFormat/DXContainerConstants.def" |
| } |
| |
| void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping( |
| IO &IO, DXContainerYAML::ResourceBindInfo &Res) { |
| IO.mapRequired("Type", Res.Type); |
| IO.mapRequired("Space", Res.Space); |
| IO.mapRequired("LowerBound", Res.LowerBound); |
| IO.mapRequired("UpperBound", Res.UpperBound); |
| |
| const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext()); |
| if (*PSVVersion < 2) |
| return; |
| |
| IO.mapRequired("Kind", Res.Kind); |
| IO.mapRequired("Flags", Res.Flags); |
| } |
| |
| void MappingTraits<DXContainerYAML::SignatureElement>::mapping( |
| IO &IO, DXContainerYAML::SignatureElement &El) { |
| IO.mapRequired("Name", El.Name); |
| IO.mapRequired("Indices", El.Indices); |
| IO.mapRequired("StartRow", El.StartRow); |
| IO.mapRequired("Cols", El.Cols); |
| IO.mapRequired("StartCol", El.StartCol); |
| IO.mapRequired("Allocated", El.Allocated); |
| IO.mapRequired("Kind", El.Kind); |
| IO.mapRequired("ComponentType", El.Type); |
| IO.mapRequired("Interpolation", El.Mode); |
| IO.mapRequired("DynamicMask", El.DynamicMask); |
| IO.mapRequired("Stream", El.Stream); |
| } |
| |
| void MappingTraits<DXContainerYAML::StringTableEntry>::mapping( |
| IO &IO, DXContainerYAML::StringTableEntry &E) { |
| IO.mapRequired("String", E.String); |
| IO.mapRequired("Offset", E.Offset); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration( |
| IO &IO, dxbc::PSV::SemanticKind &Value) { |
| for (const auto &E : dxbc::PSV::getSemanticKinds()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration( |
| IO &IO, dxbc::PSV::ComponentType &Value) { |
| for (const auto &E : dxbc::PSV::getComponentTypes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration( |
| IO &IO, dxbc::PSV::InterpolationMode &Value) { |
| for (const auto &E : dxbc::PSV::getInterpolationModes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration( |
| IO &IO, dxbc::PSV::ResourceType &Value) { |
| for (const auto &E : dxbc::PSV::getResourceTypes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration( |
| IO &IO, dxbc::PSV::ResourceKind &Value) { |
| for (const auto &E : dxbc::PSV::getResourceKinds()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration( |
| IO &IO, dxbc::D3DSystemValue &Value) { |
| for (const auto &E : dxbc::getD3DSystemValues()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration( |
| IO &IO, dxbc::SigMinPrecision &Value) { |
| for (const auto &E : dxbc::getSigMinPrecisions()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration( |
| IO &IO, dxbc::SigComponentType &Value) { |
| for (const auto &E : dxbc::getSigComponentTypes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::RootParameterType>::enumeration( |
| IO &IO, dxbc::RootParameterType &Value) { |
| for (const auto &E : dxbc::getRootParameterTypes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxil::ResourceClass>::enumeration( |
| IO &IO, dxil::ResourceClass &Value) { |
| constexpr EnumStringDef<dxil::ResourceClass> ResourceClassDefs[] = { |
| {{"CBuffer"}, dxil::ResourceClass::CBuffer}, |
| {{"SRV"}, dxil::ResourceClass::SRV}, |
| {{"UAV"}, dxil::ResourceClass::UAV}, |
| {{"Sampler"}, dxil::ResourceClass::Sampler}, |
| }; |
| static constexpr auto ResourceClasses = BUILD_ENUM_STRINGS(ResourceClassDefs); |
| |
| for (const auto &E : EnumStrings(ResourceClasses)) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::SamplerFilter>::enumeration( |
| IO &IO, dxbc::SamplerFilter &Value) { |
| for (const auto &E : dxbc::getSamplerFilters()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::StaticBorderColor>::enumeration( |
| IO &IO, dxbc::StaticBorderColor &Value) { |
| for (const auto &E : dxbc::getStaticBorderColors()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::TextureAddressMode>::enumeration( |
| IO &IO, dxbc::TextureAddressMode &Value) { |
| for (const auto &E : dxbc::getTextureAddressModes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::ShaderVisibility>::enumeration( |
| IO &IO, dxbc::ShaderVisibility &Value) { |
| for (const auto &E : dxbc::getShaderVisibility()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<dxbc::ComparisonFunc>::enumeration( |
| IO &IO, dxbc::ComparisonFunc &Value) { |
| for (const auto &E : dxbc::getComparisonFuncs()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits<llvm::dxbc::SourceInfo::SectionType>::enumeration( |
| IO &IO, llvm::dxbc::SourceInfo::SectionType &Value) { |
| for (const auto &E : dxbc::SourceInfo::getSectionTypes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void ScalarEnumerationTraits< |
| llvm::dxbc::SourceInfo::Contents::CompressionType>:: |
| enumeration(IO &IO, |
| llvm::dxbc::SourceInfo::Contents::CompressionType &Value) { |
| for (const auto &E : dxbc::SourceInfo::Contents::getCompressionTypes()) |
| IO.enumCase(Value, E.name(), E.value()); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::Header>::mapping( |
| IO &IO, llvm::DXContainerYAML::SourceInfo::Header &H) { |
| IO.mapOptional("AlignedSizeInBytes", H.AlignedSizeInBytes); |
| IO.mapOptional("Flags", H.Flags); |
| IO.mapOptional("SectionCount", H.SectionCount); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SectionHeader>::mapping( |
| IO &IO, llvm::DXContainerYAML::SourceInfo::SectionHeader &H) { |
| IO.mapOptional("AlignedSizeInBytes", H.AlignedSizeInBytes); |
| IO.mapOptional("Flags", H.Flags); |
| IO.mapOptional("Type", H.Type); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames::Header>:: |
| mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames::Header &H) { |
| IO.mapOptional("Flags", H.Flags); |
| IO.mapOptional("Count", H.Count); |
| IO.mapOptional("EntriesSizeInBytes", H.EntriesSizeInBytes); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames::Entry>:: |
| mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames::Entry &E) { |
| IO.mapOptional("AlignedSizeInBytes", E.AlignedSizeInBytes); |
| IO.mapOptional("Flags", E.Flags); |
| IO.mapOptional("NameSizeInBytes", E.NameSizeInBytes); |
| IO.mapOptional("ContentSizeInBytes", E.ContentSizeInBytes); |
| IO.mapRequired("FileName", E.FileName); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames>::mapping( |
| IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames &S) { |
| IO.mapRequired("SectionHeader", S.GenericHeader); |
| IO.mapRequired("Header", S.Parameters); |
| IO.mapRequired("Entries", S.Entries); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents::Header>:: |
| mapping(IO &IO, |
| llvm::DXContainerYAML::SourceInfo::SourceContents::Header &H) { |
| IO.mapOptional("AlignedSizeInBytes", H.AlignedSizeInBytes); |
| IO.mapOptional("Flags", H.Flags); |
| IO.mapRequired("Type", H.Type); |
| IO.mapOptional("EntriesSizeInBytes", H.EntriesSizeInBytes); |
| IO.mapOptional("UncompressedEntriesSizeInBytes", |
| H.UncompressedEntriesSizeInBytes); |
| IO.mapOptional("Count", H.Count); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents::Entry>:: |
| mapping(IO &IO, |
| llvm::DXContainerYAML::SourceInfo::SourceContents::Entry &E) { |
| IO.mapOptional("AlignedSizeInBytes", E.AlignedSizeInBytes); |
| IO.mapOptional("Flags", E.Flags); |
| IO.mapOptional("ContentSizeInBytes", E.ContentSizeInBytes); |
| IO.mapRequired("FileContent", E.FileContent); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents>::mapping( |
| IO &IO, llvm::DXContainerYAML::SourceInfo::SourceContents &S) { |
| IO.mapRequired("SectionHeader", S.GenericHeader); |
| IO.mapRequired("Header", S.Parameters); |
| IO.mapRequired("Entries", S.Entries); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::ProgramArgs::Header>:: |
| mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::ProgramArgs::Header &H) { |
| IO.mapOptional("Flags", H.Flags); |
| IO.mapOptional("SizeInBytes", H.SizeInBytes); |
| IO.mapOptional("Count", H.Count); |
| } |
| |
| void MappingTraits<mcdxbc::SourceInfo::ProgramArgs::Entry>::mapping( |
| IO &IO, mcdxbc::SourceInfo::ProgramArgs::Entry &E) { |
| IO.mapRequired("Arg", E.first); |
| IO.mapRequired("Value", E.second); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo::ProgramArgs>::mapping( |
| IO &IO, llvm::DXContainerYAML::SourceInfo::ProgramArgs &S) { |
| IO.mapRequired("SectionHeader", S.GenericHeader); |
| IO.mapRequired("Header", S.Parameters); |
| IO.mapRequired("Args", S.Args); |
| } |
| |
| void MappingTraits<llvm::DXContainerYAML::SourceInfo>::mapping( |
| IO &IO, llvm::DXContainerYAML::SourceInfo &S) { |
| IO.mapRequired("Header", S.Parameters); |
| IO.mapRequired("Names", S.Names); |
| IO.mapRequired("Contents", S.Contents); |
| IO.mapRequired("Args", S.Args); |
| } |
| |
| } // namespace yaml |
| |
| void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) { |
| dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo; |
| Triple::EnvironmentType Stage = dxbc::getShaderStage(Info.ShaderStage); |
| |
| switch (Stage) { |
| case Triple::EnvironmentType::Pixel: |
| IO.mapRequired("DepthOutput", StageInfo.PS.DepthOutput); |
| IO.mapRequired("SampleFrequency", StageInfo.PS.SampleFrequency); |
| break; |
| case Triple::EnvironmentType::Vertex: |
| IO.mapRequired("OutputPositionPresent", StageInfo.VS.OutputPositionPresent); |
| break; |
| case Triple::EnvironmentType::Geometry: |
| IO.mapRequired("InputPrimitive", StageInfo.GS.InputPrimitive); |
| IO.mapRequired("OutputTopology", StageInfo.GS.OutputTopology); |
| IO.mapRequired("OutputStreamMask", StageInfo.GS.OutputStreamMask); |
| IO.mapRequired("OutputPositionPresent", StageInfo.GS.OutputPositionPresent); |
| break; |
| case Triple::EnvironmentType::Hull: |
| IO.mapRequired("InputControlPointCount", |
| StageInfo.HS.InputControlPointCount); |
| IO.mapRequired("OutputControlPointCount", |
| StageInfo.HS.OutputControlPointCount); |
| IO.mapRequired("TessellatorDomain", StageInfo.HS.TessellatorDomain); |
| IO.mapRequired("TessellatorOutputPrimitive", |
| StageInfo.HS.TessellatorOutputPrimitive); |
| break; |
| case Triple::EnvironmentType::Domain: |
| IO.mapRequired("InputControlPointCount", |
| StageInfo.DS.InputControlPointCount); |
| IO.mapRequired("OutputPositionPresent", StageInfo.DS.OutputPositionPresent); |
| IO.mapRequired("TessellatorDomain", StageInfo.DS.TessellatorDomain); |
| break; |
| case Triple::EnvironmentType::Mesh: |
| IO.mapRequired("GroupSharedBytesUsed", StageInfo.MS.GroupSharedBytesUsed); |
| IO.mapRequired("GroupSharedBytesDependentOnViewID", |
| StageInfo.MS.GroupSharedBytesDependentOnViewID); |
| IO.mapRequired("PayloadSizeInBytes", StageInfo.MS.PayloadSizeInBytes); |
| IO.mapRequired("MaxOutputVertices", StageInfo.MS.MaxOutputVertices); |
| IO.mapRequired("MaxOutputPrimitives", StageInfo.MS.MaxOutputPrimitives); |
| break; |
| case Triple::EnvironmentType::Amplification: |
| IO.mapRequired("PayloadSizeInBytes", StageInfo.AS.PayloadSizeInBytes); |
| break; |
| default: |
| break; |
| } |
| |
| IO.mapRequired("MinimumWaveLaneCount", Info.MinimumWaveLaneCount); |
| IO.mapRequired("MaximumWaveLaneCount", Info.MaximumWaveLaneCount); |
| |
| if (Version == 0) |
| return; |
| |
| IO.mapRequired("UsesViewID", Info.UsesViewID); |
| |
| switch (Stage) { |
| case Triple::EnvironmentType::Geometry: |
| IO.mapRequired("MaxVertexCount", Info.GeomData.MaxVertexCount); |
| break; |
| case Triple::EnvironmentType::Hull: |
| case Triple::EnvironmentType::Domain: |
| IO.mapRequired("SigPatchConstOrPrimVectors", |
| Info.GeomData.SigPatchConstOrPrimVectors); |
| break; |
| case Triple::EnvironmentType::Mesh: |
| IO.mapRequired("SigPrimVectors", Info.GeomData.MeshInfo.SigPrimVectors); |
| IO.mapRequired("MeshOutputTopology", |
| Info.GeomData.MeshInfo.MeshOutputTopology); |
| break; |
| default: |
| break; |
| } |
| |
| IO.mapRequired("SigInputVectors", Info.SigInputVectors); |
| MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors); |
| IO.mapRequired("SigOutputVectors", Vec); |
| |
| if (Version == 1) |
| return; |
| |
| IO.mapRequired("NumThreadsX", Info.NumThreadsX); |
| IO.mapRequired("NumThreadsY", Info.NumThreadsY); |
| IO.mapRequired("NumThreadsZ", Info.NumThreadsZ); |
| |
| if (Version == 2) |
| return; |
| |
| IO.mapRequired("EntryName", EntryName); |
| } |
| |
| static DXContainerYAML::Signature |
| dumpSignature(const object::DirectX::Signature &Sig) { |
| DXContainerYAML::Signature YAML; |
| for (auto Param : Sig) |
| YAML.Parameters.push_back(DXContainerYAML::SignatureParameter{ |
| Param.Stream, Sig.getName(Param.NameOffset).str(), Param.Index, |
| Param.SystemValue, Param.CompType, Param.Register, Param.Mask, |
| Param.ExclusiveMask, Param.MinPrecision}); |
| return YAML; |
| } |
| |
| static void assign(DXContainerYAML::SourceInfo::SectionHeader &Dst, |
| const dxbc::SourceInfo::SectionHeader &Src) { |
| Dst.AlignedSizeInBytes = Src.AlignedSizeInBytes; |
| Dst.Flags = Src.Flags; |
| Dst.Type = Src.Type; |
| } |
| |
| Expected<std::unique_ptr<DXContainerYAML::Object>> |
| DXContainerYAML::fromDXContainer(object::DXContainer &Container) { |
| std::unique_ptr<DXContainerYAML::Object> Obj = |
| std::make_unique<DXContainerYAML::Object>(); |
| |
| for (uint8_t Byte : Container.getHeader().FileHash.Digest) |
| Obj->Header.Hash.push_back(Byte); |
| Obj->Header.Version.Major = Container.getHeader().Version.Major; |
| Obj->Header.Version.Minor = Container.getHeader().Version.Minor; |
| Obj->Header.FileSize = Container.getHeader().FileSize; |
| Obj->Header.PartCount = Container.getHeader().PartCount; |
| |
| Obj->Header.PartOffsets = std::vector<uint32_t>(); |
| for (const auto P : Container) { |
| Obj->Header.PartOffsets->push_back(P.Offset); |
| Obj->Parts.push_back( |
| DXContainerYAML::Part(P.Part.getName().str(), P.Part.Size)); |
| DXContainerYAML::Part &NewPart = Obj->Parts.back(); |
| dxbc::PartType PT = dxbc::parsePartType(P.Part.getName()); |
| switch (PT) { |
| case dxbc::PartType::DXIL: |
| case dxbc::PartType::ILDB: { |
| std::optional<object::DXContainer::DXILData> DXIL = |
| Container.getDXIL(dxbc::isDebugProgramPart(PT)); |
| assert(DXIL && "Since we are iterating and found a DXIL/ILDB part, " |
| "this should never not have a value"); |
| NewPart.Program = DXContainerYAML::DXILProgram{ |
| DXIL->first.getMajorVersion(), |
| DXIL->first.getMinorVersion(), |
| DXIL->first.ShaderKind, |
| DXIL->first.Size, |
| DXIL->first.Bitcode.MajorVersion, |
| DXIL->first.Bitcode.MinorVersion, |
| DXIL->first.Bitcode.Offset, |
| DXIL->first.Bitcode.Size, |
| std::vector<llvm::yaml::Hex8>( |
| DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)}; |
| break; |
| } |
| case dxbc::PartType::ILDN: { |
| std::optional<mcdxbc::DebugName> DebugName = Container.getDebugName(); |
| assert(DebugName && "Since we are iterating and found a ILDN part, this " |
| "should never not have a value"); |
| NewPart.DebugName = DXContainerYAML::DebugName{ |
| DebugName->Parameters.Flags, DebugName->Parameters.NameLength, |
| DebugName->Filename.str()}; |
| break; |
| } |
| case dxbc::PartType::PRIV: { |
| std::optional<StringRef> PrivateData = Container.getPrivateData(); |
| assert(PrivateData && "Since we are iterating and found a PRIV part, " |
| "this should never not have a value"); |
| NewPart.PrivateData.emplace(PrivateData->data(), |
| PrivateData->data() + PrivateData->size()); |
| break; |
| } |
| case dxbc::PartType::SFI0: { |
| std::optional<uint64_t> Flags = Container.getShaderFeatureFlags(); |
| // Omit the flags in the YAML if they are missing or zero. |
| if (Flags && *Flags > 0) |
| NewPart.Flags = DXContainerYAML::ShaderFeatureFlags(*Flags); |
| break; |
| } |
| case dxbc::PartType::HASH: { |
| std::optional<dxbc::ShaderHash> Hash = Container.getShaderHash(); |
| if (Hash && Hash->isPopulated()) |
| NewPart.Hash = DXContainerYAML::ShaderHash(*Hash); |
| break; |
| } |
| case dxbc::PartType::PSV0: { |
| const auto &PSVInfo = Container.getPSVInfo(); |
| if (!PSVInfo) |
| break; |
| if (const auto *P = |
| std::get_if<dxbc::PSV::v0::RuntimeInfo>(&PSVInfo->getInfo())) { |
| std::optional<uint16_t> ShaderKind = Container.getShaderKind(); |
| if (!ShaderKind) |
| break; |
| NewPart.Info = DXContainerYAML::PSVInfo(P, *ShaderKind); |
| } else if (const auto *P = std::get_if<dxbc::PSV::v1::RuntimeInfo>( |
| &PSVInfo->getInfo())) |
| NewPart.Info = DXContainerYAML::PSVInfo(P); |
| else if (const auto *P = |
| std::get_if<dxbc::PSV::v2::RuntimeInfo>(&PSVInfo->getInfo())) |
| NewPart.Info = DXContainerYAML::PSVInfo(P); |
| else if (const auto *P = |
| std::get_if<dxbc::PSV::v3::RuntimeInfo>(&PSVInfo->getInfo())) |
| NewPart.Info = DXContainerYAML::PSVInfo(P, PSVInfo->getStringTable()); |
| NewPart.Info->ResourceStride = PSVInfo->getResourceStride(); |
| NewPart.Info->RuntimeInfoSize = PSVInfo->getSize(); |
| if (PSVInfo->getVersion() > 0) { |
| StringRef ST = PSVInfo->getStringTable(); |
| size_t Pos = 0; |
| while (Pos < ST.size()) { |
| size_t End = ST.find('\0', Pos); |
| if (End == StringRef::npos) |
| End = ST.size(); |
| if (End > Pos) |
| NewPart.Info->StringTable.push_back( |
| {ST.slice(Pos, End), static_cast<uint32_t>(Pos)}); |
| Pos = End + 1; |
| } |
| } |
| for (auto Res : PSVInfo->getResources()) |
| NewPart.Info->Resources.push_back(Res); |
| |
| for (auto El : PSVInfo->getSigInputElements()) |
| NewPart.Info->SigInputElements.push_back( |
| DXContainerYAML::SignatureElement( |
| El, PSVInfo->getStringTable(), |
| PSVInfo->getSemanticIndexTable())); |
| for (auto El : PSVInfo->getSigOutputElements()) |
| NewPart.Info->SigOutputElements.push_back( |
| DXContainerYAML::SignatureElement( |
| El, PSVInfo->getStringTable(), |
| PSVInfo->getSemanticIndexTable())); |
| for (auto El : PSVInfo->getSigPatchOrPrimElements()) |
| NewPart.Info->SigPatchOrPrimElements.push_back( |
| DXContainerYAML::SignatureElement( |
| El, PSVInfo->getStringTable(), |
| PSVInfo->getSemanticIndexTable())); |
| |
| if (PSVInfo->usesViewID()) { |
| for (int I = 0; I < 4; ++I) |
| for (auto Mask : PSVInfo->getOutputVectorMasks(I)) |
| NewPart.Info->OutputVectorMasks[I].push_back(Mask); |
| for (auto Mask : PSVInfo->getPatchOrPrimMasks()) |
| NewPart.Info->PatchOrPrimMasks.push_back(Mask); |
| } |
| |
| for (int I = 0; I < 4; ++I) |
| for (auto Mask : PSVInfo->getInputOutputMap(I)) |
| NewPart.Info->InputOutputMap[I].push_back(Mask); |
| |
| for (auto Mask : PSVInfo->getInputPatchMap()) |
| NewPart.Info->InputPatchMap.push_back(Mask); |
| |
| for (auto Mask : PSVInfo->getPatchOutputMap()) |
| NewPart.Info->PatchOutputMap.push_back(Mask); |
| |
| break; |
| } |
| case dxbc::PartType::ISG1: |
| NewPart.Signature = dumpSignature(Container.getInputSignature()); |
| break; |
| case dxbc::PartType::OSG1: |
| NewPart.Signature = dumpSignature(Container.getOutputSignature()); |
| break; |
| case dxbc::PartType::PSG1: |
| NewPart.Signature = dumpSignature(Container.getPatchConstantSignature()); |
| break; |
| case dxbc::PartType::Unknown: |
| break; |
| case dxbc::PartType::RTS0: { |
| std::optional<object::DirectX::RootSignature> RS = |
| Container.getRootSignature(); |
| if (RS.has_value()) { |
| auto RootSigDescOrErr = |
| DXContainerYAML::RootSignatureYamlDesc::create(*RS); |
| if (Error E = RootSigDescOrErr.takeError()) |
| return std::move(E); |
| NewPart.RootSignature = RootSigDescOrErr.get(); |
| } |
| break; |
| } |
| case dxbc::PartType::SRCI: { |
| std::optional<mcdxbc::SourceInfo> SourceInfo = Container.getSourceInfo(); |
| assert(SourceInfo && "Since we are iterating and found a SRCI part, this " |
| "should never not have a value"); |
| auto &SourceInfoYAML = NewPart.SourceInfo.emplace(); |
| SourceInfoYAML.Parameters.AlignedSizeInBytes = |
| SourceInfo->Parameters.AlignedSizeInBytes; |
| SourceInfoYAML.Parameters.Flags = SourceInfo->Parameters.Flags; |
| SourceInfoYAML.Parameters.SectionCount = |
| SourceInfo->Parameters.SectionCount; |
| |
| auto &NamesYAML = SourceInfoYAML.Names; |
| auto &Names = SourceInfo->Names; |
| assign(NamesYAML.GenericHeader, SourceInfo->Names.GenericHeader); |
| NamesYAML.Parameters.Flags = Names.Parameters.Flags; |
| NamesYAML.Parameters.Count = Names.Parameters.Count; |
| NamesYAML.Parameters.EntriesSizeInBytes = |
| Names.Parameters.EntriesSizeInBytes; |
| NamesYAML.Entries.reserve(Names.Entries.size()); |
| for (const auto &NameEntry : Names.Entries) { |
| DXContainerYAML::SourceInfo::SourceNames::Entry NameEntryYAML; |
| NameEntryYAML.AlignedSizeInBytes = |
| NameEntry.Parameters.AlignedSizeInBytes; |
| NameEntryYAML.Flags = NameEntry.Parameters.Flags; |
| NameEntryYAML.NameSizeInBytes = NameEntry.Parameters.NameSizeInBytes; |
| NameEntryYAML.ContentSizeInBytes = |
| NameEntry.Parameters.ContentSizeInBytes; |
| NameEntryYAML.FileName = NameEntry.FileName; |
| NamesYAML.Entries.emplace_back(NameEntryYAML); |
| } |
| |
| auto &ContentsYAML = SourceInfoYAML.Contents; |
| auto &Contents = SourceInfo->Contents; |
| assign(ContentsYAML.GenericHeader, Contents.GenericHeader); |
| ContentsYAML.Parameters.AlignedSizeInBytes = |
| Contents.Parameters.AlignedSizeInBytes; |
| ContentsYAML.Parameters.Flags = Contents.Parameters.Flags; |
| ContentsYAML.Parameters.Type = Contents.Parameters.Type; |
| ContentsYAML.Parameters.EntriesSizeInBytes = |
| Contents.Parameters.EntriesSizeInBytes; |
| ContentsYAML.Parameters.UncompressedEntriesSizeInBytes = |
| Contents.Parameters.UncompressedEntriesSizeInBytes; |
| ContentsYAML.Parameters.Count = Contents.Parameters.Count; |
| ContentsYAML.Entries.reserve(Contents.Entries.size()); |
| for (const auto &ContentEntry : Contents.Entries) { |
| DXContainerYAML::SourceInfo::SourceContents::Entry ContentEntryYAML; |
| ContentEntryYAML.AlignedSizeInBytes = |
| ContentEntry.Parameters.AlignedSizeInBytes; |
| ContentEntryYAML.Flags = ContentEntry.Parameters.Flags; |
| ContentEntryYAML.ContentSizeInBytes = |
| ContentEntry.Parameters.ContentSizeInBytes; |
| ContentEntryYAML.FileContent = ContentEntry.FileContent; |
| ContentsYAML.Entries.emplace_back(ContentEntryYAML); |
| } |
| |
| auto &ArgsYAML = SourceInfoYAML.Args; |
| auto &Args = SourceInfo->Args; |
| assign(ArgsYAML.GenericHeader, Args.GenericHeader); |
| ArgsYAML.Parameters.Flags = Args.Parameters.Flags; |
| ArgsYAML.Parameters.SizeInBytes = Args.Parameters.SizeInBytes; |
| ArgsYAML.Parameters.Count = Args.Parameters.Count; |
| ArgsYAML.Args = Args.Args; |
| break; |
| } |
| case dxbc::PartType::VERS: { |
| std::optional<mcdxbc::CompilerVersion> Version = |
| Container.getCompilerVersionInfo(); |
| assert(Version && "Since we are iterating and found a VERS part, this " |
| "should never not have a value"); |
| NewPart.CompilerVersion.emplace(DXContainerYAML::CompilerVersion{ |
| Version->Parameters.Major, Version->Parameters.Minor, |
| !!(Version->Parameters.Flags & dxbc::CompilerVersionFlags::Debug), |
| !!(Version->Parameters.Flags & dxbc::CompilerVersionFlags::Internal), |
| Version->Parameters.CommitCount, |
| Version->Parameters.ContentSizeInBytes, Version->CommitSha.str(), |
| Version->CustomVersionString.str()}); |
| break; |
| } |
| } |
| } |
| return std::move(Obj); |
| } |
| |
| } // namespace llvm |