1 //===- DXContainerYAML.h - DXContainer YAMLIO implementation ----*- C++ -*-===// 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 /// \file 10 /// This file declares classes for handling the YAML representation 11 /// of DXContainer. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_OBJECTYAML_DXCONTAINERYAML_H 16 #define LLVM_OBJECTYAML_DXCONTAINERYAML_H 17 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/BinaryFormat/DXContainer.h" 20 #include "llvm/ObjectYAML/YAML.h" 21 #include "llvm/Support/YAMLTraits.h" 22 #include <array> 23 #include <cstdint> 24 #include <optional> 25 #include <string> 26 #include <vector> 27 28 namespace llvm { 29 namespace DXContainerYAML { 30 31 struct VersionTuple { 32 uint16_t Major; 33 uint16_t Minor; 34 }; 35 36 // The optional header fields are required in the binary and will be populated 37 // when reading from binary, but can be omitted in the YAML text because the 38 // emitter can calculate them. 39 struct FileHeader { 40 std::vector<llvm::yaml::Hex8> Hash; 41 VersionTuple Version; 42 std::optional<uint32_t> FileSize; 43 uint32_t PartCount; 44 std::optional<std::vector<uint32_t>> PartOffsets; 45 }; 46 47 struct DXILProgram { 48 uint8_t MajorVersion; 49 uint8_t MinorVersion; 50 uint16_t ShaderKind; 51 std::optional<uint32_t> Size; 52 uint16_t DXILMajorVersion; 53 uint16_t DXILMinorVersion; 54 std::optional<uint32_t> DXILOffset; 55 std::optional<uint32_t> DXILSize; 56 std::optional<std::vector<llvm::yaml::Hex8>> DXIL; 57 }; 58 59 #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) bool Val = false; 60 struct ShaderFeatureFlags { 61 ShaderFeatureFlags() = default; 62 ShaderFeatureFlags(uint64_t FlagData); 63 uint64_t getEncodedFlags(); 64 #include "llvm/BinaryFormat/DXContainerConstants.def" 65 }; 66 67 struct ShaderHash { 68 ShaderHash() = default; 69 ShaderHash(const dxbc::ShaderHash &Data); 70 71 bool IncludesSource; 72 std::vector<llvm::yaml::Hex8> Digest; 73 }; 74 75 using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo; 76 77 struct SignatureElement { 78 SignatureElement() = default; 79 80 SignatureElement(dxbc::PSV::v0::SignatureElement El, StringRef StringTable, 81 ArrayRef<uint32_t> IdxTable) 82 : Name(StringTable.substr(El.NameOffset, 83 StringTable.find('\0', El.NameOffset) - 84 El.NameOffset)), 85 Indices(IdxTable.slice(El.IndicesOffset, El.Rows)), 86 StartRow(El.StartRow), Cols(El.Cols), StartCol(El.StartCol), 87 Allocated(El.Allocated != 0), Kind(El.Kind), Type(El.Type), 88 Mode(El.Mode), DynamicMask(El.DynamicMask), Stream(El.Stream) {} 89 StringRef Name; 90 SmallVector<uint32_t> Indices; 91 92 uint8_t StartRow; 93 uint8_t Cols; 94 uint8_t StartCol; 95 bool Allocated; 96 dxbc::PSV::SemanticKind Kind; 97 98 dxbc::PSV::ComponentType Type; 99 dxbc::PSV::InterpolationMode Mode; 100 llvm::yaml::Hex8 DynamicMask; 101 uint8_t Stream; 102 }; 103 104 struct PSVInfo { 105 // The version field isn't actually encoded in the file, but it is inferred by 106 // the size of data regions. We include it in the yaml because it simplifies 107 // the format. 108 uint32_t Version; 109 110 dxbc::PSV::v3::RuntimeInfo Info; 111 uint32_t ResourceStride; 112 SmallVector<ResourceBindInfo> Resources; 113 SmallVector<SignatureElement> SigInputElements; 114 SmallVector<SignatureElement> SigOutputElements; 115 SmallVector<SignatureElement> SigPatchOrPrimElements; 116 117 using MaskVector = SmallVector<llvm::yaml::Hex32>; 118 std::array<MaskVector, 4> OutputVectorMasks; 119 MaskVector PatchOrPrimMasks; 120 std::array<MaskVector, 4> InputOutputMap; 121 MaskVector InputPatchMap; 122 MaskVector PatchOutputMap; 123 124 StringRef EntryName; 125 126 void mapInfoForVersion(yaml::IO &IO); 127 128 PSVInfo(); 129 PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P, uint16_t Stage); 130 PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P); 131 PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P); 132 PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P, StringRef StringTable); 133 }; 134 135 struct SignatureParameter { 136 uint32_t Stream; 137 std::string Name; 138 uint32_t Index; 139 dxbc::D3DSystemValue SystemValue; 140 dxbc::SigComponentType CompType; 141 uint32_t Register; 142 uint8_t Mask; 143 uint8_t ExclusiveMask; 144 dxbc::SigMinPrecision MinPrecision; 145 }; 146 147 struct Signature { 148 llvm::SmallVector<SignatureParameter> Parameters; 149 }; 150 151 struct Part { 152 Part() = default; 153 Part(std::string N, uint32_t S) : Name(N), Size(S) {} 154 std::string Name; 155 uint32_t Size; 156 std::optional<DXILProgram> Program; 157 std::optional<ShaderFeatureFlags> Flags; 158 std::optional<ShaderHash> Hash; 159 std::optional<PSVInfo> Info; 160 std::optional<DXContainerYAML::Signature> Signature; 161 }; 162 163 struct Object { 164 FileHeader Header; 165 std::vector<Part> Parts; 166 }; 167 168 } // namespace DXContainerYAML 169 } // namespace llvm 170 171 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part) 172 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo) 173 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement) 174 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector) 175 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter) 176 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind) 177 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType) 178 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode) 179 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::D3DSystemValue) 180 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigComponentType) 181 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigMinPrecision) 182 183 namespace llvm { 184 185 class raw_ostream; 186 187 namespace yaml { 188 189 template <> struct MappingTraits<DXContainerYAML::VersionTuple> { 190 static void mapping(IO &IO, DXContainerYAML::VersionTuple &Version); 191 }; 192 193 template <> struct MappingTraits<DXContainerYAML::FileHeader> { 194 static void mapping(IO &IO, DXContainerYAML::FileHeader &Header); 195 }; 196 197 template <> struct MappingTraits<DXContainerYAML::DXILProgram> { 198 static void mapping(IO &IO, DXContainerYAML::DXILProgram &Program); 199 }; 200 201 template <> struct MappingTraits<DXContainerYAML::ShaderFeatureFlags> { 202 static void mapping(IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags); 203 }; 204 205 template <> struct MappingTraits<DXContainerYAML::ShaderHash> { 206 static void mapping(IO &IO, DXContainerYAML::ShaderHash &Hash); 207 }; 208 209 template <> struct MappingTraits<DXContainerYAML::PSVInfo> { 210 static void mapping(IO &IO, DXContainerYAML::PSVInfo &PSV); 211 }; 212 213 template <> struct MappingTraits<DXContainerYAML::Part> { 214 static void mapping(IO &IO, DXContainerYAML::Part &Version); 215 }; 216 217 template <> struct MappingTraits<DXContainerYAML::Object> { 218 static void mapping(IO &IO, DXContainerYAML::Object &Obj); 219 }; 220 221 template <> struct MappingTraits<DXContainerYAML::ResourceBindInfo> { 222 static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res); 223 }; 224 225 template <> struct MappingTraits<DXContainerYAML::SignatureElement> { 226 static void mapping(IO &IO, llvm::DXContainerYAML::SignatureElement &El); 227 }; 228 229 template <> struct MappingTraits<DXContainerYAML::SignatureParameter> { 230 static void mapping(IO &IO, llvm::DXContainerYAML::SignatureParameter &El); 231 }; 232 233 template <> struct MappingTraits<DXContainerYAML::Signature> { 234 static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El); 235 }; 236 237 } // namespace yaml 238 239 } // namespace llvm 240 241 #endif // LLVM_OBJECTYAML_DXCONTAINERYAML_H 242