LLVM 17.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
25namespace llvm {
26namespace object {
27
28namespace DirectX {
30
31 // This class provides a view into the underlying resource array. The Resource
32 // data is little-endian encoded and may not be properly aligned to read
33 // directly from. The dereference operator creates a copy of the data and byte
34 // swaps it as appropriate.
35 struct ResourceArray {
37 size_t Stride; // size of each element in the list.
38
39 ResourceArray() = default;
40 ResourceArray(StringRef D, size_t S) : Data(D), Stride(S) {}
41
42 using value_type = dxbc::PSV::v2::ResourceBindInfo;
43
44 struct iterator {
46 size_t Stride; // size of each element in the list.
47 const char *Current;
48
49 iterator(const ResourceArray &A, const char *C)
50 : Data(A.Data), Stride(A.Stride), Current(C) {}
51 iterator(const iterator &) = default;
52
54 // Explicitly zero the structure so that unused fields are zeroed. It is
55 // up to the user to know if the fields are used by verifying the PSV
56 // version.
57 value_type Val = {{0, 0, 0, 0}, 0, 0};
58 if (Current >= Data.end())
59 return Val;
60 memcpy(static_cast<void *>(&Val), Current, Stride);
62 Val.swapBytes();
63 return Val;
64 }
65
67 if (Current < Data.end())
68 Current += Stride;
69 return *this;
70 }
71
73 iterator Tmp = *this;
74 ++*this;
75 return Tmp;
76 }
77
79 if (Current > Data.begin())
80 Current -= Stride;
81 return *this;
82 }
83
85 iterator Tmp = *this;
86 --*this;
87 return Tmp;
88 }
89
90 bool operator==(const iterator I) { return I.Current == Current; }
91 bool operator!=(const iterator I) { return !(*this == I); }
92 };
93
94 iterator begin() const { return iterator(*this, Data.begin()); }
95
96 iterator end() const { return iterator(*this, Data.end()); }
97
98 size_t size() const { return Data.size() / Stride; }
99 };
100
101 StringRef Data;
102 uint32_t Size;
103 using InfoStruct =
104 std::variant<std::monostate, dxbc::PSV::v0::RuntimeInfo,
105 dxbc::PSV::v1::RuntimeInfo, dxbc::PSV::v2::RuntimeInfo>;
106 InfoStruct BasicInfo;
107 ResourceArray Resources;
108
109public:
111
112 // Parsing depends on the shader kind
113 Error parse(uint16_t ShaderKind);
114
115 uint32_t getSize() const { return Size; }
116 uint32_t getResourceCount() const { return Resources.size(); }
117 ResourceArray getResources() const { return Resources; }
118
120 return Size >= sizeof(dxbc::PSV::v2::RuntimeInfo)
121 ? 2
122 : (Size >= sizeof(dxbc::PSV::v1::RuntimeInfo) ? 1 : 0);
123 }
124
125 const InfoStruct &getInfo() const { return BasicInfo; }
126};
127
128} // namespace DirectX
129
131public:
132 using DXILData = std::pair<dxbc::ProgramHeader, const char *>;
133
134private:
136
137 MemoryBufferRef Data;
138 dxbc::Header Header;
139 SmallVector<uint32_t, 4> PartOffsets;
140 std::optional<DXILData> DXIL;
141 std::optional<uint64_t> ShaderFlags;
142 std::optional<dxbc::ShaderHash> Hash;
143 std::optional<DirectX::PSVRuntimeInfo> PSVInfo;
144
145 Error parseHeader();
146 Error parsePartOffsets();
147 Error parseDXILHeader(StringRef Part);
148 Error parseShaderFlags(StringRef Part);
149 Error parseHash(StringRef Part);
150 Error parsePSVInfo(StringRef Part);
151 friend class PartIterator;
152
153public:
154 // The PartIterator is a wrapper around the iterator for the PartOffsets
155 // member of the DXContainer. It contains a refernce to the container, and the
156 // current iterator value, as well as storage for a parsed part header.
158 const DXContainer &Container;
160 struct PartData {
161 dxbc::PartHeader Part;
162 uint32_t Offset;
164 } IteratorState;
165
166 friend class DXContainer;
167
170 : Container(C), OffsetIt(It) {
171 if (OffsetIt == Container.PartOffsets.end())
172 updateIteratorImpl(Container.PartOffsets.back());
173 else
174 updateIterator();
175 }
176
177 // Updates the iterator's state data. This results in copying the part
178 // header into the iterator and handling any required byte swapping. This is
179 // called when incrementing or decrementing the iterator.
180 void updateIterator() {
181 if (OffsetIt != Container.PartOffsets.end())
182 updateIteratorImpl(*OffsetIt);
183 }
184
185 // Implementation for updating the iterator state based on a specified
186 // offest.
187 void updateIteratorImpl(const uint32_t Offset);
188
189 public:
191 if (OffsetIt == Container.PartOffsets.end())
192 return *this;
193 ++OffsetIt;
194 updateIterator();
195 return *this;
196 }
197
199 PartIterator Tmp = *this;
200 ++(*this);
201 return Tmp;
202 }
203
204 bool operator==(const PartIterator &RHS) const {
205 return OffsetIt == RHS.OffsetIt;
206 }
207
208 bool operator!=(const PartIterator &RHS) const {
209 return OffsetIt != RHS.OffsetIt;
210 }
211
212 const PartData &operator*() { return IteratorState; }
213 const PartData *operator->() { return &IteratorState; }
214 };
215
217 return PartIterator(*this, PartOffsets.begin());
218 }
219
220 PartIterator end() const { return PartIterator(*this, PartOffsets.end()); }
221
222 StringRef getData() const { return Data.getBuffer(); }
224
225 const dxbc::Header &getHeader() const { return Header; }
226
227 const std::optional<DXILData> &getDXIL() const { return DXIL; }
228
229 std::optional<uint64_t> getShaderFlags() const { return ShaderFlags; }
230
231 std::optional<dxbc::ShaderHash> getShaderHash() const { return Hash; }
232
233 const std::optional<DirectX::PSVRuntimeInfo> &getPSVInfo() const {
234 return PSVInfo;
235 };
236};
237
238} // namespace object
239} // namespace llvm
240
241#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")
#define I(x, y, z)
Definition: MD5.cpp:58
This file defines the SmallVector class.
@ Data
Definition: TextStubV5.cpp:111
Value * RHS
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Tagged union holding either a T or a Error.
Definition: Error.h:470
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
iterator begin() const
Definition: StringRef.h:111
iterator end() const
Definition: StringRef.h:113
bool operator!=(const PartIterator &RHS) const
Definition: DXContainer.h:208
bool operator==(const PartIterator &RHS) const
Definition: DXContainer.h:204
std::optional< uint64_t > getShaderFlags() const
Definition: DXContainer.h:229
PartIterator end() const
Definition: DXContainer.h:220
const std::optional< DXILData > & getDXIL() const
Definition: DXContainer.h:227
const std::optional< DirectX::PSVRuntimeInfo > & getPSVInfo() const
Definition: DXContainer.h:233
const dxbc::Header & getHeader() const
Definition: DXContainer.h:225
std::pair< dxbc::ProgramHeader, const char * > DXILData
Definition: DXContainer.h:132
StringRef getData() const
Definition: DXContainer.h:222
PartIterator begin() const
Definition: DXContainer.h:216
static Expected< DXContainer > create(MemoryBufferRef Object)
std::optional< dxbc::ShaderHash > getShaderHash() const
Definition: DXContainer.h:231
ResourceArray getResources() const
Definition: DXContainer.h:117
const InfoStruct & getInfo() const
Definition: DXContainer.h:125
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
constexpr bool IsBigEndianHost
Definition: SwapByteOrder.h:67
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1777
Use this type to describe the size and type of a DXIL container part.
Definition: DXContainer.h:92
iterator(const ResourceArray &A, const char *C)
Definition: DXContainer.h:49
Definition: regcomp.c:192