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
SignatureElementSignatureElement80 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;
PartPart153 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)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo)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