LLVM 24.0.0git
DXContainerPSVInfo.cpp
Go to the documentation of this file.
1//===- llvm/MC/DXContainerPSVInfo.cpp - DXContainer PSVInfo -----*- 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
15
16using namespace llvm;
17using namespace llvm::mcdxbc;
18using namespace llvm::dxbc::PSV;
19
20static constexpr size_t npos = StringRef::npos;
21
22static size_t FindSequence(ArrayRef<uint32_t> Buffer,
23 ArrayRef<uint32_t> Sequence) {
24 if (Buffer.size() < Sequence.size())
25 return npos;
26 for (size_t Idx = 0; Idx <= Buffer.size() - Sequence.size(); ++Idx) {
27 if (0 == memcmp(static_cast<const void *>(&Buffer[Idx]),
28 static_cast<const void *>(Sequence.begin()),
29 Sequence.size() * sizeof(uint32_t)))
30 return Idx;
31 }
32 return npos;
33}
34
35static void
37 SmallVectorImpl<uint32_t> &IndexBuffer,
39 SmallVectorImpl<StringRef> &SemanticNames,
41 for (const auto &El : Elements) {
42 // Put the name in the string table and the name list.
43 StrTabBuilder.add(El.Name);
44 SemanticNames.push_back(El.Name);
45
46 v0::SignatureElement FinalElement;
47 memset(&FinalElement, 0, sizeof(v0::SignatureElement));
48 FinalElement.Rows = static_cast<uint8_t>(El.Indices.size());
49 FinalElement.StartRow = El.StartRow;
50 FinalElement.Cols = El.Cols;
51 FinalElement.StartCol = El.StartCol;
52 FinalElement.Allocated = El.Allocated;
53 FinalElement.Kind = El.Kind;
54 FinalElement.Type = El.Type;
55 FinalElement.Mode = El.Mode;
56 FinalElement.DynamicMask = El.DynamicMask;
57 FinalElement.Stream = El.Stream;
58
59 size_t Idx = FindSequence(IndexBuffer, El.Indices);
60 if (Idx == npos) {
61 FinalElement.IndicesOffset = static_cast<uint32_t>(IndexBuffer.size());
62 llvm::append_range(IndexBuffer, El.Indices);
63 } else
64 FinalElement.IndicesOffset = static_cast<uint32_t>(Idx);
65 FinalElements.push_back(FinalElement);
66 }
67}
68
70 assert(IsFinalized && "finalize must be called before write");
71
72 uint32_t InfoSize;
73 uint32_t BindingSize;
74 switch (Version) {
75 case 0:
76 InfoSize = sizeof(dxbc::PSV::v0::RuntimeInfo);
77 BindingSize = sizeof(dxbc::PSV::v0::ResourceBindInfo);
78 break;
79 case 1:
80 InfoSize = sizeof(dxbc::PSV::v1::RuntimeInfo);
81 BindingSize = sizeof(dxbc::PSV::v0::ResourceBindInfo);
82 break;
83 case 2:
84 InfoSize = sizeof(dxbc::PSV::v2::RuntimeInfo);
85 BindingSize = sizeof(dxbc::PSV::v2::ResourceBindInfo);
86 break;
87 case 3:
88 default:
89 InfoSize = sizeof(dxbc::PSV::v3::RuntimeInfo);
90 BindingSize = sizeof(dxbc::PSV::v2::ResourceBindInfo);
91 }
92
93 // Write the size of the info.
95
96 // Write the info itself.
97 OS.write(reinterpret_cast<const char *>(&BaseData), InfoSize);
98
99 uint32_t ResourceCount = static_cast<uint32_t>(Resources.size());
100
102 if (ResourceCount > 0)
104
105 for (const auto &Res : Resources)
106 OS.write(reinterpret_cast<const char *>(&Res), BindingSize);
107
108 // PSV Version 0 stops after the resource list.
109 if (Version == 0)
110 return;
111
113 static_cast<uint32_t>(DXConStrTabBuilder.getSize()),
115
116 // Write the string table.
117 DXConStrTabBuilder.write(OS);
118
119 // Write the index table size, then table.
120 support::endian::write(OS, static_cast<uint32_t>(IndexBuffer.size()),
122 for (auto I : IndexBuffer)
124
125 if (SignatureElements.size() > 0) {
126 // write the size of the signature elements.
128 static_cast<uint32_t>(sizeof(v0::SignatureElement)),
130
131 // write the signature elements.
132 OS.write(reinterpret_cast<const char *>(&SignatureElements[0]),
133 SignatureElements.size() * sizeof(v0::SignatureElement));
134 }
135
136 for (const auto &MaskVector : OutputVectorMasks)
141 for (const auto &MaskVector : InputOutputMap)
148}
149
151 IsFinalized = true;
152 BaseData.SigInputElements = static_cast<uint32_t>(InputElements.size());
153 BaseData.SigOutputElements = static_cast<uint32_t>(OutputElements.size());
154 BaseData.SigPatchOrPrimElements =
155 static_cast<uint32_t>(PatchOrPrimElements.size());
156
157 SmallVector<StringRef, 32> SemanticNames;
158
159 // Build a string table and set associated offsets to be written when
160 // write() is called
161 ProcessElementList(DXConStrTabBuilder, IndexBuffer, SignatureElements,
162 SemanticNames, InputElements);
163 ProcessElementList(DXConStrTabBuilder, IndexBuffer, SignatureElements,
164 SemanticNames, OutputElements);
165 ProcessElementList(DXConStrTabBuilder, IndexBuffer, SignatureElements,
166 SemanticNames, PatchOrPrimElements);
167
168 if (Version >= 3 && !EntryName.empty())
169 DXConStrTabBuilder.add(EntryName);
170
171 DXConStrTabBuilder.finalize();
172 for (auto ElAndName : zip(SignatureElements, SemanticNames)) {
173 llvm::dxbc::PSV::v0::SignatureElement &El = std::get<0>(ElAndName);
174 StringRef Name = std::get<1>(ElAndName);
175 El.NameOffset = static_cast<uint32_t>(DXConStrTabBuilder.getOffset(Name));
177 El.swapBytes();
178 }
179
180 if (Version >= 3 && !EntryName.empty())
181 BaseData.EntryNameOffset =
182 static_cast<uint32_t>(DXConStrTabBuilder.getOffset(EntryName));
183
185 return;
186 BaseData.swapBytes();
187 BaseData.swapBytes(Stage);
188 for (auto &Res : Resources)
189 Res.swapBytes();
190}
191
192void Signature::write(raw_ostream &OS, bool PadToDword) {
194 SigParams.reserve(Params.size());
196
197 // Name offsets are from the start of the part. Pre-calculate the offset to
198 // the start of the string table so that it can be added to the table offset.
199 uint32_t TableStart = sizeof(dxbc::ProgramSignatureHeader) +
200 (sizeof(dxbc::ProgramSignatureElement) * Params.size());
201
202 for (const auto &P : Params) {
203 // zero out the data
205 memset(&FinalElement, 0, sizeof(dxbc::ProgramSignatureElement));
206 FinalElement.Stream = P.Stream;
207 FinalElement.NameOffset =
208 static_cast<uint32_t>(StrTabBuilder.add(P.Name)) + TableStart;
209 FinalElement.Index = P.Index;
210 FinalElement.SystemValue = P.SystemValue;
211 FinalElement.CompType = P.CompType;
212 FinalElement.Register = P.Register;
213 FinalElement.Mask = P.Mask;
214 FinalElement.ExclusiveMask = P.ExclusiveMask;
215 FinalElement.MinPrecision = P.MinPrecision;
216 SigParams.push_back(FinalElement);
217 }
218
219 StrTabBuilder.finalizeInOrder();
220 stable_sort(SigParams, [&](const dxbc::ProgramSignatureElement &L,
222 return std::tie(L.Stream, L.Register, L.NameOffset) <
223 std::tie(R.Stream, R.Register, R.NameOffset);
224 });
226 for (auto &El : SigParams)
227 El.swapBytes();
228
229 dxbc::ProgramSignatureHeader Header = {static_cast<uint32_t>(Params.size()),
232 Header.swapBytes();
233 OS.write(reinterpret_cast<const char *>(&Header),
235 OS.write(reinterpret_cast<const char *>(SigParams.data()),
236 sizeof(dxbc::ProgramSignatureElement) * SigParams.size());
237 StrTabBuilder.write(OS);
238 if (PadToDword)
239 OS.write_zeros(
240 offsetToAlignment(TableStart + StrTabBuilder.getSize(), Align(4)));
241}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr size_t npos
static void ProcessElementList(StringTableBuilder &StrTabBuilder, SmallVectorImpl< uint32_t > &IndexBuffer, SmallVectorImpl< v0::SignatureElement > &FinalElements, SmallVectorImpl< StringRef > &SemanticNames, ArrayRef< PSVSignatureElement > Elements)
static size_t FindSequence(ArrayRef< uint32_t > Buffer, ArrayRef< uint32_t > Sequence)
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
Utility for building string tables with deduplicated suffixes.
LLVM_ABI void finalizeInOrder()
Finalize the string table without reording it.
LLVM_ABI size_t add(CachedHashStringRef S, uint8_t Priority=0)
Add a string to the builder.
LLVM_ABI void write(raw_ostream &OS) const
LLVM_ABI void write(raw_ostream &OS, bool PadToDword=true)
Legacy validator versions through 1.6 require unpadded signature parts.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
raw_ostream & write(unsigned char C)
void write_array(raw_ostream &os, ArrayRef< value_type > values, endianness endian)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:82
constexpr bool IsBigEndianHost
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition STLExtras.h:846
void stable_sort(R &&Range)
Definition STLExtras.h:2132
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition Alignment.h:191
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
dxbc::PSV::v3::RuntimeInfo BaseData
SmallVector< uint32_t > PatchOrPrimMasks
SmallVector< uint32_t > PatchOutputMap
SmallVector< dxbc::PSV::v2::ResourceBindInfo > Resources
SmallVector< PSVSignatureElement > InputElements
LLVM_ABI void finalize(Triple::EnvironmentType Stage, uint32_t Version=std::numeric_limits< uint32_t >::max())
SmallVector< uint32_t > InputPatchMap
SmallVector< PSVSignatureElement > OutputElements
SmallVector< PSVSignatureElement > PatchOrPrimElements
LLVM_ABI void write(raw_ostream &OS, uint32_t Version=std::numeric_limits< uint32_t >::max()) const
std::array< SmallVector< uint32_t >, 4 > OutputVectorMasks
std::array< SmallVector< uint32_t >, 4 > InputOutputMap