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 <cstdint>
23 #include <optional>
24 #include <string>
25 #include <vector>
26 
27 namespace llvm {
28 namespace DXContainerYAML {
29 
30 struct VersionTuple {
31   uint16_t Major;
32   uint16_t Minor;
33 };
34 
35 // The optional header fields are required in the binary and will be populated
36 // when reading from binary, but can be omitted in the YAML text because the
37 // emitter can calculate them.
38 struct FileHeader {
39   std::vector<llvm::yaml::Hex8> Hash;
40   VersionTuple Version;
41   std::optional<uint32_t> FileSize;
42   uint32_t PartCount;
43   std::optional<std::vector<uint32_t>> PartOffsets;
44 };
45 
46 struct DXILProgram {
47   uint8_t MajorVersion;
48   uint8_t MinorVersion;
49   uint16_t ShaderKind;
50   std::optional<uint32_t> Size;
51   uint16_t DXILMajorVersion;
52   uint16_t DXILMinorVersion;
53   std::optional<uint32_t> DXILOffset;
54   std::optional<uint32_t> DXILSize;
55   std::optional<std::vector<llvm::yaml::Hex8>> DXIL;
56 };
57 
58 #define SHADER_FLAG(Num, Val, Str) bool Val = false;
59 struct ShaderFlags {
60   ShaderFlags() = default;
61   ShaderFlags(uint64_t FlagData);
62   uint64_t getEncodedFlags();
63 #include "llvm/BinaryFormat/DXContainerConstants.def"
64 };
65 
66 struct ShaderHash {
67   ShaderHash() = default;
68   ShaderHash(const dxbc::ShaderHash &Data);
69 
70   bool IncludesSource;
71   std::vector<llvm::yaml::Hex8> Digest;
72 };
73 
74 using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo;
75 
76 struct PSVInfo {
77   // The version field isn't actually encoded in the file, but it is inferred by
78   // the size of data regions. We include it in the yaml because it simplifies
79   // the format.
80   uint32_t Version;
81 
82   dxbc::PSV::v2::RuntimeInfo Info;
83   uint32_t ResourceStride;
84   std::vector<ResourceBindInfo> Resources;
85 
86   void mapInfoForVersion(yaml::IO &IO);
87 
88   PSVInfo();
89   PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P, uint16_t Stage);
90   PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P);
91   PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P);
92 };
93 
94 struct Part {
95   Part() = default;
96   Part(std::string N, uint32_t S) : Name(N), Size(S) {}
97   std::string Name;
98   uint32_t Size;
99   std::optional<DXILProgram> Program;
100   std::optional<ShaderFlags> Flags;
101   std::optional<ShaderHash> Hash;
102   std::optional<PSVInfo> Info;
103 };
104 
105 struct Object {
106   FileHeader Header;
107   std::vector<Part> Parts;
108 };
109 
110 } // namespace DXContainerYAML
111 } // namespace llvm
112 
113 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part)
114 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo)
115 namespace llvm {
116 
117 class raw_ostream;
118 
119 namespace yaml {
120 
121 template <> struct MappingTraits<DXContainerYAML::VersionTuple> {
122   static void mapping(IO &IO, DXContainerYAML::VersionTuple &Version);
123 };
124 
125 template <> struct MappingTraits<DXContainerYAML::FileHeader> {
126   static void mapping(IO &IO, DXContainerYAML::FileHeader &Header);
127 };
128 
129 template <> struct MappingTraits<DXContainerYAML::DXILProgram> {
130   static void mapping(IO &IO, DXContainerYAML::DXILProgram &Program);
131 };
132 
133 template <> struct MappingTraits<DXContainerYAML::ShaderFlags> {
134   static void mapping(IO &IO, DXContainerYAML::ShaderFlags &Flags);
135 };
136 
137 template <> struct MappingTraits<DXContainerYAML::ShaderHash> {
138   static void mapping(IO &IO, DXContainerYAML::ShaderHash &Hash);
139 };
140 
141 template <> struct MappingTraits<DXContainerYAML::PSVInfo> {
142   static void mapping(IO &IO, DXContainerYAML::PSVInfo &PSV);
143 };
144 
145 template <> struct MappingTraits<DXContainerYAML::Part> {
146   static void mapping(IO &IO, DXContainerYAML::Part &Version);
147 };
148 
149 template <> struct MappingTraits<DXContainerYAML::Object> {
150   static void mapping(IO &IO, DXContainerYAML::Object &Obj);
151 };
152 
153 template <> struct MappingTraits<DXContainerYAML::ResourceBindInfo> {
154   static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res);
155 };
156 
157 } // namespace yaml
158 
159 } // namespace llvm
160 
161 #endif // LLVM_OBJECTYAML_DXCONTAINERYAML_H
162