1 //===- DXContainerYAML.cpp - DXContainer YAMLIO implementation ------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines classes for handling the YAML representation of
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ObjectYAML/DXContainerYAML.h"
15 #include "llvm/ADT/ScopeExit.h"
16 #include "llvm/BinaryFormat/DXContainer.h"
17 #include "llvm/Support/ScopedPrinter.h"
21 // This assert is duplicated here to leave a breadcrumb of the places that need
22 // to be updated if flags grow past 64-bits.
23 static_assert((uint64_t)dxbc::FeatureFlags::NextUnusedBit
<= 1ull << 63,
24 "Shader flag bits exceed enum size.");
26 DXContainerYAML::ShaderFlags::ShaderFlags(uint64_t FlagData
) {
27 #define SHADER_FLAG(Num, Val, Str) \
28 Val = (FlagData & (uint64_t)dxbc::FeatureFlags::Val) > 0;
29 #include "llvm/BinaryFormat/DXContainerConstants.def"
32 uint64_t DXContainerYAML::ShaderFlags::getEncodedFlags() {
34 #define SHADER_FLAG(Num, Val, Str) \
36 Flag |= (uint64_t)dxbc::FeatureFlags::Val;
37 #include "llvm/BinaryFormat/DXContainerConstants.def"
41 DXContainerYAML::ShaderHash::ShaderHash(const dxbc::ShaderHash
&Data
)
42 : IncludesSource((Data
.Flags
& static_cast<uint32_t>(
43 dxbc::HashFlags::IncludesSource
)) != 0),
45 memcpy(Digest
.data(), &Data
.Digest
[0], 16);
48 DXContainerYAML::PSVInfo::PSVInfo() : Version(0) {
49 memset(&Info
, 0, sizeof(Info
));
52 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo
*P
,
55 memset(&Info
, 0, sizeof(Info
));
56 memcpy(&Info
, P
, sizeof(dxbc::PSV::v0::RuntimeInfo
));
58 assert(Stage
< std::numeric_limits
<uint8_t>::max() &&
59 "Stage should be a very small number");
60 // We need to bring the stage in separately since it isn't part of the v1 data
62 Info
.ShaderStage
= static_cast<uint8_t>(Stage
);
65 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo
*P
)
67 memset(&Info
, 0, sizeof(Info
));
68 memcpy(&Info
, P
, sizeof(dxbc::PSV::v1::RuntimeInfo
));
71 DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo
*P
)
73 memset(&Info
, 0, sizeof(Info
));
74 memcpy(&Info
, P
, sizeof(dxbc::PSV::v2::RuntimeInfo
));
79 void MappingTraits
<DXContainerYAML::VersionTuple
>::mapping(
80 IO
&IO
, DXContainerYAML::VersionTuple
&Version
) {
81 IO
.mapRequired("Major", Version
.Major
);
82 IO
.mapRequired("Minor", Version
.Minor
);
85 void MappingTraits
<DXContainerYAML::FileHeader
>::mapping(
86 IO
&IO
, DXContainerYAML::FileHeader
&Header
) {
87 IO
.mapRequired("Hash", Header
.Hash
);
88 IO
.mapRequired("Version", Header
.Version
);
89 IO
.mapOptional("FileSize", Header
.FileSize
);
90 IO
.mapRequired("PartCount", Header
.PartCount
);
91 IO
.mapOptional("PartOffsets", Header
.PartOffsets
);
94 void MappingTraits
<DXContainerYAML::DXILProgram
>::mapping(
95 IO
&IO
, DXContainerYAML::DXILProgram
&Program
) {
96 IO
.mapRequired("MajorVersion", Program
.MajorVersion
);
97 IO
.mapRequired("MinorVersion", Program
.MinorVersion
);
98 IO
.mapRequired("ShaderKind", Program
.ShaderKind
);
99 IO
.mapOptional("Size", Program
.Size
);
100 IO
.mapRequired("DXILMajorVersion", Program
.DXILMajorVersion
);
101 IO
.mapRequired("DXILMinorVersion", Program
.DXILMinorVersion
);
102 IO
.mapOptional("DXILSize", Program
.DXILSize
);
103 IO
.mapOptional("DXIL", Program
.DXIL
);
106 void MappingTraits
<DXContainerYAML::ShaderFlags
>::mapping(
107 IO
&IO
, DXContainerYAML::ShaderFlags
&Flags
) {
108 #define SHADER_FLAG(Num, Val, Str) IO.mapRequired(#Val, Flags.Val);
109 #include "llvm/BinaryFormat/DXContainerConstants.def"
112 void MappingTraits
<DXContainerYAML::ShaderHash
>::mapping(
113 IO
&IO
, DXContainerYAML::ShaderHash
&Hash
) {
114 IO
.mapRequired("IncludesSource", Hash
.IncludesSource
);
115 IO
.mapRequired("Digest", Hash
.Digest
);
118 void MappingTraits
<DXContainerYAML::PSVInfo
>::mapping(
119 IO
&IO
, DXContainerYAML::PSVInfo
&PSV
) {
120 IO
.mapRequired("Version", PSV
.Version
);
122 // Store the PSV version in the YAML context.
123 void *OldContext
= IO
.getContext();
124 uint32_t Version
= PSV
.Version
;
125 IO
.setContext(&Version
);
127 // Restore the YAML context on function exit.
128 auto RestoreContext
= make_scope_exit([&]() { IO
.setContext(OldContext
); });
130 // Shader stage is only included in binaries for v1 and later, but we always
131 // include it since it simplifies parsing and file construction.
132 IO
.mapRequired("ShaderStage", PSV
.Info
.ShaderStage
);
133 PSV
.mapInfoForVersion(IO
);
135 IO
.mapRequired("ResourceStride", PSV
.ResourceStride
);
136 IO
.mapRequired("Resources", PSV
.Resources
);
137 if (PSV
.Version
== 0)
139 IO
.mapRequired("SigInputElements", PSV
.SigInputElements
);
140 IO
.mapRequired("SigOutputElements", PSV
.SigOutputElements
);
141 IO
.mapRequired("SigPatchOrPrimElements", PSV
.SigPatchOrPrimElements
);
143 Triple::EnvironmentType Stage
= dxbc::getShaderStage(PSV
.Info
.ShaderStage
);
144 if (PSV
.Info
.UsesViewID
) {
145 MutableArrayRef
<SmallVector
<llvm::yaml::Hex32
>> MutableOutMasks(
146 PSV
.OutputVectorMasks
);
147 IO
.mapRequired("OutputVectorMasks", MutableOutMasks
);
148 if (Stage
== Triple::EnvironmentType::Hull
)
149 IO
.mapRequired("PatchOrPrimMasks", PSV
.PatchOrPrimMasks
);
151 MutableArrayRef
<SmallVector
<llvm::yaml::Hex32
>> MutableIOMap(
153 IO
.mapRequired("InputOutputMap", MutableIOMap
);
155 if (Stage
== Triple::EnvironmentType::Hull
)
156 IO
.mapRequired("InputPatchMap", PSV
.InputPatchMap
);
158 if (Stage
== Triple::EnvironmentType::Domain
)
159 IO
.mapRequired("PatchOutputMap", PSV
.PatchOutputMap
);
162 void MappingTraits
<DXContainerYAML::SignatureParameter
>::mapping(
163 IO
&IO
, DXContainerYAML::SignatureParameter
&S
) {
164 IO
.mapRequired("Stream", S
.Stream
);
165 IO
.mapRequired("Name", S
.Name
);
166 IO
.mapRequired("Index", S
.Index
);
167 IO
.mapRequired("SystemValue", S
.SystemValue
);
168 IO
.mapRequired("CompType", S
.CompType
);
169 IO
.mapRequired("Register", S
.Register
);
170 IO
.mapRequired("Mask", S
.Mask
);
171 IO
.mapRequired("ExclusiveMask", S
.ExclusiveMask
);
172 IO
.mapRequired("MinPrecision", S
.MinPrecision
);
175 void MappingTraits
<DXContainerYAML::Signature
>::mapping(
176 IO
&IO
, DXContainerYAML::Signature
&S
) {
177 IO
.mapRequired("Parameters", S
.Parameters
);
180 void MappingTraits
<DXContainerYAML::Part
>::mapping(IO
&IO
,
181 DXContainerYAML::Part
&P
) {
182 IO
.mapRequired("Name", P
.Name
);
183 IO
.mapRequired("Size", P
.Size
);
184 IO
.mapOptional("Program", P
.Program
);
185 IO
.mapOptional("Flags", P
.Flags
);
186 IO
.mapOptional("Hash", P
.Hash
);
187 IO
.mapOptional("PSVInfo", P
.Info
);
188 IO
.mapOptional("Signature", P
.Signature
);
191 void MappingTraits
<DXContainerYAML::Object
>::mapping(
192 IO
&IO
, DXContainerYAML::Object
&Obj
) {
193 IO
.mapTag("!dxcontainer", true);
194 IO
.mapRequired("Header", Obj
.Header
);
195 IO
.mapRequired("Parts", Obj
.Parts
);
198 void MappingTraits
<DXContainerYAML::ResourceBindInfo
>::mapping(
199 IO
&IO
, DXContainerYAML::ResourceBindInfo
&Res
) {
200 IO
.mapRequired("Type", Res
.Type
);
201 IO
.mapRequired("Space", Res
.Space
);
202 IO
.mapRequired("LowerBound", Res
.LowerBound
);
203 IO
.mapRequired("UpperBound", Res
.UpperBound
);
205 const uint32_t *PSVVersion
= static_cast<uint32_t *>(IO
.getContext());
209 IO
.mapRequired("Kind", Res
.Kind
);
210 IO
.mapRequired("Flags", Res
.Flags
);
213 void MappingTraits
<DXContainerYAML::SignatureElement
>::mapping(
214 IO
&IO
, DXContainerYAML::SignatureElement
&El
) {
215 IO
.mapRequired("Name", El
.Name
);
216 IO
.mapRequired("Indices", El
.Indices
);
217 IO
.mapRequired("StartRow", El
.StartRow
);
218 IO
.mapRequired("Cols", El
.Cols
);
219 IO
.mapRequired("StartCol", El
.StartCol
);
220 IO
.mapRequired("Allocated", El
.Allocated
);
221 IO
.mapRequired("Kind", El
.Kind
);
222 IO
.mapRequired("ComponentType", El
.Type
);
223 IO
.mapRequired("Interpolation", El
.Mode
);
224 IO
.mapRequired("DynamicMask", El
.DynamicMask
);
225 IO
.mapRequired("Stream", El
.Stream
);
228 void ScalarEnumerationTraits
<dxbc::PSV::SemanticKind
>::enumeration(
229 IO
&IO
, dxbc::PSV::SemanticKind
&Value
) {
230 for (const auto &E
: dxbc::PSV::getSemanticKinds())
231 IO
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
234 void ScalarEnumerationTraits
<dxbc::PSV::ComponentType
>::enumeration(
235 IO
&IO
, dxbc::PSV::ComponentType
&Value
) {
236 for (const auto &E
: dxbc::PSV::getComponentTypes())
237 IO
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
240 void ScalarEnumerationTraits
<dxbc::PSV::InterpolationMode
>::enumeration(
241 IO
&IO
, dxbc::PSV::InterpolationMode
&Value
) {
242 for (const auto &E
: dxbc::PSV::getInterpolationModes())
243 IO
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
246 void ScalarEnumerationTraits
<dxbc::D3DSystemValue
>::enumeration(
247 IO
&IO
, dxbc::D3DSystemValue
&Value
) {
248 for (const auto &E
: dxbc::getD3DSystemValues())
249 IO
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
252 void ScalarEnumerationTraits
<dxbc::SigMinPrecision
>::enumeration(
253 IO
&IO
, dxbc::SigMinPrecision
&Value
) {
254 for (const auto &E
: dxbc::getSigMinPrecisions())
255 IO
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
258 void ScalarEnumerationTraits
<dxbc::SigComponentType
>::enumeration(
259 IO
&IO
, dxbc::SigComponentType
&Value
) {
260 for (const auto &E
: dxbc::getSigComponentTypes())
261 IO
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
266 void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO
&IO
) {
267 dxbc::PipelinePSVInfo
&StageInfo
= Info
.StageInfo
;
268 Triple::EnvironmentType Stage
= dxbc::getShaderStage(Info
.ShaderStage
);
271 case Triple::EnvironmentType::Pixel
:
272 IO
.mapRequired("DepthOutput", StageInfo
.PS
.DepthOutput
);
273 IO
.mapRequired("SampleFrequency", StageInfo
.PS
.SampleFrequency
);
275 case Triple::EnvironmentType::Vertex
:
276 IO
.mapRequired("OutputPositionPresent", StageInfo
.VS
.OutputPositionPresent
);
278 case Triple::EnvironmentType::Geometry
:
279 IO
.mapRequired("InputPrimitive", StageInfo
.GS
.InputPrimitive
);
280 IO
.mapRequired("OutputTopology", StageInfo
.GS
.OutputTopology
);
281 IO
.mapRequired("OutputStreamMask", StageInfo
.GS
.OutputStreamMask
);
282 IO
.mapRequired("OutputPositionPresent", StageInfo
.GS
.OutputPositionPresent
);
284 case Triple::EnvironmentType::Hull
:
285 IO
.mapRequired("InputControlPointCount",
286 StageInfo
.HS
.InputControlPointCount
);
287 IO
.mapRequired("OutputControlPointCount",
288 StageInfo
.HS
.OutputControlPointCount
);
289 IO
.mapRequired("TessellatorDomain", StageInfo
.HS
.TessellatorDomain
);
290 IO
.mapRequired("TessellatorOutputPrimitive",
291 StageInfo
.HS
.TessellatorOutputPrimitive
);
293 case Triple::EnvironmentType::Domain
:
294 IO
.mapRequired("InputControlPointCount",
295 StageInfo
.DS
.InputControlPointCount
);
296 IO
.mapRequired("OutputPositionPresent", StageInfo
.DS
.OutputPositionPresent
);
297 IO
.mapRequired("TessellatorDomain", StageInfo
.DS
.TessellatorDomain
);
299 case Triple::EnvironmentType::Mesh
:
300 IO
.mapRequired("GroupSharedBytesUsed", StageInfo
.MS
.GroupSharedBytesUsed
);
301 IO
.mapRequired("GroupSharedBytesDependentOnViewID",
302 StageInfo
.MS
.GroupSharedBytesDependentOnViewID
);
303 IO
.mapRequired("PayloadSizeInBytes", StageInfo
.MS
.PayloadSizeInBytes
);
304 IO
.mapRequired("MaxOutputVertices", StageInfo
.MS
.MaxOutputVertices
);
305 IO
.mapRequired("MaxOutputPrimitives", StageInfo
.MS
.MaxOutputPrimitives
);
307 case Triple::EnvironmentType::Amplification
:
308 IO
.mapRequired("PayloadSizeInBytes", StageInfo
.AS
.PayloadSizeInBytes
);
314 IO
.mapRequired("MinimumWaveLaneCount", Info
.MinimumWaveLaneCount
);
315 IO
.mapRequired("MaximumWaveLaneCount", Info
.MaximumWaveLaneCount
);
320 IO
.mapRequired("UsesViewID", Info
.UsesViewID
);
323 case Triple::EnvironmentType::Geometry
:
324 IO
.mapRequired("MaxVertexCount", Info
.GeomData
.MaxVertexCount
);
326 case Triple::EnvironmentType::Hull
:
327 case Triple::EnvironmentType::Domain
:
328 IO
.mapRequired("SigPatchConstOrPrimVectors",
329 Info
.GeomData
.SigPatchConstOrPrimVectors
);
331 case Triple::EnvironmentType::Mesh
:
332 IO
.mapRequired("SigPrimVectors", Info
.GeomData
.MeshInfo
.SigPrimVectors
);
333 IO
.mapRequired("MeshOutputTopology",
334 Info
.GeomData
.MeshInfo
.MeshOutputTopology
);
340 IO
.mapRequired("SigInputVectors", Info
.SigInputVectors
);
341 MutableArrayRef
<uint8_t> Vec(Info
.SigOutputVectors
);
342 IO
.mapRequired("SigOutputVectors", Vec
);
347 IO
.mapRequired("NumThreadsX", Info
.NumThreadsX
);
348 IO
.mapRequired("NumThreadsY", Info
.NumThreadsY
);
349 IO
.mapRequired("NumThreadsZ", Info
.NumThreadsZ
);