/src/spirv-tools/source/table2.cpp
Line | Count | Source |
1 | | // Copyright (c) 2025 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | // Compressed grammar tables. |
16 | | |
17 | | #include "source/table2.h" |
18 | | |
19 | | #include <algorithm> |
20 | | #include <array> |
21 | | #include <cstring> |
22 | | |
23 | | #include "source/extensions.h" |
24 | | #include "source/latest_version_spirv_header.h" |
25 | | #include "source/spirv_constant.h" |
26 | | #include "source/spirv_target_env.h" |
27 | | #include "spirv-tools/libspirv.hpp" |
28 | | |
29 | | namespace spvtools { |
30 | | namespace { |
31 | | |
32 | | // This is used in the source for the generated tables. |
33 | 32.5M | constexpr inline IndexRange IR(uint32_t first, uint32_t count) { |
34 | 32.5M | return IndexRange{first, count}; |
35 | 32.5M | } |
36 | | |
37 | | struct NameIndex { |
38 | | // Location of the null-terminated name in the global string table kStrings. |
39 | | IndexRange name; |
40 | | // Index of this name's entry in the corresponding by-value table. |
41 | | uint32_t index; |
42 | | }; |
43 | | |
44 | | struct NameValue { |
45 | | // Location of the null-terminated name in the global string table kStrings. |
46 | | IndexRange name; |
47 | | // Enum value in the binary format. |
48 | | uint32_t value; |
49 | | }; |
50 | | |
51 | | // The generated include file contains variables: |
52 | | // |
53 | | // std::array<NameIndex,...> kOperandNames: |
54 | | // Operand names and index, ordered by (operand kind, name) |
55 | | // The index part is the named entry's index in kOperandsByValue array. |
56 | | // Aliases are included as their own entries. |
57 | | // |
58 | | // std::array<OperandDesc, ...> kOperandsByValue: |
59 | | // Operand descriptions, ordered by (operand kind, operand enum value). |
60 | | // |
61 | | // std::array<NameIndex,...> kInstructionNames: |
62 | | // Instruction names and index, ordered by (name, value) |
63 | | // The index part is the named entry's index in kInstructionDesc array. |
64 | | // Aliases are included as their own entries. |
65 | | // |
66 | | // std::array<InstructionDesc, ...> kInstructionDesc |
67 | | // Instruction descriptions, ordered by opcode. |
68 | | // |
69 | | // const char kStrings[] |
70 | | // Array of characters, referenced by IndexRanges elsewhere. |
71 | | // Each IndexRange denotes a string. |
72 | | // |
73 | | // const IndexRange kAliasSpans[] |
74 | | // Array of IndexRanges, where each represents a string by referencing |
75 | | // the kStrings table. |
76 | | // This array contains all sequences of alias strings used in the grammar. |
77 | | // This table is referenced by an IndexRange elsewhere, i.e. by the |
78 | | // 'aliases' field of an instruction or operand description. |
79 | | // |
80 | | // const spv::Capability kCapabilitySpans[] |
81 | | // Array of capabilities, referenced by IndexRanges elsewhere. |
82 | | // Contains all sequences of capabilities used in the grammar. |
83 | | // |
84 | | // const spvtools::Extension kExtensionSpans[] = { |
85 | | // Array of extensions, referenced by IndexRanges elsewhere. |
86 | | // Contains all sequences of extensions used in the grammar. |
87 | | // |
88 | | // const spv_operand_type_t kOperandSpans[] = { |
89 | | // Array of operand types, referenced by IndexRanges elsewhere. |
90 | | // Contains all sequences of operand types used in the grammar. |
91 | | |
92 | | // Maps an operand kind to NameValue entries for that kind. |
93 | | // The result is an IndexRange into kOperandNames, and are sorted |
94 | | // by string name within that span. |
95 | | IndexRange OperandNameRangeForKind(spv_operand_type_t type); |
96 | | |
97 | | // Maps an operand kind to possible operands for that kind. |
98 | | // The result is an IndexRange into kOperandsByValue, and the operands |
99 | | // are sorted by value within that span. |
100 | | IndexRange OperandByValueRangeForKind(spv_operand_type_t type); |
101 | | |
102 | | // Maps an extended instruction set kind to NameValue entries for that kind. |
103 | | // The result is an IndexRange into kExtIntNames, and are sorted |
104 | | // by string name within that span. |
105 | | IndexRange ExtInstNameRangeForKind(spv_ext_inst_type_t type); |
106 | | |
107 | | // Maps an extended instruction set kind to possible operands for that kind. |
108 | | // The result is an IndexRange into kExtInstByValue, and the instructions |
109 | | // are sorted by opcode value within that span. |
110 | | IndexRange ExtInstByValueRangeForKind(spv_ext_inst_type_t type); |
111 | | |
112 | | // Returns the name of an extension, as an index into kStrings |
113 | | IndexRange ExtensionToIndexRange(Extension extension); |
114 | | |
115 | | #include "core_tables_body.inc" |
116 | | |
117 | | // Returns a pointer to the null-terminated C-style string in the global |
118 | | // strings table, as referenced by 'ir'. Assumes the given range is valid. |
119 | 7.93M | const char* getChars(IndexRange ir) { |
120 | 7.93M | assert(ir.first() < sizeof(kStrings)); |
121 | 7.93M | return ir.apply(kStrings).data(); |
122 | 7.93M | } |
123 | | |
124 | | } // anonymous namespace |
125 | | |
126 | 19.8M | utils::Span<const spv_operand_type_t> OperandDesc::operands() const { |
127 | 19.8M | return operands_range.apply(kOperandSpans); |
128 | 19.8M | } |
129 | 9.03M | utils::Span<const char> OperandDesc::name() const { |
130 | 9.03M | return name_range.apply(kStrings); |
131 | 9.03M | } |
132 | 0 | utils::Span<const IndexRange> OperandDesc::aliases() const { |
133 | 0 | return name_range.apply(kAliasSpans); |
134 | 0 | } |
135 | 1.17M | utils::Span<const spv::Capability> OperandDesc::capabilities() const { |
136 | 1.17M | return capabilities_range.apply(kCapabilitySpans); |
137 | 1.17M | } |
138 | 3.06k | utils::Span<const spvtools::Extension> OperandDesc::extensions() const { |
139 | 3.06k | return extensions_range.apply(kExtensionSpans); |
140 | 3.06k | } |
141 | | |
142 | 88.1M | utils::Span<const spv_operand_type_t> InstructionDesc::operands() const { |
143 | 88.1M | return operands_range.apply(kOperandSpans); |
144 | 88.1M | } |
145 | 13.2M | utils::Span<const char> InstructionDesc::name() const { |
146 | 13.2M | return name_range.apply(kStrings); |
147 | 13.2M | } |
148 | 0 | utils::Span<const IndexRange> InstructionDesc::aliases() const { |
149 | 0 | return name_range.apply(kAliasSpans); |
150 | 0 | } |
151 | 26.9M | utils::Span<const spv::Capability> InstructionDesc::capabilities() const { |
152 | 26.9M | return capabilities_range.apply(kCapabilitySpans); |
153 | 26.9M | } |
154 | 26.8M | utils::Span<const spvtools::Extension> InstructionDesc::extensions() const { |
155 | 26.8M | return extensions_range.apply(kExtensionSpans); |
156 | 26.8M | } |
157 | | |
158 | 493k | utils::Span<const spv_operand_type_t> ExtInstDesc::operands() const { |
159 | 493k | return operands_range.apply(kOperandSpans); |
160 | 493k | } |
161 | 151k | utils::Span<const char> ExtInstDesc::name() const { |
162 | 151k | return name_range.apply(kStrings); |
163 | 151k | } |
164 | 0 | utils::Span<const spv::Capability> ExtInstDesc::capabilities() const { |
165 | 0 | return capabilities_range.apply(kCapabilitySpans); |
166 | 0 | } |
167 | | |
168 | 127M | spv_result_t LookupOpcode(spv::Op opcode, const InstructionDesc** desc) { |
169 | | // Metaphor: Look for the needle in the haystack. |
170 | 127M | const InstructionDesc needle(opcode); |
171 | 127M | auto where = std::lower_bound( |
172 | 127M | kInstructionDesc.begin(), kInstructionDesc.end(), needle, |
173 | 1.21G | [&](const InstructionDesc& lhs, const InstructionDesc& rhs) { |
174 | 1.21G | return uint32_t(lhs.opcode) < uint32_t(rhs.opcode); |
175 | 1.21G | }); |
176 | 127M | if (where != kInstructionDesc.end() && where->opcode == opcode) { |
177 | 127M | *desc = &*where; |
178 | 127M | return SPV_SUCCESS; |
179 | 127M | } |
180 | 45.4k | return SPV_ERROR_INVALID_LOOKUP; |
181 | 127M | } |
182 | | |
183 | 640k | spv_result_t LookupOpcode(const char* name, const InstructionDesc** desc) { |
184 | | // The comparison function knows to use 'name' string to compare against |
185 | | // when the value is kSentinel. |
186 | 640k | const auto kSentinel = uint32_t(-1); |
187 | 640k | const NameIndex needle{{}, kSentinel}; |
188 | 6.22M | auto less = [&](const NameIndex& lhs, const NameIndex& rhs) { |
189 | 6.22M | const char* lhs_chars = lhs.index == kSentinel ? name : getChars(lhs.name); |
190 | 6.22M | const char* rhs_chars = rhs.index == kSentinel ? name : getChars(rhs.name); |
191 | 6.22M | return std::strcmp(lhs_chars, rhs_chars) < 0; |
192 | 6.22M | }; |
193 | | |
194 | 640k | auto where = std::lower_bound(kInstructionNames.begin(), |
195 | 640k | kInstructionNames.end(), needle, less); |
196 | 640k | if (where != kInstructionNames.end() && |
197 | 640k | std::strcmp(getChars(where->name), name) == 0) { |
198 | 639k | *desc = &kInstructionDesc[where->index]; |
199 | 639k | return SPV_SUCCESS; |
200 | 639k | } |
201 | 578 | return SPV_ERROR_INVALID_LOOKUP; |
202 | 640k | } |
203 | | |
204 | | namespace { |
205 | | template <typename KEY_TYPE> |
206 | | spv_result_t LookupOpcodeForEnvInternal(spv_target_env env, KEY_TYPE key, |
207 | 14.1M | const InstructionDesc** desc) { |
208 | 14.1M | const InstructionDesc* desc_proxy; |
209 | 14.1M | auto status = LookupOpcode(key, &desc_proxy); |
210 | 14.1M | if (status != SPV_SUCCESS) { |
211 | 578 | return status; |
212 | 578 | } |
213 | 14.1M | const auto& entry = *desc_proxy; |
214 | 14.1M | const auto version = spvVersionForTargetEnv(env); |
215 | 14.1M | if ((version >= entry.minVersion && version <= entry.lastVersion) || |
216 | 21.2k | entry.extensions_range.count() > 0 || |
217 | 14.1M | entry.capabilities_range.count() > 0) { |
218 | 14.1M | *desc = desc_proxy; |
219 | 14.1M | return SPV_SUCCESS; |
220 | 14.1M | } |
221 | 16 | return SPV_ERROR_INVALID_LOOKUP; |
222 | 14.1M | } table2.cpp:spv_result_t spvtools::(anonymous namespace)::LookupOpcodeForEnvInternal<char const*>(spv_target_env, char const*, spvtools::InstructionDesc const**) Line | Count | Source | 207 | 640k | const InstructionDesc** desc) { | 208 | 640k | const InstructionDesc* desc_proxy; | 209 | 640k | auto status = LookupOpcode(key, &desc_proxy); | 210 | 640k | if (status != SPV_SUCCESS) { | 211 | 578 | return status; | 212 | 578 | } | 213 | 639k | const auto& entry = *desc_proxy; | 214 | 639k | const auto version = spvVersionForTargetEnv(env); | 215 | 639k | if ((version >= entry.minVersion && version <= entry.lastVersion) || | 216 | 18.3k | entry.extensions_range.count() > 0 || | 217 | 639k | entry.capabilities_range.count() > 0) { | 218 | 639k | *desc = desc_proxy; | 219 | 639k | return SPV_SUCCESS; | 220 | 639k | } | 221 | 2 | return SPV_ERROR_INVALID_LOOKUP; | 222 | 639k | } |
table2.cpp:spv_result_t spvtools::(anonymous namespace)::LookupOpcodeForEnvInternal<spv::Op>(spv_target_env, spv::Op, spvtools::InstructionDesc const**) Line | Count | Source | 207 | 13.4M | const InstructionDesc** desc) { | 208 | 13.4M | const InstructionDesc* desc_proxy; | 209 | 13.4M | auto status = LookupOpcode(key, &desc_proxy); | 210 | 13.4M | if (status != SPV_SUCCESS) { | 211 | 0 | return status; | 212 | 0 | } | 213 | 13.4M | const auto& entry = *desc_proxy; | 214 | 13.4M | const auto version = spvVersionForTargetEnv(env); | 215 | 13.4M | if ((version >= entry.minVersion && version <= entry.lastVersion) || | 216 | 2.88k | entry.extensions_range.count() > 0 || | 217 | 13.4M | entry.capabilities_range.count() > 0) { | 218 | 13.4M | *desc = desc_proxy; | 219 | 13.4M | return SPV_SUCCESS; | 220 | 13.4M | } | 221 | 14 | return SPV_ERROR_INVALID_LOOKUP; | 222 | 13.4M | } |
|
223 | | } // namespace |
224 | | |
225 | | spv_result_t LookupOpcodeForEnv(spv_target_env env, const char* name, |
226 | 640k | const InstructionDesc** desc) { |
227 | 640k | return LookupOpcodeForEnvInternal(env, name, desc); |
228 | 640k | } |
229 | | |
230 | | spv_result_t LookupOpcodeForEnv(spv_target_env env, spv::Op opcode, |
231 | 13.4M | const InstructionDesc** desc) { |
232 | 13.4M | return LookupOpcodeForEnvInternal(env, opcode, desc); |
233 | 13.4M | } |
234 | | |
235 | | spv_result_t LookupOperand(spv_operand_type_t type, uint32_t value, |
236 | 31.5M | const OperandDesc** desc) { |
237 | 31.5M | auto ir = OperandByValueRangeForKind(type); |
238 | 31.5M | if (ir.empty()) { |
239 | 856k | return SPV_ERROR_INVALID_LOOKUP; |
240 | 856k | } |
241 | | |
242 | 30.6M | auto span = ir.apply(kOperandsByValue.data()); |
243 | | |
244 | | // Metaphor: Look for the needle in the haystack. |
245 | | // The operand value is the first member. |
246 | 30.6M | const OperandDesc needle{value}; |
247 | 30.6M | auto where = |
248 | 30.6M | std::lower_bound(span.begin(), span.end(), needle, |
249 | 159M | [&](const OperandDesc& lhs, const OperandDesc& rhs) { |
250 | 159M | return lhs.value < rhs.value; |
251 | 159M | }); |
252 | 30.6M | if (where != span.end() && where->value == value) { |
253 | 30.5M | *desc = &*where; |
254 | 30.5M | return SPV_SUCCESS; |
255 | 30.5M | } |
256 | 52.7k | return SPV_ERROR_INVALID_LOOKUP; |
257 | 30.6M | } |
258 | | |
259 | | spv_result_t LookupOperand(spv_operand_type_t type, const char* name, |
260 | 159k | size_t name_len, const OperandDesc** desc) { |
261 | 159k | auto ir = OperandNameRangeForKind(type); |
262 | 159k | if (ir.empty()) { |
263 | 0 | return SPV_ERROR_INVALID_LOOKUP; |
264 | 0 | } |
265 | | |
266 | 159k | auto span = ir.apply(kOperandNames.data()); |
267 | | |
268 | | // The comparison function knows to use (name, name_len) as the |
269 | | // string to compare against when the value is kSentinel. |
270 | 159k | const auto kSentinel = uint32_t(-1); |
271 | 159k | const NameIndex needle{{}, kSentinel}; |
272 | | // The strings in the global string table are null-terminated, and the count |
273 | | // reflects that. So always deduct 1 from its length. |
274 | 555k | auto less = [&](const NameIndex& lhs, const NameIndex& rhs) { |
275 | 555k | const char* lhs_chars = lhs.index == kSentinel ? name : getChars(lhs.name); |
276 | 555k | const char* rhs_chars = rhs.index == kSentinel ? name : getChars(rhs.name); |
277 | 555k | const auto content_cmp = std::strncmp(lhs_chars, rhs_chars, name_len); |
278 | 555k | if (content_cmp != 0) { |
279 | 391k | return content_cmp < 0; |
280 | 391k | } |
281 | 164k | const auto lhs_len = |
282 | 164k | lhs.index == kSentinel ? name_len : lhs.name.count() - 1; |
283 | 164k | const auto rhs_len = |
284 | 164k | rhs.index == kSentinel ? name_len : rhs.name.count() - 1; |
285 | 164k | return lhs_len < rhs_len; |
286 | 555k | }; |
287 | | |
288 | 159k | auto where = std::lower_bound(span.begin(), span.end(), needle, less); |
289 | 159k | if (where != span.end() && where->name.count() - 1 == name_len && |
290 | 159k | std::strncmp(getChars(where->name), name, name_len) == 0) { |
291 | 159k | *desc = &kOperandsByValue[where->index]; |
292 | 159k | return SPV_SUCCESS; |
293 | 159k | } |
294 | 692 | return SPV_ERROR_INVALID_LOOKUP; |
295 | 159k | } |
296 | | |
297 | | spv_result_t LookupExtInst(spv_ext_inst_type_t type, const char* name, |
298 | 13.9k | const ExtInstDesc** desc) { |
299 | 13.9k | auto ir = ExtInstNameRangeForKind(type); |
300 | 13.9k | if (ir.empty()) { |
301 | 6.79k | return SPV_ERROR_INVALID_LOOKUP; |
302 | 6.79k | } |
303 | | |
304 | 7.19k | auto span = ir.apply(kExtInstNames.data()); |
305 | | |
306 | | // The comparison function knows to use 'name' string to compare against |
307 | | // when the value is kSentinel. |
308 | 7.19k | const auto kSentinel = uint32_t(-1); |
309 | 7.19k | const NameIndex needle{{}, kSentinel}; |
310 | 39.9k | auto less = [&](const NameIndex& lhs, const NameIndex& rhs) { |
311 | 39.9k | const char* lhs_chars = lhs.index == kSentinel ? name : getChars(lhs.name); |
312 | 39.9k | const char* rhs_chars = rhs.index == kSentinel ? name : getChars(rhs.name); |
313 | 39.9k | return std::strcmp(lhs_chars, rhs_chars) < 0; |
314 | 39.9k | }; |
315 | | |
316 | 7.19k | auto where = std::lower_bound(span.begin(), span.end(), needle, less); |
317 | 7.19k | if (where != span.end() && std::strcmp(getChars(where->name), name) == 0) { |
318 | 3.48k | *desc = &kExtInstByValue[where->index]; |
319 | 3.48k | return SPV_SUCCESS; |
320 | 3.48k | } |
321 | 3.70k | return SPV_ERROR_INVALID_LOOKUP; |
322 | 7.19k | } |
323 | | |
324 | | // Finds the extended instruction description by opcode value. |
325 | | // On success, returns SPV_SUCCESS and updates *desc. |
326 | | spv_result_t LookupExtInst(spv_ext_inst_type_t type, uint32_t value, |
327 | 871k | const ExtInstDesc** desc) { |
328 | 871k | auto ir = ExtInstByValueRangeForKind(type); |
329 | 871k | if (ir.empty()) { |
330 | 218k | return SPV_ERROR_INVALID_LOOKUP; |
331 | 218k | } |
332 | | |
333 | 652k | auto span = ir.apply(kExtInstByValue.data()); |
334 | | |
335 | | // Metaphor: Look for the needle in the haystack. |
336 | | // The operand value is the first member. |
337 | 652k | const ExtInstDesc needle(value); |
338 | 652k | auto where = |
339 | 652k | std::lower_bound(span.begin(), span.end(), needle, |
340 | 4.33M | [&](const ExtInstDesc& lhs, const ExtInstDesc& rhs) { |
341 | 4.33M | return lhs.value < rhs.value; |
342 | 4.33M | }); |
343 | 652k | if (where != span.end() && where->value == value) { |
344 | 641k | *desc = &*where; |
345 | 641k | return SPV_SUCCESS; |
346 | 641k | } |
347 | 10.6k | return SPV_ERROR_INVALID_LOOKUP; |
348 | 652k | } |
349 | | |
350 | 39.3k | const char* ExtensionToString(Extension extension) { |
351 | 39.3k | return getChars(ExtensionToIndexRange(extension)); |
352 | 39.3k | } |
353 | | |
354 | 32.8k | bool GetExtensionFromString(const char* name, Extension* extension) { |
355 | | // The comparison function knows to use 'name' string to compare against |
356 | | // when the value is kSentinel. |
357 | 32.8k | const auto kSentinel = uint32_t(-1); |
358 | 32.8k | const NameValue needle{{}, kSentinel}; |
359 | 248k | auto less = [&](const NameValue& lhs, const NameValue& rhs) { |
360 | 248k | const char* lhs_chars = lhs.value == kSentinel ? name : getChars(lhs.name); |
361 | 248k | const char* rhs_chars = rhs.value == kSentinel ? name : getChars(rhs.name); |
362 | 248k | return std::strcmp(lhs_chars, rhs_chars) < 0; |
363 | 248k | }; |
364 | | |
365 | 32.8k | auto where = std::lower_bound(kExtensionNames.begin(), kExtensionNames.end(), |
366 | 32.8k | needle, less); |
367 | 32.8k | if (where != kExtensionNames.end() && |
368 | 19.6k | std::strcmp(getChars(where->name), name) == 0) { |
369 | 3.52k | *extension = static_cast<Extension>(where->value); |
370 | 3.52k | return true; |
371 | 3.52k | } |
372 | 29.2k | return false; |
373 | 32.8k | } |
374 | | |
375 | | // This is dirty copy of the spirv.hpp11 function |
376 | | // TODO - Use a generated version of this function |
377 | 5 | const char* StorageClassToString(spv::StorageClass value) { |
378 | 5 | switch (value) { |
379 | 1 | case spv::StorageClass::UniformConstant: |
380 | 1 | return "UniformConstant"; |
381 | 2 | case spv::StorageClass::Input: |
382 | 2 | return "Input"; |
383 | 0 | case spv::StorageClass::Uniform: |
384 | 0 | return "Uniform"; |
385 | 2 | case spv::StorageClass::Output: |
386 | 2 | return "Output"; |
387 | 0 | case spv::StorageClass::Workgroup: |
388 | 0 | return "Workgroup"; |
389 | 0 | case spv::StorageClass::CrossWorkgroup: |
390 | 0 | return "CrossWorkgroup"; |
391 | 0 | case spv::StorageClass::Private: |
392 | 0 | return "Private"; |
393 | 0 | case spv::StorageClass::Function: |
394 | 0 | return "Function"; |
395 | 0 | case spv::StorageClass::Generic: |
396 | 0 | return "Generic"; |
397 | 0 | case spv::StorageClass::PushConstant: |
398 | 0 | return "PushConstant"; |
399 | 0 | case spv::StorageClass::AtomicCounter: |
400 | 0 | return "AtomicCounter"; |
401 | 0 | case spv::StorageClass::Image: |
402 | 0 | return "Image"; |
403 | 0 | case spv::StorageClass::StorageBuffer: |
404 | 0 | return "StorageBuffer"; |
405 | 0 | case spv::StorageClass::TileImageEXT: |
406 | 0 | return "TileImageEXT"; |
407 | 0 | case spv::StorageClass::TileAttachmentQCOM: |
408 | 0 | return "TileAttachmentQCOM"; |
409 | 0 | case spv::StorageClass::NodePayloadAMDX: |
410 | 0 | return "NodePayloadAMDX"; |
411 | 0 | case spv::StorageClass::CallableDataKHR: |
412 | 0 | return "CallableDataKHR"; |
413 | 0 | case spv::StorageClass::IncomingCallableDataKHR: |
414 | 0 | return "IncomingCallableDataKHR"; |
415 | 0 | case spv::StorageClass::RayPayloadKHR: |
416 | 0 | return "RayPayloadKHR"; |
417 | 0 | case spv::StorageClass::HitAttributeKHR: |
418 | 0 | return "HitAttributeKHR"; |
419 | 0 | case spv::StorageClass::IncomingRayPayloadKHR: |
420 | 0 | return "IncomingRayPayloadKHR"; |
421 | 0 | case spv::StorageClass::ShaderRecordBufferKHR: |
422 | 0 | return "ShaderRecordBufferKHR"; |
423 | 0 | case spv::StorageClass::PhysicalStorageBuffer: |
424 | 0 | return "PhysicalStorageBuffer"; |
425 | 0 | case spv::StorageClass::HitObjectAttributeNV: |
426 | 0 | return "HitObjectAttributeNV"; |
427 | 0 | case spv::StorageClass::TaskPayloadWorkgroupEXT: |
428 | 0 | return "TaskPayloadWorkgroupEXT"; |
429 | 0 | case spv::StorageClass::CodeSectionINTEL: |
430 | 0 | return "CodeSectionINTEL"; |
431 | 0 | case spv::StorageClass::DeviceOnlyINTEL: |
432 | 0 | return "DeviceOnlyINTEL"; |
433 | 0 | case spv::StorageClass::HostOnlyINTEL: |
434 | 0 | return "HostOnlyINTEL"; |
435 | 0 | default: |
436 | 0 | return "Unknown"; |
437 | 5 | } |
438 | 5 | } |
439 | | |
440 | | } // namespace spvtools |