LLVM 18.0.0git
DXContainer.h
Go to the documentation of this file.
1//===- DXContainer.h - DXContainer file 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// This file declares the DXContainerFile class, which implements the ObjectFile
10// interface for DXContainer files.
11//
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECT_DXCONTAINER_H
16#define LLVM_OBJECT_DXCONTAINER_H
17
19#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/Error.h"
24#include <array>
25#include <variant>
26
27namespace llvm {
28namespace object {
29
30namespace detail {
31template <typename T>
32std::enable_if_t<std::is_arithmetic<T>::value, void> swapBytes(T &value) {
34}
35
36template <typename T>
37std::enable_if_t<std::is_class<T>::value, void> swapBytes(T &value) {
38 value.swapBytes();
39}
40} // namespace detail
41
42// This class provides a view into the underlying resource array. The Resource
43// data is little-endian encoded and may not be properly aligned to read
44// directly from. The dereference operator creates a copy of the data and byte
45// swaps it as appropriate.
46template <typename T> struct ViewArray {
48 uint32_t Stride = sizeof(T); // size of each element in the list.
49
50 ViewArray() = default;
51 ViewArray(StringRef D, size_t S) : Data(D), Stride(S) {}
52
53 using value_type = T;
54 static constexpr uint32_t MaxStride() {
55 return static_cast<uint32_t>(sizeof(value_type));
56 }
57
58 struct iterator {
60 uint32_t Stride; // size of each element in the list.
61 const char *Current;
62
63 iterator(const ViewArray &A, const char *C)
64 : Data(A.Data), Stride(A.Stride), Current(C) {}
65 iterator(const iterator &) = default;
66
68 // Explicitly zero the structure so that unused fields are zeroed. It is
69 // up to the user to know if the fields are used by verifying the PSV
70 // version.
71 value_type Val;
72 std::memset(&Val, 0, sizeof(value_type));
73 if (Current >= Data.end())
74 return Val;
75 memcpy(static_cast<void *>(&Val), Current, std::min(Stride, MaxStride()));
78 return Val;
79 }
80
82 if (Current < Data.end())
83 Current += Stride;
84 return *this;
85 }
86
88 iterator Tmp = *this;
89 ++*this;
90 return Tmp;
91 }
92
94 if (Current > Data.begin())
95 Current -= Stride;
96 return *this;
97 }
98
100 iterator Tmp = *this;
101 --*this;
102 return Tmp;
103 }
104
105 bool operator==(const iterator I) { return I.Current == Current; }
106 bool operator!=(const iterator I) { return !(*this == I); }
107 };
108
109 iterator begin() const { return iterator(*this, Data.begin()); }
110
111 iterator end() const { return iterator(*this, Data.end()); }
112
113 size_t size() const { return Data.size() / Stride; }
114
115 bool isEmpty() const { return Data.empty(); }
116};
117
118namespace DirectX {
120
123
124 StringRef Data;
125 uint32_t Size;
126 using InfoStruct =
127 std::variant<std::monostate, dxbc::PSV::v0::RuntimeInfo,
129 InfoStruct BasicInfo;
130 ResourceArray Resources;
131 StringRef StringTable;
132 SmallVector<uint32_t> SemanticIndexTable;
133 SigElementArray SigInputElements;
134 SigElementArray SigOutputElements;
135 SigElementArray SigPatchOrPrimElements;
136
137 std::array<ViewArray<uint32_t>, 4> OutputVectorMasks;
138 ViewArray<uint32_t> PatchOrPrimMasks;
139 std::array<ViewArray<uint32_t>, 4> InputOutputMap;
140 ViewArray<uint32_t> InputPatchMap;
141 ViewArray<uint32_t> PatchOutputMap;
142
143public:
144 PSVRuntimeInfo(StringRef D) : Data(D), Size(0) {}
145
146 // Parsing depends on the shader kind
147 Error parse(uint16_t ShaderKind);
148
149 uint32_t getSize() const { return Size; }
150 uint32_t getResourceCount() const { return Resources.size(); }
151 ResourceArray getResources() const { return Resources; }
152
154 return Size >= sizeof(dxbc::PSV::v2::RuntimeInfo)
155 ? 2
156 : (Size >= sizeof(dxbc::PSV::v1::RuntimeInfo) ? 1 : 0);
157 }
158
159 uint32_t getResourceStride() const { return Resources.Stride; }
160
161 const InfoStruct &getInfo() const { return BasicInfo; }
162
163 template <typename T> const T *getInfoAs() const {
164 if (const auto *P = std::get_if<dxbc::PSV::v2::RuntimeInfo>(&BasicInfo))
165 return static_cast<const T *>(P);
166 if (std::is_same<T, dxbc::PSV::v2::RuntimeInfo>::value)
167 return nullptr;
168
169 if (const auto *P = std::get_if<dxbc::PSV::v1::RuntimeInfo>(&BasicInfo))
170 return static_cast<const T *>(P);
171 if (std::is_same<T, dxbc::PSV::v1::RuntimeInfo>::value)
172 return nullptr;
173
174 if (const auto *P = std::get_if<dxbc::PSV::v0::RuntimeInfo>(&BasicInfo))
175 return static_cast<const T *>(P);
176 return nullptr;
177 }
178
179 StringRef getStringTable() const { return StringTable; }
181 return SemanticIndexTable;
182 }
183
184 uint8_t getSigInputCount() const;
185 uint8_t getSigOutputCount() const;
186 uint8_t getSigPatchOrPrimCount() const;
187
188 SigElementArray getSigInputElements() const { return SigInputElements; }
189 SigElementArray getSigOutputElements() const { return SigOutputElements; }
191 return SigPatchOrPrimElements;
192 }
193
195 assert(Idx < 4);
196 return OutputVectorMasks[Idx];
197 }
198
199 ViewArray<uint32_t> getPatchOrPrimMasks() const { return PatchOrPrimMasks; }
200
202 assert(Idx < 4);
203 return InputOutputMap[Idx];
204 }
205
206 ViewArray<uint32_t> getInputPatchMap() const { return InputPatchMap; }
207 ViewArray<uint32_t> getPatchOutputMap() const { return PatchOutputMap; }
208
209 uint32_t getSigElementStride() const { return SigInputElements.Stride; }
210
211 bool usesViewID() const {
212 if (const auto *P = getInfoAs<dxbc::PSV::v1::RuntimeInfo>())
213 return P->UsesViewID != 0;
214 return false;
215 }
216
217 uint8_t getInputVectorCount() const {
218 if (const auto *P = getInfoAs<dxbc::PSV::v1::RuntimeInfo>())
219 return P->SigInputVectors;
220 return 0;
221 }
222
224 if (const auto *P = getInfoAs<dxbc::PSV::v1::RuntimeInfo>())
225 return ArrayRef<uint8_t>(P->SigOutputVectors);
226 return ArrayRef<uint8_t>();
227 }
228
230 if (const auto *P = getInfoAs<dxbc::PSV::v1::RuntimeInfo>())
231 return P->GeomData.SigPatchConstOrPrimVectors;
232 return 0;
233 }
234};
235
239 StringRef StringTable;
240
241public:
243 return Parameters.begin();
244 }
245
247 return Parameters.end();
248 }
249
252 Offset < StringTableOffset + StringTable.size() &&
253 "Offset out of range.");
254 // Name offsets are from the start of the signature data, not from the start
255 // of the string table. The header encodes the start offset of the sting
256 // table, so we convert the offset here.
257 uint32_t TableOffset = Offset - StringTableOffset;
258 return StringTable.slice(TableOffset, StringTable.find('\0', TableOffset));
259 }
260
261 bool isEmpty() const { return Parameters.isEmpty(); }
262
264};
265
266} // namespace DirectX
267
269public:
270 using DXILData = std::pair<dxbc::ProgramHeader, const char *>;
271
272private:
274
275 MemoryBufferRef Data;
276 dxbc::Header Header;
277 SmallVector<uint32_t, 4> PartOffsets;
278 std::optional<DXILData> DXIL;
279 std::optional<uint64_t> ShaderFlags;
280 std::optional<dxbc::ShaderHash> Hash;
281 std::optional<DirectX::PSVRuntimeInfo> PSVInfo;
282 DirectX::Signature InputSignature;
283 DirectX::Signature OutputSignature;
284 DirectX::Signature PatchConstantSignature;
285
286 Error parseHeader();
287 Error parsePartOffsets();
288 Error parseDXILHeader(StringRef Part);
289 Error parseShaderFlags(StringRef Part);
290 Error parseHash(StringRef Part);
291 Error parsePSVInfo(StringRef Part);
292 Error parseSignature(StringRef Part, DirectX::Signature &Array);
293 friend class PartIterator;
294
295public:
296 // The PartIterator is a wrapper around the iterator for the PartOffsets
297 // member of the DXContainer. It contains a refernce to the container, and the
298 // current iterator value, as well as storage for a parsed part header.
300 const DXContainer &Container;
302 struct PartData {
303 dxbc::PartHeader Part;
304 uint32_t Offset;
305 StringRef Data;
306 } IteratorState;
307
308 friend class DXContainer;
309
312 : Container(C), OffsetIt(It) {
313 if (OffsetIt == Container.PartOffsets.end())
314 updateIteratorImpl(Container.PartOffsets.back());
315 else
316 updateIterator();
317 }
318
319 // Updates the iterator's state data. This results in copying the part
320 // header into the iterator and handling any required byte swapping. This is
321 // called when incrementing or decrementing the iterator.
322 void updateIterator() {
323 if (OffsetIt != Container.PartOffsets.end())
324 updateIteratorImpl(*OffsetIt);
325 }
326
327 // Implementation for updating the iterator state based on a specified
328 // offest.
329 void updateIteratorImpl(const uint32_t Offset);
330
331 public:
333 if (OffsetIt == Container.PartOffsets.end())
334 return *this;
335 ++OffsetIt;
336 updateIterator();
337 return *this;
338 }
339
341 PartIterator Tmp = *this;
342 ++(*this);
343 return Tmp;
344 }
345
346 bool operator==(const PartIterator &RHS) const {
347 return OffsetIt == RHS.OffsetIt;
348 }
349
350 bool operator!=(const PartIterator &RHS) const {
351 return OffsetIt != RHS.OffsetIt;
352 }
353
354 const PartData &operator*() { return IteratorState; }
355 const PartData *operator->() { return &IteratorState; }
356 };
357
359 return PartIterator(*this, PartOffsets.begin());
360 }
361
362 PartIterator end() const { return PartIterator(*this, PartOffsets.end()); }
363
364 StringRef getData() const { return Data.getBuffer(); }
366
367 const dxbc::Header &getHeader() const { return Header; }
368
369 const std::optional<DXILData> &getDXIL() const { return DXIL; }
370
371 std::optional<uint64_t> getShaderFlags() const { return ShaderFlags; }
372
373 std::optional<dxbc::ShaderHash> getShaderHash() const { return Hash; }
374
375 const std::optional<DirectX::PSVRuntimeInfo> &getPSVInfo() const {
376 return PSVInfo;
377 };
378
379 const DirectX::Signature &getInputSignature() const { return InputSignature; }
381 return OutputSignature;
382 }
384 return PatchConstantSignature;
385 }
386};
387
388} // namespace object
389} // namespace llvm
390
391#endif // LLVM_OBJECT_DXCONTAINER_H
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live value
#define I(x, y, z)
Definition: MD5.cpp:58
#define T
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Value * RHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Tagged union holding either a T or a Error.
Definition: Error.h:474
typename SuperClass::const_iterator const_iterator
Definition: SmallVector.h:582
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
iterator begin() const
Definition: StringRef.h:111
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
iterator end() const
Definition: StringRef.h:113
bool operator!=(const PartIterator &RHS) const
Definition: DXContainer.h:350
bool operator==(const PartIterator &RHS) const
Definition: DXContainer.h:346
std::optional< uint64_t > getShaderFlags() const
Definition: DXContainer.h:371
PartIterator end() const
Definition: DXContainer.h:362
const std::optional< DXILData > & getDXIL() const
Definition: DXContainer.h:369
const std::optional< DirectX::PSVRuntimeInfo > & getPSVInfo() const
Definition: DXContainer.h:375
const dxbc::Header & getHeader() const
Definition: DXContainer.h:367
const DirectX::Signature & getInputSignature() const
Definition: DXContainer.h:379
std::pair< dxbc::ProgramHeader, const char * > DXILData
Definition: DXContainer.h:270
StringRef getData() const
Definition: DXContainer.h:364
PartIterator begin() const
Definition: DXContainer.h:358
static Expected< DXContainer > create(MemoryBufferRef Object)
std::optional< dxbc::ShaderHash > getShaderHash() const
Definition: DXContainer.h:373
const DirectX::Signature & getOutputSignature() const
Definition: DXContainer.h:380
const DirectX::Signature & getPatchConstantSignature() const
Definition: DXContainer.h:383
ArrayRef< uint8_t > getOutputVectorCounts() const
Definition: DXContainer.h:223
ArrayRef< uint32_t > getSemanticIndexTable() const
Definition: DXContainer.h:180
ResourceArray getResources() const
Definition: DXContainer.h:151
ViewArray< uint32_t > getInputOutputMap(size_t Idx) const
Definition: DXContainer.h:201
uint8_t getPatchConstOrPrimVectorCount() const
Definition: DXContainer.h:229
ViewArray< uint32_t > getPatchOrPrimMasks() const
Definition: DXContainer.h:199
ViewArray< uint32_t > getInputPatchMap() const
Definition: DXContainer.h:206
ViewArray< uint32_t > getOutputVectorMasks(size_t Idx) const
Definition: DXContainer.h:194
SigElementArray getSigPatchOrPrimElements() const
Definition: DXContainer.h:190
SigElementArray getSigInputElements() const
Definition: DXContainer.h:188
SigElementArray getSigOutputElements() const
Definition: DXContainer.h:189
const InfoStruct & getInfo() const
Definition: DXContainer.h:161
ViewArray< uint32_t > getPatchOutputMap() const
Definition: DXContainer.h:207
ViewArray< dxbc::ProgramSignatureElement >::iterator begin() const
Definition: DXContainer.h:242
Error initialize(StringRef Part)
ViewArray< dxbc::ProgramSignatureElement >::iterator end() const
Definition: DXContainer.h:246
StringRef getName(uint32_t Offset) const
Definition: DXContainer.h:250
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
std::enable_if_t< std::is_arithmetic< T >::value, void > swapBytes(T &value)
Definition: DXContainer.h:32
constexpr bool IsBigEndianHost
Definition: SwapByteOrder.h:26
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:61
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
Use this type to describe the size and type of a DXIL container part.
Definition: DXContainer.h:93
bool operator!=(const iterator I)
Definition: DXContainer.h:106
iterator(const ViewArray &A, const char *C)
Definition: DXContainer.h:63
bool operator==(const iterator I)
Definition: DXContainer.h:105
iterator(const iterator &)=default
static constexpr uint32_t MaxStride()
Definition: DXContainer.h:54
iterator end() const
Definition: DXContainer.h:111
ViewArray(StringRef D, size_t S)
Definition: DXContainer.h:51
size_t size() const
Definition: DXContainer.h:113
iterator begin() const
Definition: DXContainer.h:109
Definition: regcomp.c:192