blob: 1bcdec536bba20289f3c05332ec1f36d339c418f [file] [log] [blame]
Dejan Mircevskib6fe02f2016-01-07 13:44:22 -05001// Copyright (c) 2015-2016 The Khronos Group Inc.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01002//
David Neto9fc86582016-09-01 15:33:59 -04003// 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
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01006//
David Neto9fc86582016-09-01 15:33:59 -04007// http://www.apache.org/licenses/LICENSE-2.0
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01008//
David Neto9fc86582016-09-01 15:33:59 -04009// 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.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010014
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010015#include "opcode.h"
16
17#include <assert.h>
18#include <string.h>
19
David Neto5a0b5ca2016-12-09 14:01:43 -050020#include <algorithm>
Lei Zhang972788b2015-11-12 13:48:30 -050021#include <cstdlib>
22
Lei Zhang923f6c12015-11-11 12:45:23 -050023#include "instruction.h"
Lei Zhangca1bf942016-04-27 16:47:13 -040024#include "macro.h"
David Neto5a703352016-02-17 14:44:00 -050025#include "spirv-tools/libspirv.h"
Lei Zhangaa056cd2015-11-11 14:24:04 -050026#include "spirv_constant.h"
David Neto4c215712015-12-22 15:08:41 -050027#include "spirv_endian.h"
Lei Zhang923f6c12015-11-11 12:45:23 -050028
David Neto78c3b432015-08-27 13:03:52 -040029namespace {
Lei Zhang16981f82017-09-21 17:24:57 -040030struct OpcodeDescPtrLen {
31 const spv_opcode_desc_t* ptr;
32 uint32_t len;
33};
David Neto78c3b432015-08-27 13:03:52 -040034
David Neto00fa3932018-02-09 14:29:02 -050035#include "core.insts-unified1.inc" // defines kOpcodeTableEntries_1_3
Lei Zhang16981f82017-09-21 17:24:57 -040036
Lei Zhang1ef6b192018-03-14 13:06:18 -040037static const spv_opcode_table_t kOpcodeTable = {ARRAY_SIZE(kOpcodeTableEntries),
38 kOpcodeTableEntries};
David Neto78c3b432015-08-27 13:03:52 -040039
David Neto5a0b5ca2016-12-09 14:01:43 -050040// Represents a vendor tool entry in the SPIR-V XML Regsitry.
41struct VendorTool {
42 uint32_t value;
43 const char* vendor;
Lei Zhang16981f82017-09-21 17:24:57 -040044 const char* tool; // Might be empty string.
45 const char* vendor_tool; // Combiantion of vendor and tool.
David Neto5a0b5ca2016-12-09 14:01:43 -050046};
47
48const VendorTool vendor_tools[] = {
49#include "generators.inc"
50};
51
Lei Zhanga94701d2015-09-14 10:05:37 -040052} // anonymous namespace
David Neto78c3b432015-08-27 13:03:52 -040053
David Neto5a0b5ca2016-12-09 14:01:43 -050054// TODO(dneto): Move this to another file. It doesn't belong with opcode
55// processing.
Lei Zhang1a0334e2015-11-02 09:41:20 -050056const char* spvGeneratorStr(uint32_t generator) {
David Neto5a0b5ca2016-12-09 14:01:43 -050057 auto where = std::find_if(
58 std::begin(vendor_tools), std::end(vendor_tools),
59 [generator](const VendorTool& vt) { return generator == vt.value; });
60 if (where != std::end(vendor_tools)) return where->vendor_tool;
61 return "Unknown";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010062}
63
Lei Zhangb36e7042015-10-28 13:40:52 -040064uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010065 return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
66}
67
Lei Zhang6fa3f8a2016-03-31 17:26:31 -040068void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount,
69 uint16_t* pOpcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010070 if (pWordCount) {
71 *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
72 }
73 if (pOpcode) {
Lei Zhang6fa3f8a2016-03-31 17:26:31 -040074 *pOpcode = 0x0000ffff & word;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010075 }
76}
77
Lei Zhang1ef6b192018-03-14 13:06:18 -040078spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable, spv_target_env) {
Lei Zhang40056702015-09-11 14:31:27 -040079 if (!pInstTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010080
Lei Zhang16981f82017-09-21 17:24:57 -040081 // Descriptions of each opcode. Each entry describes the format of the
82 // instruction that follows a particular opcode.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010083
Lei Zhang1ef6b192018-03-14 13:06:18 -040084 *pInstTable = &kOpcodeTable;
85 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010086}
87
Lei Zhang1ef6b192018-03-14 13:06:18 -040088spv_result_t spvOpcodeTableNameLookup(spv_target_env env,
89 const spv_opcode_table table,
Lei Zhang1a0334e2015-11-02 09:41:20 -050090 const char* name,
91 spv_opcode_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040092 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
93 if (!table) return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010094
95 // TODO: This lookup of the Opcode table is suboptimal! Binary sort would be
96 // preferable but the table requires sorting on the Opcode name, but it's
Lei Zhang1ef6b192018-03-14 13:06:18 -040097 // static const initialized and matches the order of the spec.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010098 const size_t nameLength = strlen(name);
99 for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400100 const spv_opcode_desc_t& entry = table->entries[opcodeIndex];
101 // We considers the current opcode as available as long as
102 // 1. The target environment satisfies the minimal requirement of the
103 // opcode; or
104 // 2. There is at least one extension enabling this opcode.
105 //
106 // Note that the second rule assumes the extension enabling this instruction
107 // is indeed requested in the SPIR-V code; checking that should be
108 // validator's work.
109 if ((static_cast<uint32_t>(env) >= entry.minVersion ||
110 entry.numExtensions > 0u) &&
111 nameLength == strlen(entry.name) &&
112 !strncmp(name, entry.name, nameLength)) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100113 // NOTE: Found out Opcode!
Lei Zhang1ef6b192018-03-14 13:06:18 -0400114 *pEntry = &entry;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100115 return SPV_SUCCESS;
116 }
117 }
118
119 return SPV_ERROR_INVALID_LOOKUP;
120}
121
Lei Zhang1ef6b192018-03-14 13:06:18 -0400122spv_result_t spvOpcodeTableValueLookup(spv_target_env env,
123 const spv_opcode_table table,
Lei Zhangb36e7042015-10-28 13:40:52 -0400124 const SpvOp opcode,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500125 spv_opcode_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400126 if (!table) return SPV_ERROR_INVALID_TABLE;
127 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100128
Jesus Carabanof063f912017-10-27 15:28:50 +0300129 const auto beg = table->entries;
130 const auto end = table->entries + table->count;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400131
132 spv_opcode_desc_t needle = {"", opcode, 0, nullptr, 0, {},
133 false, false, 0, nullptr, ~0u};
134
Jesus Carabanof063f912017-10-27 15:28:50 +0300135 auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
136 return lhs.opcode < rhs.opcode;
137 };
Lei Zhang1ef6b192018-03-14 13:06:18 -0400138
139 // We need to loop here because there can exist multiple symbols for the same
140 // opcode value, and they can be introduced in different target environments,
141 // which means they can have different minimal version requirements.
142 // Assumes the underlying table is already sorted ascendingly according to
143 // opcode value.
144 for (auto it = std::lower_bound(beg, end, needle, comp);
145 it != end && it->opcode == opcode; ++it) {
146 // We considers the current opcode as available as long as
147 // 1. The target environment satisfies the minimal requirement of the
148 // opcode; or
149 // 2. There is at least one extension enabling this opcode.
150 //
151 // Note that the second rule assumes the extension enabling this instruction
152 // is indeed requested in the SPIR-V code; checking that should be
153 // validator's work.
154 if (static_cast<uint32_t>(env) >= it->minVersion ||
155 it->numExtensions > 0u) {
156 *pEntry = it;
157 return SPV_SUCCESS;
158 }
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100159 }
160
161 return SPV_ERROR_INVALID_LOOKUP;
162}
163
Lei Zhang1a0334e2015-11-02 09:41:20 -0500164void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100165 const uint16_t wordCount, const spv_endianness_t endian,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500166 spv_instruction_t* pInst) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100167 pInst->opcode = opcode;
David Netob5dc8fc2015-10-06 16:22:00 -0400168 pInst->words.resize(wordCount);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100169 for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
170 pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
171 if (!wordIndex) {
172 uint16_t thisWordCount;
Lei Zhang6fa3f8a2016-03-31 17:26:31 -0400173 uint16_t thisOpcode;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100174 spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
Lei Zhang6fa3f8a2016-03-31 17:26:31 -0400175 assert(opcode == static_cast<SpvOp>(thisOpcode) &&
176 wordCount == thisWordCount && "Endianness failed!");
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100177 }
178 }
179}
180
Lei Zhang1a0334e2015-11-02 09:41:20 -0500181const char* spvOpcodeString(const SpvOp opcode) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400182 const auto beg = kOpcodeTableEntries;
183 const auto end = kOpcodeTableEntries + ARRAY_SIZE(kOpcodeTableEntries);
184 spv_opcode_desc_t needle = {"", opcode, 0, nullptr, 0, {},
185 false, false, 0, nullptr, ~0u};
Jesus Carabanof063f912017-10-27 15:28:50 +0300186 auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
187 return lhs.opcode < rhs.opcode;
188 };
Lei Zhang1ef6b192018-03-14 13:06:18 -0400189 auto it = std::lower_bound(beg, end, needle, comp);
Diego Novillod2938e42017-11-08 12:40:02 -0500190 if (it != end && it->opcode == opcode) {
Jesus Carabanof063f912017-10-27 15:28:50 +0300191 return it->name;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100192 }
Lei Zhang16981f82017-09-21 17:24:57 -0400193
Lei Zhang4f293b72016-03-21 16:36:14 -0400194 assert(0 && "Unreachable!");
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100195 return "unknown";
196}
197
Lei Zhangb36e7042015-10-28 13:40:52 -0400198int32_t spvOpcodeIsScalarType(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100199 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400200 case SpvOpTypeInt:
201 case SpvOpTypeFloat:
Dejan Mircevski276a7242016-01-21 15:55:43 -0500202 case SpvOpTypeBool:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100203 return true;
204 default:
205 return false;
206 }
207}
208
Alan Baker0a2ee652018-03-23 14:18:54 -0400209int32_t spvOpcodeIsSpecConstant(const SpvOp opcode) {
210 switch (opcode) {
211 case SpvOpSpecConstantTrue:
212 case SpvOpSpecConstantFalse:
213 case SpvOpSpecConstant:
214 case SpvOpSpecConstantComposite:
215 case SpvOpSpecConstantOp:
216 return true;
217 default:
218 return false;
219 }
220}
221
Lei Zhangb36e7042015-10-28 13:40:52 -0400222int32_t spvOpcodeIsConstant(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100223 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400224 case SpvOpConstantTrue:
225 case SpvOpConstantFalse:
226 case SpvOpConstant:
227 case SpvOpConstantComposite:
228 case SpvOpConstantSampler:
Lei Zhangb36e7042015-10-28 13:40:52 -0400229 case SpvOpConstantNull:
230 case SpvOpSpecConstantTrue:
231 case SpvOpSpecConstantFalse:
232 case SpvOpSpecConstant:
233 case SpvOpSpecConstantComposite:
Dejan Mircevski3fb26762016-04-04 15:55:05 -0400234 case SpvOpSpecConstantOp:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100235 return true;
236 default:
237 return false;
238 }
239}
240
David Neto1f3fb502016-09-14 11:57:20 -0400241bool spvOpcodeIsConstantOrUndef(const SpvOp opcode) {
242 return opcode == SpvOpUndef || spvOpcodeIsConstant(opcode);
243}
244
Aliya Pazylbekovaedb52642017-02-24 20:43:28 -0500245bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode) {
246 switch (opcode) {
247 case SpvOpSpecConstantTrue:
248 case SpvOpSpecConstantFalse:
249 case SpvOpSpecConstant:
250 return true;
251 default:
252 return false;
253 }
254}
255
Lei Zhangb36e7042015-10-28 13:40:52 -0400256int32_t spvOpcodeIsComposite(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100257 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400258 case SpvOpTypeVector:
259 case SpvOpTypeMatrix:
260 case SpvOpTypeArray:
261 case SpvOpTypeStruct:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100262 return true;
263 default:
264 return false;
265 }
266}
267
Ehsan Nasiri23af06c2017-02-01 15:37:39 -0500268bool spvOpcodeReturnsLogicalVariablePointer(const SpvOp opcode) {
269 switch (opcode) {
270 case SpvOpVariable:
271 case SpvOpAccessChain:
272 case SpvOpInBoundsAccessChain:
273 case SpvOpFunctionParameter:
274 case SpvOpImageTexelPointer:
275 case SpvOpCopyObject:
276 case SpvOpSelect:
277 case SpvOpPhi:
278 case SpvOpFunctionCall:
279 case SpvOpPtrAccessChain:
280 case SpvOpLoad:
281 case SpvOpConstantNull:
282 return true;
283 default:
284 return false;
285 }
286}
287
Florian Ziesche66fcb452016-03-02 22:17:54 +0100288int32_t spvOpcodeReturnsLogicalPointer(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100289 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400290 case SpvOpVariable:
291 case SpvOpAccessChain:
292 case SpvOpInBoundsAccessChain:
293 case SpvOpFunctionParameter:
Florian Ziesche66fcb452016-03-02 22:17:54 +0100294 case SpvOpImageTexelPointer:
295 case SpvOpCopyObject:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100296 return true;
297 default:
298 return false;
299 }
300}
301
Lei Zhangb36e7042015-10-28 13:40:52 -0400302int32_t spvOpcodeGeneratesType(SpvOp op) {
Lei Zhang1a0334e2015-11-02 09:41:20 -0500303 switch (op) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400304 case SpvOpTypeVoid:
305 case SpvOpTypeBool:
306 case SpvOpTypeInt:
307 case SpvOpTypeFloat:
308 case SpvOpTypeVector:
309 case SpvOpTypeMatrix:
310 case SpvOpTypeImage:
311 case SpvOpTypeSampler:
312 case SpvOpTypeSampledImage:
313 case SpvOpTypeArray:
314 case SpvOpTypeRuntimeArray:
315 case SpvOpTypeStruct:
316 case SpvOpTypeOpaque:
317 case SpvOpTypePointer:
318 case SpvOpTypeFunction:
319 case SpvOpTypeEvent:
320 case SpvOpTypeDeviceEvent:
321 case SpvOpTypeReserveId:
322 case SpvOpTypeQueue:
323 case SpvOpTypePipe:
Andrey Tuganov4ef3b3e2017-02-28 11:53:47 -0500324 case SpvOpTypePipeStorage:
325 case SpvOpTypeNamedBarrier:
Andrew Woloszyn537e7762015-09-29 11:28:34 -0400326 return true;
David Netoaef608c2015-11-02 14:59:02 -0500327 default:
328 // In particular, OpTypeForwardPointer does not generate a type,
329 // but declares a storage class for a pointer type generated
330 // by a different instruction.
331 break;
Andrew Woloszyn537e7762015-09-29 11:28:34 -0400332 }
333 return 0;
334}
Steven Perroneb4653a2017-11-13 15:31:43 -0500335
336bool spvOpcodeIsDecoration(const SpvOp opcode) {
Steven Perron28c41552017-11-10 20:26:55 -0500337 switch (opcode) {
Steven Perroneb4653a2017-11-13 15:31:43 -0500338 case SpvOpDecorate:
339 case SpvOpDecorateId:
340 case SpvOpMemberDecorate:
341 case SpvOpGroupDecorate:
342 case SpvOpGroupMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500343 case SpvOpDecorateStringGOOGLE:
344 case SpvOpMemberDecorateStringGOOGLE:
Steven Perroneb4653a2017-11-13 15:31:43 -0500345 return true;
346 default:
347 break;
348 }
349 return false;
350}
Steven Perron28c41552017-11-10 20:26:55 -0500351
352bool spvOpcodeIsLoad(const SpvOp opcode) {
353 switch (opcode) {
354 case SpvOpLoad:
355 case SpvOpImageSampleExplicitLod:
356 case SpvOpImageSampleImplicitLod:
357 case SpvOpImageSampleDrefImplicitLod:
358 case SpvOpImageSampleDrefExplicitLod:
359 case SpvOpImageSampleProjImplicitLod:
360 case SpvOpImageSampleProjExplicitLod:
361 case SpvOpImageSampleProjDrefImplicitLod:
362 case SpvOpImageSampleProjDrefExplicitLod:
363 case SpvOpImageFetch:
364 case SpvOpImageGather:
365 case SpvOpImageDrefGather:
366 case SpvOpImageRead:
367 case SpvOpImageSparseSampleImplicitLod:
368 case SpvOpImageSparseSampleExplicitLod:
369 case SpvOpImageSparseSampleDrefExplicitLod:
370 case SpvOpImageSparseSampleDrefImplicitLod:
371 case SpvOpImageSparseFetch:
372 case SpvOpImageSparseGather:
373 case SpvOpImageSparseDrefGather:
374 case SpvOpImageSparseRead:
375 return true;
376 default:
377 return false;
378 }
379}
380
Diego Novillo74327842017-11-17 08:59:25 -0500381bool spvOpcodeIsBranch(SpvOp opcode) {
382 switch (opcode) {
383 case SpvOpBranch:
384 case SpvOpBranchConditional:
385 case SpvOpSwitch:
386 return true;
387 default:
388 return false;
389 }
390}
391
Steven Perron28c41552017-11-10 20:26:55 -0500392bool spvOpcodeIsAtomicOp(const SpvOp opcode) {
393 switch (opcode) {
394 case SpvOpAtomicLoad:
395 case SpvOpAtomicStore:
396 case SpvOpAtomicExchange:
397 case SpvOpAtomicCompareExchange:
398 case SpvOpAtomicCompareExchangeWeak:
399 case SpvOpAtomicIIncrement:
400 case SpvOpAtomicIDecrement:
401 case SpvOpAtomicIAdd:
402 case SpvOpAtomicISub:
403 case SpvOpAtomicSMin:
404 case SpvOpAtomicUMin:
405 case SpvOpAtomicSMax:
406 case SpvOpAtomicUMax:
407 case SpvOpAtomicAnd:
408 case SpvOpAtomicOr:
409 case SpvOpAtomicXor:
410 case SpvOpAtomicFlagTestAndSet:
411 case SpvOpAtomicFlagClear:
412 return true;
413 default:
414 return false;
415 }
416}
Diego Novillo74327842017-11-17 08:59:25 -0500417
418bool spvOpcodeIsReturn(SpvOp opcode) {
419 switch (opcode) {
420 case SpvOpReturn:
421 case SpvOpReturnValue:
422 return true;
423 default:
424 return false;
425 }
426}
427
Diego Novillo5f100782018-01-03 15:25:03 -0500428bool spvOpcodeIsReturnOrAbort(SpvOp opcode) {
429 return spvOpcodeIsReturn(opcode) || opcode == SpvOpKill ||
430 opcode == SpvOpUnreachable;
431}
432
Diego Novillo74327842017-11-17 08:59:25 -0500433bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
Diego Novillo5f100782018-01-03 15:25:03 -0500434 return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
Diego Novillo74327842017-11-17 08:59:25 -0500435}
Steven Perron79a00642017-12-11 13:10:24 -0500436
437bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
438 switch (opcode) {
439 case SpvOpTypeImage:
440 case SpvOpTypeSampler:
441 case SpvOpTypeSampledImage:
442 case SpvOpTypeOpaque:
443 case SpvOpTypeEvent:
444 case SpvOpTypeDeviceEvent:
445 case SpvOpTypeReserveId:
446 case SpvOpTypeQueue:
447 case SpvOpTypePipe:
448 case SpvOpTypeForwardPointer:
449 case SpvOpTypePipeStorage:
450 case SpvOpTypeNamedBarrier:
451 return true;
452 default:
453 return false;
454 }
455}