//===- DXContainerYAML.h - DXContainer YAMLIO implementation ----*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// /// /// \file /// This file declares classes for handling the YAML representation /// of DXContainer. /// //===----------------------------------------------------------------------===// #ifndef LLVM_OBJECTYAML_DXCONTAINERYAML_H #define LLVM_OBJECTYAML_DXCONTAINERYAML_H #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/DXContainer.h" #include "llvm/Object/DXContainer.h" #include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/YAMLTraits.h" #include #include #include #include namespace llvm { namespace DXContainerYAML { struct VersionTuple { uint16_t Major; uint16_t Minor; }; // The optional header fields are required in the binary and will be populated // when reading from binary, but can be omitted in the YAML text because the // emitter can calculate them. struct FileHeader { std::vector Hash; VersionTuple Version; std::optional FileSize; uint32_t PartCount; std::optional> PartOffsets; }; struct DXILProgram { uint8_t MajorVersion; uint8_t MinorVersion; uint16_t ShaderKind; std::optional Size; uint16_t DXILMajorVersion; uint16_t DXILMinorVersion; std::optional DXILOffset; std::optional DXILSize; std::optional> DXIL; }; #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) bool Val = false; struct ShaderFeatureFlags { ShaderFeatureFlags() = default; LLVM_ABI ShaderFeatureFlags(uint64_t FlagData); LLVM_ABI uint64_t getEncodedFlags(); #include "llvm/BinaryFormat/DXContainerConstants.def" }; struct ShaderHash { ShaderHash() = default; LLVM_ABI ShaderHash(const dxbc::ShaderHash &Data); bool IncludesSource; std::vector Digest; }; struct RootConstantsYaml { uint32_t ShaderRegister; uint32_t RegisterSpace; uint32_t Num32BitValues; }; struct RootDescriptorYaml { RootDescriptorYaml() = default; uint32_t ShaderRegister; uint32_t RegisterSpace; LLVM_ABI uint32_t getEncodedFlags() const; #define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) bool Enum = false; #include "llvm/BinaryFormat/DXContainerConstants.def" }; struct DescriptorRangeYaml { dxil::ResourceClass RangeType; uint32_t NumDescriptors; uint32_t BaseShaderRegister; uint32_t RegisterSpace; uint32_t OffsetInDescriptorsFromTableStart; LLVM_ABI uint32_t getEncodedFlags() const; #define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) bool Enum = false; #include "llvm/BinaryFormat/DXContainerConstants.def" }; struct DescriptorTableYaml { uint32_t NumRanges; uint32_t RangesOffset; SmallVector Ranges; }; struct RootParameterHeaderYaml { dxbc::RootParameterType Type; dxbc::ShaderVisibility Visibility; uint32_t Offset; RootParameterHeaderYaml() = default; RootParameterHeaderYaml(dxbc::RootParameterType T) : Type(T) {} }; struct RootParameterLocationYaml { RootParameterHeaderYaml Header; std::optional IndexInSignature; RootParameterLocationYaml() = default; explicit RootParameterLocationYaml(RootParameterHeaderYaml Header) : Header(Header) {} }; struct RootParameterYamlDesc { SmallVector Locations; SmallVector Constants; SmallVector Descriptors; SmallVector Tables; template T &getOrInsertImpl(RootParameterLocationYaml &ParamDesc, SmallVectorImpl &Container) { if (!ParamDesc.IndexInSignature) { ParamDesc.IndexInSignature = Container.size(); Container.emplace_back(); } return Container[*ParamDesc.IndexInSignature]; } RootConstantsYaml & getOrInsertConstants(RootParameterLocationYaml &ParamDesc) { return getOrInsertImpl(ParamDesc, Constants); } RootDescriptorYaml & getOrInsertDescriptor(RootParameterLocationYaml &ParamDesc) { return getOrInsertImpl(ParamDesc, Descriptors); } DescriptorTableYaml &getOrInsertTable(RootParameterLocationYaml &ParamDesc) { return getOrInsertImpl(ParamDesc, Tables); } void insertLocation(RootParameterLocationYaml &Location) { Locations.push_back(Location); } }; struct StaticSamplerYamlDesc { dxbc::SamplerFilter Filter = dxbc::SamplerFilter::Anisotropic; dxbc::TextureAddressMode AddressU = dxbc::TextureAddressMode::Wrap; dxbc::TextureAddressMode AddressV = dxbc::TextureAddressMode::Wrap; dxbc::TextureAddressMode AddressW = dxbc::TextureAddressMode::Wrap; float MipLODBias = 0.f; uint32_t MaxAnisotropy = 16u; dxbc::ComparisonFunc ComparisonFunc = dxbc::ComparisonFunc::LessEqual; dxbc::StaticBorderColor BorderColor = dxbc::StaticBorderColor::OpaqueWhite; float MinLOD = 0.f; float MaxLOD = std::numeric_limits::max(); uint32_t ShaderRegister; uint32_t RegisterSpace; dxbc::ShaderVisibility ShaderVisibility; LLVM_ABI uint32_t getEncodedFlags() const; #define STATIC_SAMPLER_FLAG(Num, Enum, Flag) bool Enum = false; #include "llvm/BinaryFormat/DXContainerConstants.def" }; struct RootSignatureYamlDesc { RootSignatureYamlDesc() = default; uint32_t Version; uint32_t NumRootParameters; std::optional RootParametersOffset; uint32_t NumStaticSamplers; std::optional StaticSamplersOffset; RootParameterYamlDesc Parameters; SmallVector StaticSamplers; LLVM_ABI uint32_t getEncodedFlags(); iterator_range samplers() { return make_range(StaticSamplers.begin(), StaticSamplers.end()); } LLVM_ABI static llvm::Expected create(const object::DirectX::RootSignature &Data); #define ROOT_SIGNATURE_FLAG(Num, Val) bool Val = false; #include "llvm/BinaryFormat/DXContainerConstants.def" }; using ResourceFlags = dxbc::PSV::ResourceFlags; using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo; struct SignatureElement { SignatureElement() = default; SignatureElement(dxbc::PSV::v0::SignatureElement El, StringRef StringTable, ArrayRef IdxTable) : Name(StringTable.substr(El.NameOffset, StringTable.find('\0', El.NameOffset) - El.NameOffset)), Indices(IdxTable.slice(El.IndicesOffset, El.Rows)), StartRow(El.StartRow), Cols(El.Cols), StartCol(El.StartCol), Allocated(El.Allocated != 0), Kind(El.Kind), Type(El.Type), Mode(El.Mode), DynamicMask(El.DynamicMask), Stream(El.Stream) {} StringRef Name; SmallVector Indices; uint8_t StartRow; uint8_t Cols; uint8_t StartCol; bool Allocated; dxbc::PSV::SemanticKind Kind; dxbc::PSV::ComponentType Type; dxbc::PSV::InterpolationMode Mode; llvm::yaml::Hex8 DynamicMask; uint8_t Stream; }; struct PSVInfo { // The version field isn't actually encoded in the file, but it is inferred by // the size of data regions. We include it in the yaml because it simplifies // the format. uint32_t Version; dxbc::PSV::v3::RuntimeInfo Info; uint32_t ResourceStride; SmallVector Resources; SmallVector SigInputElements; SmallVector SigOutputElements; SmallVector SigPatchOrPrimElements; using MaskVector = SmallVector; std::array OutputVectorMasks; MaskVector PatchOrPrimMasks; std::array InputOutputMap; MaskVector InputPatchMap; MaskVector PatchOutputMap; StringRef EntryName; LLVM_ABI void mapInfoForVersion(yaml::IO &IO); LLVM_ABI PSVInfo(); LLVM_ABI PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P, uint16_t Stage); LLVM_ABI PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P); LLVM_ABI PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P); LLVM_ABI PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P, StringRef StringTable); }; struct SignatureParameter { uint32_t Stream; std::string Name; uint32_t Index; dxbc::D3DSystemValue SystemValue; dxbc::SigComponentType CompType; uint32_t Register; uint8_t Mask; uint8_t ExclusiveMask; dxbc::SigMinPrecision MinPrecision; }; struct Signature { llvm::SmallVector Parameters; }; struct Part { Part() = default; Part(std::string N, uint32_t S) : Name(N), Size(S) {} std::string Name; uint32_t Size; std::optional Program; std::optional Flags; std::optional Hash; std::optional Info; std::optional Signature; std::optional RootSignature; }; struct Object { FileHeader Header; std::vector Parts; }; } // namespace DXContainerYAML } // namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::RootParameterLocationYaml) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::DescriptorRangeYaml) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::StaticSamplerYamlDesc) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ResourceType) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ResourceKind) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::D3DSystemValue) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigComponentType) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigMinPrecision) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::RootParameterType) LLVM_YAML_DECLARE_ENUM_TRAITS(dxil::ResourceClass) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SamplerFilter) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::StaticBorderColor) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::TextureAddressMode) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::ShaderVisibility) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::ComparisonFunc) namespace llvm { class raw_ostream; namespace yaml { template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::VersionTuple &Version); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::FileHeader &Header); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::DXILProgram &Program); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ShaderHash &Hash); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::PSVInfo &PSV); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::Part &Version); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::Object &Obj); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ResourceFlags &Flags); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::SignatureElement &El); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::SignatureParameter &El); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, DXContainerYAML::RootSignatureYamlDesc &RootSignature); }; template <> struct MappingContextTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::RootParameterLocationYaml &L, DXContainerYAML::RootSignatureYamlDesc &S); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &D); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &D); }; template <> struct MappingTraits { LLVM_ABI static void mapping(IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S); }; } // namespace yaml } // namespace llvm #endif // LLVM_OBJECTYAML_DXCONTAINERYAML_H