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_FLAG(Num, Val, Str) bool Val = false; 60 struct ShaderFlags { 61 ShaderFlags() = default; 62 ShaderFlags(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::v2::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 void mapInfoForVersion(yaml::IO &IO); 125 126 PSVInfo(); 127 PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P, uint16_t Stage); 128 PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P); 129 PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P); 130 }; 131 132 struct SignatureParameter { 133 uint32_t Stream; 134 std::string Name; 135 uint32_t Index; 136 dxbc::D3DSystemValue SystemValue; 137 dxbc::SigComponentType CompType; 138 uint32_t Register; 139 uint8_t Mask; 140 uint8_t ExclusiveMask; 141 dxbc::SigMinPrecision MinPrecision; 142 }; 143 144 struct Signature { 145 llvm::SmallVector<SignatureParameter> Parameters; 146 }; 147 148 struct Part { 149 Part() = default; 150 Part(std::string N, uint32_t S) : Name(N), Size(S) {} 151 std::string Name; 152 uint32_t Size; 153 std::optional<DXILProgram> Program; 154 std::optional<ShaderFlags> Flags; 155 std::optional<ShaderHash> Hash; 156 std::optional<PSVInfo> Info; 157 std::optional<DXContainerYAML::Signature> Signature; 158 }; 159 160 struct Object { 161 FileHeader Header; 162 std::vector<Part> Parts; 163 }; 164 165 } // namespace DXContainerYAML 166 } // namespace llvm 167 168 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part) 169 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo) 170 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement) 171 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector) 172 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter) 173 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind) 174 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType) 175 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode) 176 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::D3DSystemValue) 177 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigComponentType) 178 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::SigMinPrecision) 179 180 namespace llvm { 181 182 class raw_ostream; 183 184 namespace yaml { 185 186 template <> struct MappingTraits<DXContainerYAML::VersionTuple> { 187 static void mapping(IO &IO, DXContainerYAML::VersionTuple &Version); 188 }; 189 190 template <> struct MappingTraits<DXContainerYAML::FileHeader> { 191 static void mapping(IO &IO, DXContainerYAML::FileHeader &Header); 192 }; 193 194 template <> struct MappingTraits<DXContainerYAML::DXILProgram> { 195 static void mapping(IO &IO, DXContainerYAML::DXILProgram &Program); 196 }; 197 198 template <> struct MappingTraits<DXContainerYAML::ShaderFlags> { 199 static void mapping(IO &IO, DXContainerYAML::ShaderFlags &Flags); 200 }; 201 202 template <> struct MappingTraits<DXContainerYAML::ShaderHash> { 203 static void mapping(IO &IO, DXContainerYAML::ShaderHash &Hash); 204 }; 205 206 template <> struct MappingTraits<DXContainerYAML::PSVInfo> { 207 static void mapping(IO &IO, DXContainerYAML::PSVInfo &PSV); 208 }; 209 210 template <> struct MappingTraits<DXContainerYAML::Part> { 211 static void mapping(IO &IO, DXContainerYAML::Part &Version); 212 }; 213 214 template <> struct MappingTraits<DXContainerYAML::Object> { 215 static void mapping(IO &IO, DXContainerYAML::Object &Obj); 216 }; 217 218 template <> struct MappingTraits<DXContainerYAML::ResourceBindInfo> { 219 static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res); 220 }; 221 222 template <> struct MappingTraits<DXContainerYAML::SignatureElement> { 223 static void mapping(IO &IO, llvm::DXContainerYAML::SignatureElement &El); 224 }; 225 226 template <> struct MappingTraits<DXContainerYAML::SignatureParameter> { 227 static void mapping(IO &IO, llvm::DXContainerYAML::SignatureParameter &El); 228 }; 229 230 template <> struct MappingTraits<DXContainerYAML::Signature> { 231 static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El); 232 }; 233 234 } // namespace yaml 235 236 } // namespace llvm 237 238 #endif // LLVM_OBJECTYAML_DXCONTAINERYAML_H 239