/src/spirv-tools/source/val/validation_state.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2015-2016 The Khronos Group Inc. |
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 | | #include "source/val/validation_state.h" |
16 | | |
17 | | #include <cassert> |
18 | | #include <stack> |
19 | | #include <utility> |
20 | | |
21 | | #include "source/opcode.h" |
22 | | #include "source/spirv_constant.h" |
23 | | #include "source/spirv_target_env.h" |
24 | | #include "source/val/basic_block.h" |
25 | | #include "source/val/construct.h" |
26 | | #include "source/val/function.h" |
27 | | #include "spirv-tools/libspirv.h" |
28 | | |
29 | | namespace spvtools { |
30 | | namespace val { |
31 | | namespace { |
32 | | |
33 | | ModuleLayoutSection InstructionLayoutSection( |
34 | 3.71M | ModuleLayoutSection current_section, spv::Op op) { |
35 | | // See Section 2.4 |
36 | 3.71M | if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op)) |
37 | 591k | return kLayoutTypes; |
38 | | |
39 | 3.12M | switch (op) { |
40 | 32.0k | case spv::Op::OpCapability: |
41 | 32.0k | return kLayoutCapabilities; |
42 | 11.5k | case spv::Op::OpExtension: |
43 | 11.5k | return kLayoutExtensions; |
44 | 47.4k | case spv::Op::OpExtInstImport: |
45 | 47.4k | return kLayoutExtInstImport; |
46 | 131k | case spv::Op::OpMemoryModel: |
47 | 131k | return kLayoutMemoryModel; |
48 | 85.8k | case spv::Op::OpEntryPoint: |
49 | 85.8k | return kLayoutEntryPoint; |
50 | 52.7k | case spv::Op::OpExecutionMode: |
51 | 52.7k | case spv::Op::OpExecutionModeId: |
52 | 52.7k | return kLayoutExecutionMode; |
53 | 753 | case spv::Op::OpSourceContinued: |
54 | 26.8k | case spv::Op::OpSource: |
55 | 27.5k | case spv::Op::OpSourceExtension: |
56 | 28.5k | case spv::Op::OpString: |
57 | 28.5k | return kLayoutDebug1; |
58 | 74.0k | case spv::Op::OpName: |
59 | 80.7k | case spv::Op::OpMemberName: |
60 | 80.7k | return kLayoutDebug2; |
61 | 0 | case spv::Op::OpModuleProcessed: |
62 | 0 | return kLayoutDebug3; |
63 | 142k | case spv::Op::OpDecorate: |
64 | 154k | case spv::Op::OpMemberDecorate: |
65 | 442k | case spv::Op::OpGroupDecorate: |
66 | 500k | case spv::Op::OpGroupMemberDecorate: |
67 | 517k | case spv::Op::OpDecorationGroup: |
68 | 517k | case spv::Op::OpDecorateId: |
69 | 518k | case spv::Op::OpDecorateStringGOOGLE: |
70 | 518k | case spv::Op::OpMemberDecorateStringGOOGLE: |
71 | 518k | return kLayoutAnnotations; |
72 | 2.12k | case spv::Op::OpTypeForwardPointer: |
73 | 2.12k | return kLayoutTypes; |
74 | 143k | case spv::Op::OpVariable: |
75 | 143k | if (current_section == kLayoutTypes) return kLayoutTypes; |
76 | 105k | return kLayoutFunctionDefinitions; |
77 | 32.6k | case spv::Op::OpExtInst: |
78 | | // spv::Op::OpExtInst is only allowed in types section for certain |
79 | | // extended instruction sets. This will be checked separately. |
80 | 32.6k | if (current_section == kLayoutTypes) return kLayoutTypes; |
81 | 32.6k | return kLayoutFunctionDefinitions; |
82 | 887 | case spv::Op::OpLine: |
83 | 17.9k | case spv::Op::OpNoLine: |
84 | 23.0k | case spv::Op::OpUndef: |
85 | 23.0k | if (current_section == kLayoutTypes) return kLayoutTypes; |
86 | 5.10k | return kLayoutFunctionDefinitions; |
87 | 82.2k | case spv::Op::OpFunction: |
88 | 94.5k | case spv::Op::OpFunctionParameter: |
89 | 121k | case spv::Op::OpFunctionEnd: |
90 | 121k | if (current_section == kLayoutFunctionDeclarations) |
91 | 38.0k | return kLayoutFunctionDeclarations; |
92 | 83.9k | return kLayoutFunctionDefinitions; |
93 | 88 | case spv::Op::OpSamplerImageAddressingModeNV: |
94 | 88 | return kLayoutSamplerImageAddressMode; |
95 | 1.81M | default: |
96 | 1.81M | break; |
97 | 3.12M | } |
98 | 1.81M | return kLayoutFunctionDefinitions; |
99 | 3.12M | } |
100 | | |
101 | 3.43M | bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) { |
102 | 3.43M | return layout == InstructionLayoutSection(layout, op); |
103 | 3.43M | } |
104 | | |
105 | | // Counts the number of instructions and functions in the file. |
106 | | spv_result_t CountInstructions(void* user_data, |
107 | 3.30M | const spv_parsed_instruction_t* inst) { |
108 | 3.30M | ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data)); |
109 | 3.30M | if (spv::Op(inst->opcode) == spv::Op::OpFunction) { |
110 | 30.2k | _.increment_total_functions(); |
111 | 30.2k | } |
112 | 3.30M | _.increment_total_instructions(); |
113 | | |
114 | 3.30M | return SPV_SUCCESS; |
115 | 3.30M | } |
116 | | |
117 | | spv_result_t setHeader(void* user_data, spv_endianness_t, uint32_t, |
118 | | uint32_t version, uint32_t generator, uint32_t id_bound, |
119 | 30.5k | uint32_t) { |
120 | 30.5k | ValidationState_t& vstate = |
121 | 30.5k | *(reinterpret_cast<ValidationState_t*>(user_data)); |
122 | 30.5k | vstate.setIdBound(id_bound); |
123 | 30.5k | vstate.setGenerator(generator); |
124 | 30.5k | vstate.setVersion(version); |
125 | | |
126 | 30.5k | return SPV_SUCCESS; |
127 | 30.5k | } |
128 | | |
129 | | // Add features based on SPIR-V core version number. |
130 | | void UpdateFeaturesBasedOnSpirvVersion(ValidationState_t::Feature* features, |
131 | 30.6k | uint32_t version) { |
132 | 30.6k | assert(features); |
133 | 30.6k | if (version >= SPV_SPIRV_VERSION_WORD(1, 4)) { |
134 | 196 | features->select_between_composites = true; |
135 | 196 | features->copy_memory_permits_two_memory_accesses = true; |
136 | 196 | features->uconvert_spec_constant_op = true; |
137 | 196 | features->nonwritable_var_in_function_or_private = true; |
138 | 196 | } |
139 | 30.6k | } |
140 | | |
141 | | } // namespace |
142 | | |
143 | | ValidationState_t::ValidationState_t(const spv_const_context ctx, |
144 | | const spv_const_validator_options opt, |
145 | | const uint32_t* words, |
146 | | const size_t num_words, |
147 | | const uint32_t max_warnings) |
148 | | : context_(ctx), |
149 | | options_(opt), |
150 | | words_(words), |
151 | | num_words_(num_words), |
152 | | unresolved_forward_ids_{}, |
153 | | operand_names_{}, |
154 | | current_layout_section_(kLayoutCapabilities), |
155 | | module_functions_(), |
156 | | module_capabilities_(), |
157 | | module_extensions_(), |
158 | | ordered_instructions_(), |
159 | | all_definitions_(), |
160 | | global_vars_(), |
161 | | local_vars_(), |
162 | | struct_nesting_depth_(), |
163 | | struct_has_nested_blockorbufferblock_struct_(), |
164 | | grammar_(ctx), |
165 | | addressing_model_(spv::AddressingModel::Max), |
166 | | memory_model_(spv::MemoryModel::Max), |
167 | | pointer_size_and_alignment_(0), |
168 | | sampler_image_addressing_mode_(0), |
169 | | in_function_(false), |
170 | | num_of_warnings_(0), |
171 | 30.6k | max_num_of_warnings_(max_warnings) { |
172 | 30.6k | assert(opt && "Validator options may not be Null."); |
173 | | |
174 | 0 | const auto env = context_->target_env; |
175 | | |
176 | 30.6k | if (spvIsVulkanEnv(env)) { |
177 | | // Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core. |
178 | 0 | if (env != SPV_ENV_VULKAN_1_0) { |
179 | 0 | features_.env_relaxed_block_layout = true; |
180 | 0 | } |
181 | 0 | } |
182 | | |
183 | | // LocalSizeId is only disallowed prior to Vulkan 1.3 without maintenance4. |
184 | 30.6k | switch (env) { |
185 | 0 | case SPV_ENV_VULKAN_1_0: |
186 | 0 | case SPV_ENV_VULKAN_1_1: |
187 | 0 | case SPV_ENV_VULKAN_1_1_SPIRV_1_4: |
188 | 0 | case SPV_ENV_VULKAN_1_2: |
189 | 0 | features_.env_allow_localsizeid = false; |
190 | 0 | break; |
191 | 30.6k | default: |
192 | 30.6k | features_.env_allow_localsizeid = true; |
193 | 30.6k | break; |
194 | 30.6k | } |
195 | | |
196 | | // Only attempt to count if we have words, otherwise let the other validation |
197 | | // fail and generate an error. |
198 | 30.6k | if (num_words > 0) { |
199 | | // Count the number of instructions in the binary. |
200 | | // This parse should not produce any error messages. Hijack the context and |
201 | | // replace the message consumer so that we do not pollute any state in input |
202 | | // consumer. |
203 | 30.6k | spv_context_t hijacked_context = *ctx; |
204 | 30.6k | hijacked_context.consumer = [](spv_message_level_t, const char*, |
205 | 30.6k | const spv_position_t&, const char*) {}; |
206 | 30.6k | spvBinaryParse(&hijacked_context, this, words, num_words, setHeader, |
207 | 30.6k | CountInstructions, |
208 | 30.6k | /* diagnostic = */ nullptr); |
209 | 30.6k | preallocateStorage(); |
210 | 30.6k | } |
211 | 30.6k | UpdateFeaturesBasedOnSpirvVersion(&features_, version_); |
212 | | |
213 | 30.6k | name_mapper_ = spvtools::GetTrivialNameMapper(); |
214 | 30.6k | if (options_->use_friendly_names) { |
215 | 30.6k | friendly_mapper_ = spvtools::MakeUnique<spvtools::FriendlyNameMapper>( |
216 | 30.6k | context_, words_, num_words_); |
217 | 30.6k | name_mapper_ = friendly_mapper_->GetNameMapper(); |
218 | 30.6k | } |
219 | 30.6k | } |
220 | | |
221 | 30.6k | void ValidationState_t::preallocateStorage() { |
222 | 30.6k | ordered_instructions_.reserve(total_instructions_); |
223 | 30.6k | module_functions_.reserve(total_functions_); |
224 | 30.6k | } |
225 | | |
226 | 1.65M | spv_result_t ValidationState_t::ForwardDeclareId(uint32_t id) { |
227 | 1.65M | unresolved_forward_ids_.insert(id); |
228 | 1.65M | return SPV_SUCCESS; |
229 | 1.65M | } |
230 | | |
231 | 1.78M | spv_result_t ValidationState_t::RemoveIfForwardDeclared(uint32_t id) { |
232 | 1.78M | unresolved_forward_ids_.erase(id); |
233 | 1.78M | return SPV_SUCCESS; |
234 | 1.78M | } |
235 | | |
236 | 442 | spv_result_t ValidationState_t::RegisterForwardPointer(uint32_t id) { |
237 | 442 | forward_pointer_ids_.insert(id); |
238 | 442 | return SPV_SUCCESS; |
239 | 442 | } |
240 | | |
241 | 550k | bool ValidationState_t::IsForwardPointer(uint32_t id) const { |
242 | 550k | return (forward_pointer_ids_.find(id) != forward_pointer_ids_.end()); |
243 | 550k | } |
244 | | |
245 | 62.9k | void ValidationState_t::AssignNameToId(uint32_t id, std::string name) { |
246 | 62.9k | operand_names_[id] = name; |
247 | 62.9k | } |
248 | | |
249 | 55.1k | std::string ValidationState_t::getIdName(uint32_t id) const { |
250 | 55.1k | const std::string id_name = name_mapper_(id); |
251 | | |
252 | 55.1k | std::stringstream out; |
253 | 55.1k | out << "'" << id << "[%" << id_name << "]'"; |
254 | 55.1k | return out.str(); |
255 | 55.1k | } |
256 | | |
257 | 21.4k | size_t ValidationState_t::unresolved_forward_id_count() const { |
258 | 21.4k | return unresolved_forward_ids_.size(); |
259 | 21.4k | } |
260 | | |
261 | 1.81k | std::vector<uint32_t> ValidationState_t::UnresolvedForwardIds() const { |
262 | 1.81k | std::vector<uint32_t> out(std::begin(unresolved_forward_ids_), |
263 | 1.81k | std::end(unresolved_forward_ids_)); |
264 | 1.81k | return out; |
265 | 1.81k | } |
266 | | |
267 | 1.20M | bool ValidationState_t::IsDefinedId(uint32_t id) const { |
268 | 1.20M | return all_definitions_.find(id) != std::end(all_definitions_); |
269 | 1.20M | } |
270 | | |
271 | 10.3M | const Instruction* ValidationState_t::FindDef(uint32_t id) const { |
272 | 10.3M | auto it = all_definitions_.find(id); |
273 | 10.3M | if (it == all_definitions_.end()) return nullptr; |
274 | 9.89M | return it->second; |
275 | 10.3M | } |
276 | | |
277 | 20.4M | Instruction* ValidationState_t::FindDef(uint32_t id) { |
278 | 20.4M | auto it = all_definitions_.find(id); |
279 | 20.4M | if (it == all_definitions_.end()) return nullptr; |
280 | 17.9M | return it->second; |
281 | 20.4M | } |
282 | | |
283 | 7.03M | ModuleLayoutSection ValidationState_t::current_layout_section() const { |
284 | 7.03M | return current_layout_section_; |
285 | 7.03M | } |
286 | | |
287 | 300k | void ValidationState_t::ProgressToNextLayoutSectionOrder() { |
288 | | // Guard against going past the last element(kLayoutFunctionDefinitions) |
289 | 300k | if (current_layout_section_ <= kLayoutFunctionDefinitions) { |
290 | 300k | current_layout_section_ = |
291 | 300k | static_cast<ModuleLayoutSection>(current_layout_section_ + 1); |
292 | 300k | } |
293 | 300k | } |
294 | | |
295 | 283k | bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op) { |
296 | 283k | ModuleLayoutSection section = |
297 | 283k | InstructionLayoutSection(current_layout_section_, op); |
298 | 283k | return section < current_layout_section_; |
299 | 283k | } |
300 | | |
301 | 3.43M | bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op) { |
302 | 3.43M | return IsInstructionInLayoutSection(current_layout_section_, op); |
303 | 3.43M | } |
304 | | |
305 | | DiagnosticStream ValidationState_t::diag(spv_result_t error_code, |
306 | 21.3k | const Instruction* inst) { |
307 | 21.3k | if (error_code == SPV_WARNING) { |
308 | 5.38k | if (num_of_warnings_ == max_num_of_warnings_) { |
309 | 3.14k | DiagnosticStream({0, 0, 0}, context_->consumer, "", error_code) |
310 | 3.14k | << "Other warnings have been suppressed.\n"; |
311 | 3.14k | } |
312 | 5.38k | if (num_of_warnings_ >= max_num_of_warnings_) { |
313 | 3.14k | return DiagnosticStream({0, 0, 0}, nullptr, "", error_code); |
314 | 3.14k | } |
315 | 2.24k | ++num_of_warnings_; |
316 | 2.24k | } |
317 | | |
318 | 18.2k | std::string disassembly; |
319 | 18.2k | if (inst) disassembly = Disassemble(*inst); |
320 | | |
321 | 18.2k | return DiagnosticStream({0, 0, inst ? inst->LineNum() : 0}, |
322 | 18.2k | context_->consumer, disassembly, error_code); |
323 | 21.3k | } |
324 | | |
325 | 82.5k | std::vector<Function>& ValidationState_t::functions() { |
326 | 82.5k | return module_functions_; |
327 | 82.5k | } |
328 | | |
329 | 6.17M | Function& ValidationState_t::current_function() { |
330 | 6.17M | assert(in_function_body()); |
331 | 0 | return module_functions_.back(); |
332 | 6.17M | } |
333 | | |
334 | 0 | const Function& ValidationState_t::current_function() const { |
335 | 0 | assert(in_function_body()); |
336 | 0 | return module_functions_.back(); |
337 | 0 | } |
338 | | |
339 | 0 | const Function* ValidationState_t::function(uint32_t id) const { |
340 | 0 | const auto it = id_to_function_.find(id); |
341 | 0 | if (it == id_to_function_.end()) return nullptr; |
342 | 0 | return it->second; |
343 | 0 | } |
344 | | |
345 | 65.2k | Function* ValidationState_t::function(uint32_t id) { |
346 | 65.2k | auto it = id_to_function_.find(id); |
347 | 65.2k | if (it == id_to_function_.end()) return nullptr; |
348 | 65.2k | return it->second; |
349 | 65.2k | } |
350 | | |
351 | 9.82M | bool ValidationState_t::in_function_body() const { return in_function_; } |
352 | | |
353 | 3.96M | bool ValidationState_t::in_block() const { |
354 | 3.96M | return module_functions_.empty() == false && |
355 | 3.96M | module_functions_.back().current_block() != nullptr; |
356 | 3.96M | } |
357 | | |
358 | 65.0k | void ValidationState_t::RegisterCapability(spv::Capability cap) { |
359 | | // Avoid redundant work. Otherwise the recursion could induce work |
360 | | // quadrdatic in the capability dependency depth. (Ok, not much, but |
361 | | // it's something.) |
362 | 65.0k | if (module_capabilities_.Contains(cap)) return; |
363 | | |
364 | 61.8k | module_capabilities_.Add(cap); |
365 | 61.8k | spv_operand_desc desc; |
366 | 61.8k | if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, |
367 | 61.8k | uint32_t(cap), &desc)) { |
368 | 61.8k | CapabilitySet(desc->numCapabilities, desc->capabilities) |
369 | 61.8k | .ForEach([this](spv::Capability c) { RegisterCapability(c); }); |
370 | 61.8k | } |
371 | | |
372 | 61.8k | switch (cap) { |
373 | 409 | case spv::Capability::Kernel: |
374 | 409 | features_.group_ops_reduce_and_scans = true; |
375 | 409 | break; |
376 | 109 | case spv::Capability::Int8: |
377 | 109 | features_.use_int8_type = true; |
378 | 109 | features_.declare_int8_type = true; |
379 | 109 | break; |
380 | 3 | case spv::Capability::StorageBuffer8BitAccess: |
381 | 5 | case spv::Capability::UniformAndStorageBuffer8BitAccess: |
382 | 8 | case spv::Capability::StoragePushConstant8: |
383 | 13 | case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: |
384 | 13 | features_.declare_int8_type = true; |
385 | 13 | break; |
386 | 81 | case spv::Capability::Int16: |
387 | 81 | features_.declare_int16_type = true; |
388 | 81 | break; |
389 | 71 | case spv::Capability::Float16: |
390 | 141 | case spv::Capability::Float16Buffer: |
391 | 141 | features_.declare_float16_type = true; |
392 | 141 | break; |
393 | 6 | case spv::Capability::StorageUniformBufferBlock16: |
394 | 10 | case spv::Capability::StorageUniform16: |
395 | 13 | case spv::Capability::StoragePushConstant16: |
396 | 15 | case spv::Capability::StorageInputOutput16: |
397 | 18 | case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: |
398 | 18 | features_.declare_int16_type = true; |
399 | 18 | features_.declare_float16_type = true; |
400 | 18 | features_.free_fp_rounding_mode = true; |
401 | 18 | break; |
402 | 6 | case spv::Capability::VariablePointers: |
403 | 14 | case spv::Capability::VariablePointersStorageBuffer: |
404 | 14 | features_.variable_pointers = true; |
405 | 14 | break; |
406 | 61.0k | default: |
407 | | // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses |
408 | | // capability spv::Capability::RayTracingNV. |
409 | | // spv::Capability::RayTracingProvisionalKHR would need the same |
410 | | // treatment. One of the differences going from SPV_KHR_ray_tracing from |
411 | | // provisional to final spec was the provisional spec uses Locations |
412 | | // for variables in certain storage classes, just like the |
413 | | // SPV_NV_ray_tracing extension. So it mimics the NVIDIA extension. |
414 | | // The final SPV_KHR_ray_tracing uses a different capability token |
415 | | // number, so it doesn't fall into this case. |
416 | 61.0k | break; |
417 | 61.8k | } |
418 | 61.8k | } |
419 | | |
420 | 1.66k | void ValidationState_t::RegisterExtension(Extension ext) { |
421 | 1.66k | if (module_extensions_.Contains(ext)) return; |
422 | | |
423 | 597 | module_extensions_.Add(ext); |
424 | | |
425 | 597 | switch (ext) { |
426 | 2 | case kSPV_AMD_gpu_shader_half_float: |
427 | 2 | case kSPV_AMD_gpu_shader_half_float_fetch: |
428 | | // SPV_AMD_gpu_shader_half_float enables float16 type. |
429 | | // https://github.com/KhronosGroup/SPIRV-Tools/issues/1375 |
430 | 2 | features_.declare_float16_type = true; |
431 | 2 | break; |
432 | 5 | case kSPV_AMD_gpu_shader_int16: |
433 | | // This is not yet in the extension, but it's recommended for it. |
434 | | // See https://github.com/KhronosGroup/glslang/issues/848 |
435 | 5 | features_.uconvert_spec_constant_op = true; |
436 | 5 | break; |
437 | 2 | case kSPV_AMD_shader_ballot: |
438 | | // The grammar doesn't encode the fact that SPV_AMD_shader_ballot |
439 | | // enables the use of group operations Reduce, InclusiveScan, |
440 | | // and ExclusiveScan. Enable it manually. |
441 | | // https://github.com/KhronosGroup/SPIRV-Tools/issues/991 |
442 | 2 | features_.group_ops_reduce_and_scans = true; |
443 | 2 | break; |
444 | 588 | default: |
445 | 588 | break; |
446 | 597 | } |
447 | 597 | } |
448 | | |
449 | | bool ValidationState_t::HasAnyOfCapabilities( |
450 | 3.58M | const CapabilitySet& capabilities) const { |
451 | 3.58M | return module_capabilities_.HasAnyOf(capabilities); |
452 | 3.58M | } |
453 | | |
454 | | bool ValidationState_t::HasAnyOfExtensions( |
455 | 2.29k | const ExtensionSet& extensions) const { |
456 | 2.29k | return module_extensions_.HasAnyOf(extensions); |
457 | 2.29k | } |
458 | | |
459 | 24.2k | void ValidationState_t::set_addressing_model(spv::AddressingModel am) { |
460 | 24.2k | addressing_model_ = am; |
461 | 24.2k | switch (am) { |
462 | 80 | case spv::AddressingModel::Physical32: |
463 | 80 | pointer_size_and_alignment_ = 4; |
464 | 80 | break; |
465 | 24.0k | default: |
466 | | // fall through |
467 | 24.1k | case spv::AddressingModel::Physical64: |
468 | 24.1k | case spv::AddressingModel::PhysicalStorageBuffer64: |
469 | 24.1k | pointer_size_and_alignment_ = 8; |
470 | 24.1k | break; |
471 | 24.2k | } |
472 | 24.2k | } |
473 | | |
474 | 524k | spv::AddressingModel ValidationState_t::addressing_model() const { |
475 | 524k | return addressing_model_; |
476 | 524k | } |
477 | | |
478 | 24.2k | void ValidationState_t::set_memory_model(spv::MemoryModel mm) { |
479 | 24.2k | memory_model_ = mm; |
480 | 24.2k | } |
481 | | |
482 | 33.3k | spv::MemoryModel ValidationState_t::memory_model() const { |
483 | 33.3k | return memory_model_; |
484 | 33.3k | } |
485 | | |
486 | | void ValidationState_t::set_samplerimage_variable_address_mode( |
487 | 0 | uint32_t bit_width) { |
488 | 0 | sampler_image_addressing_mode_ = bit_width; |
489 | 0 | } |
490 | | |
491 | 0 | uint32_t ValidationState_t::samplerimage_variable_address_mode() const { |
492 | 0 | return sampler_image_addressing_mode_; |
493 | 0 | } |
494 | | |
495 | | spv_result_t ValidationState_t::RegisterFunction( |
496 | | uint32_t id, uint32_t ret_type_id, |
497 | 28.3k | spv::FunctionControlMask function_control, uint32_t function_type_id) { |
498 | 28.3k | assert(in_function_body() == false && |
499 | 28.3k | "RegisterFunction can only be called when parsing the binary outside " |
500 | 28.3k | "of another function"); |
501 | 0 | in_function_ = true; |
502 | 28.3k | module_functions_.emplace_back(id, ret_type_id, function_control, |
503 | 28.3k | function_type_id); |
504 | 28.3k | id_to_function_.emplace(id, ¤t_function()); |
505 | | |
506 | | // TODO(umar): validate function type and type_id |
507 | | |
508 | 28.3k | return SPV_SUCCESS; |
509 | 28.3k | } |
510 | | |
511 | 26.5k | spv_result_t ValidationState_t::RegisterFunctionEnd() { |
512 | 26.5k | assert(in_function_body() == true && |
513 | 26.5k | "RegisterFunctionEnd can only be called when parsing the binary " |
514 | 26.5k | "inside of another function"); |
515 | 0 | assert(in_block() == false && |
516 | 26.5k | "RegisterFunctionParameter can only be called when parsing the binary " |
517 | 26.5k | "outside of a block"); |
518 | 0 | current_function().RegisterFunctionEnd(); |
519 | 26.5k | in_function_ = false; |
520 | 26.5k | return SPV_SUCCESS; |
521 | 26.5k | } |
522 | | |
523 | | Instruction* ValidationState_t::AddOrderedInstruction( |
524 | 3.27M | const spv_parsed_instruction_t* inst) { |
525 | 3.27M | ordered_instructions_.emplace_back(inst); |
526 | 3.27M | ordered_instructions_.back().SetLineNum(ordered_instructions_.size()); |
527 | 3.27M | return &ordered_instructions_.back(); |
528 | 3.27M | } |
529 | | |
530 | | // Improves diagnostic messages by collecting names of IDs |
531 | 3.27M | void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) { |
532 | 3.27M | switch (inst->opcode()) { |
533 | 56.5k | case spv::Op::OpName: { |
534 | 56.5k | const auto target = inst->GetOperandAs<uint32_t>(0); |
535 | 56.5k | const std::string str = inst->GetOperandAs<std::string>(1); |
536 | 56.5k | AssignNameToId(target, str); |
537 | 56.5k | break; |
538 | 0 | } |
539 | 6.39k | case spv::Op::OpMemberName: { |
540 | 6.39k | const auto target = inst->GetOperandAs<uint32_t>(0); |
541 | 6.39k | const std::string str = inst->GetOperandAs<std::string>(2); |
542 | 6.39k | AssignNameToId(target, str); |
543 | 6.39k | break; |
544 | 0 | } |
545 | 383 | case spv::Op::OpSourceContinued: |
546 | 9.34k | case spv::Op::OpSource: |
547 | 9.90k | case spv::Op::OpSourceExtension: |
548 | 10.1k | case spv::Op::OpString: |
549 | 10.8k | case spv::Op::OpLine: |
550 | 30.4k | case spv::Op::OpNoLine: |
551 | 3.21M | default: |
552 | 3.21M | break; |
553 | 3.27M | } |
554 | 3.27M | } |
555 | | |
556 | 3.11M | void ValidationState_t::RegisterInstruction(Instruction* inst) { |
557 | 3.11M | if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst)); |
558 | | |
559 | | // Some validation checks are easier by getting all the consumers |
560 | 10.8M | for (size_t i = 0; i < inst->operands().size(); ++i) { |
561 | 7.76M | const spv_parsed_operand_t& operand = inst->operand(i); |
562 | 7.76M | if ((SPV_OPERAND_TYPE_ID == operand.type) || |
563 | 7.76M | (SPV_OPERAND_TYPE_TYPE_ID == operand.type)) { |
564 | 4.80M | const uint32_t operand_word = inst->word(operand.offset); |
565 | 4.80M | Instruction* operand_inst = FindDef(operand_word); |
566 | 4.80M | if (!operand_inst) { |
567 | 890k | continue; |
568 | 890k | } |
569 | | |
570 | | // If the instruction is using an OpTypeSampledImage as an operand, it |
571 | | // should be recorded. The validator will ensure that all usages of an |
572 | | // OpTypeSampledImage and its definition are in the same basic block. |
573 | 3.91M | if ((SPV_OPERAND_TYPE_ID == operand.type) && |
574 | 3.91M | (spv::Op::OpSampledImage == operand_inst->opcode())) { |
575 | 211 | RegisterSampledImageConsumer(operand_word, inst); |
576 | 211 | } |
577 | | |
578 | | // In order to track storage classes (not Function) used per execution |
579 | | // model we can't use RegisterExecutionModelLimitation on instructions |
580 | | // like OpTypePointer which are going to be in the pre-function section. |
581 | | // Instead just need to register storage class usage for consumers in a |
582 | | // function block. |
583 | 3.91M | if (inst->function()) { |
584 | 2.97M | if (operand_inst->opcode() == spv::Op::OpTypePointer) { |
585 | 226k | RegisterStorageClassConsumer( |
586 | 226k | operand_inst->GetOperandAs<spv::StorageClass>(1), inst); |
587 | 2.75M | } else if (operand_inst->opcode() == spv::Op::OpVariable) { |
588 | 418k | RegisterStorageClassConsumer( |
589 | 418k | operand_inst->GetOperandAs<spv::StorageClass>(2), inst); |
590 | 418k | } |
591 | 2.97M | } |
592 | 3.91M | } |
593 | 7.76M | } |
594 | 3.11M | } |
595 | | |
596 | | std::vector<Instruction*> ValidationState_t::getSampledImageConsumers( |
597 | 44 | uint32_t sampled_image_id) const { |
598 | 44 | std::vector<Instruction*> result; |
599 | 44 | auto iter = sampled_image_consumers_.find(sampled_image_id); |
600 | 44 | if (iter != sampled_image_consumers_.end()) { |
601 | 30 | result = iter->second; |
602 | 30 | } |
603 | 44 | return result; |
604 | 44 | } |
605 | | |
606 | | void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id, |
607 | 211 | Instruction* consumer) { |
608 | 211 | sampled_image_consumers_[sampled_image_id].push_back(consumer); |
609 | 211 | } |
610 | | |
611 | | void ValidationState_t::RegisterStorageClassConsumer( |
612 | 644k | spv::StorageClass storage_class, Instruction* consumer) { |
613 | 644k | if (spvIsVulkanEnv(context()->target_env)) { |
614 | 0 | if (storage_class == spv::StorageClass::Output) { |
615 | 0 | std::string errorVUID = VkErrorID(4644); |
616 | 0 | function(consumer->function()->id()) |
617 | 0 | ->RegisterExecutionModelLimitation([errorVUID]( |
618 | 0 | spv::ExecutionModel model, |
619 | 0 | std::string* message) { |
620 | 0 | if (model == spv::ExecutionModel::GLCompute || |
621 | 0 | model == spv::ExecutionModel::RayGenerationKHR || |
622 | 0 | model == spv::ExecutionModel::IntersectionKHR || |
623 | 0 | model == spv::ExecutionModel::AnyHitKHR || |
624 | 0 | model == spv::ExecutionModel::ClosestHitKHR || |
625 | 0 | model == spv::ExecutionModel::MissKHR || |
626 | 0 | model == spv::ExecutionModel::CallableKHR) { |
627 | 0 | if (message) { |
628 | 0 | *message = |
629 | 0 | errorVUID + |
630 | 0 | "in Vulkan environment, Output Storage Class must not be " |
631 | 0 | "used in GLCompute, RayGenerationKHR, IntersectionKHR, " |
632 | 0 | "AnyHitKHR, ClosestHitKHR, MissKHR, or CallableKHR " |
633 | 0 | "execution models"; |
634 | 0 | } |
635 | 0 | return false; |
636 | 0 | } |
637 | 0 | return true; |
638 | 0 | }); |
639 | 0 | } |
640 | |
|
641 | 0 | if (storage_class == spv::StorageClass::Workgroup) { |
642 | 0 | std::string errorVUID = VkErrorID(4645); |
643 | 0 | function(consumer->function()->id()) |
644 | 0 | ->RegisterExecutionModelLimitation([errorVUID]( |
645 | 0 | spv::ExecutionModel model, |
646 | 0 | std::string* message) { |
647 | 0 | if (model != spv::ExecutionModel::GLCompute && |
648 | 0 | model != spv::ExecutionModel::TaskNV && |
649 | 0 | model != spv::ExecutionModel::MeshNV && |
650 | 0 | model != spv::ExecutionModel::TaskEXT && |
651 | 0 | model != spv::ExecutionModel::MeshEXT) { |
652 | 0 | if (message) { |
653 | 0 | *message = |
654 | 0 | errorVUID + |
655 | 0 | "in Vulkan environment, Workgroup Storage Class is limited " |
656 | 0 | "to MeshNV, TaskNV, and GLCompute execution model"; |
657 | 0 | } |
658 | 0 | return false; |
659 | 0 | } |
660 | 0 | return true; |
661 | 0 | }); |
662 | 0 | } |
663 | 0 | } |
664 | | |
665 | 644k | if (storage_class == spv::StorageClass::CallableDataKHR) { |
666 | 0 | std::string errorVUID = VkErrorID(4704); |
667 | 0 | function(consumer->function()->id()) |
668 | 0 | ->RegisterExecutionModelLimitation([errorVUID]( |
669 | 0 | spv::ExecutionModel model, |
670 | 0 | std::string* message) { |
671 | 0 | if (model != spv::ExecutionModel::RayGenerationKHR && |
672 | 0 | model != spv::ExecutionModel::ClosestHitKHR && |
673 | 0 | model != spv::ExecutionModel::CallableKHR && |
674 | 0 | model != spv::ExecutionModel::MissKHR) { |
675 | 0 | if (message) { |
676 | 0 | *message = errorVUID + |
677 | 0 | "CallableDataKHR Storage Class is limited to " |
678 | 0 | "RayGenerationKHR, ClosestHitKHR, CallableKHR, and " |
679 | 0 | "MissKHR execution model"; |
680 | 0 | } |
681 | 0 | return false; |
682 | 0 | } |
683 | 0 | return true; |
684 | 0 | }); |
685 | 644k | } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) { |
686 | 0 | std::string errorVUID = VkErrorID(4705); |
687 | 0 | function(consumer->function()->id()) |
688 | 0 | ->RegisterExecutionModelLimitation([errorVUID]( |
689 | 0 | spv::ExecutionModel model, |
690 | 0 | std::string* message) { |
691 | 0 | if (model != spv::ExecutionModel::CallableKHR) { |
692 | 0 | if (message) { |
693 | 0 | *message = errorVUID + |
694 | 0 | "IncomingCallableDataKHR Storage Class is limited to " |
695 | 0 | "CallableKHR execution model"; |
696 | 0 | } |
697 | 0 | return false; |
698 | 0 | } |
699 | 0 | return true; |
700 | 0 | }); |
701 | 644k | } else if (storage_class == spv::StorageClass::RayPayloadKHR) { |
702 | 0 | std::string errorVUID = VkErrorID(4698); |
703 | 0 | function(consumer->function()->id()) |
704 | 0 | ->RegisterExecutionModelLimitation([errorVUID]( |
705 | 0 | spv::ExecutionModel model, |
706 | 0 | std::string* message) { |
707 | 0 | if (model != spv::ExecutionModel::RayGenerationKHR && |
708 | 0 | model != spv::ExecutionModel::ClosestHitKHR && |
709 | 0 | model != spv::ExecutionModel::MissKHR) { |
710 | 0 | if (message) { |
711 | 0 | *message = |
712 | 0 | errorVUID + |
713 | 0 | "RayPayloadKHR Storage Class is limited to RayGenerationKHR, " |
714 | 0 | "ClosestHitKHR, and MissKHR execution model"; |
715 | 0 | } |
716 | 0 | return false; |
717 | 0 | } |
718 | 0 | return true; |
719 | 0 | }); |
720 | 644k | } else if (storage_class == spv::StorageClass::HitAttributeKHR) { |
721 | 0 | std::string errorVUID = VkErrorID(4701); |
722 | 0 | function(consumer->function()->id()) |
723 | 0 | ->RegisterExecutionModelLimitation( |
724 | 0 | [errorVUID](spv::ExecutionModel model, std::string* message) { |
725 | 0 | if (model != spv::ExecutionModel::IntersectionKHR && |
726 | 0 | model != spv::ExecutionModel::AnyHitKHR && |
727 | 0 | model != spv::ExecutionModel::ClosestHitKHR) { |
728 | 0 | if (message) { |
729 | 0 | *message = errorVUID + |
730 | 0 | "HitAttributeKHR Storage Class is limited to " |
731 | 0 | "IntersectionKHR, AnyHitKHR, sand ClosestHitKHR " |
732 | 0 | "execution model"; |
733 | 0 | } |
734 | 0 | return false; |
735 | 0 | } |
736 | 0 | return true; |
737 | 0 | }); |
738 | 644k | } else if (storage_class == spv::StorageClass::IncomingRayPayloadKHR) { |
739 | 0 | std::string errorVUID = VkErrorID(4699); |
740 | 0 | function(consumer->function()->id()) |
741 | 0 | ->RegisterExecutionModelLimitation( |
742 | 0 | [errorVUID](spv::ExecutionModel model, std::string* message) { |
743 | 0 | if (model != spv::ExecutionModel::AnyHitKHR && |
744 | 0 | model != spv::ExecutionModel::ClosestHitKHR && |
745 | 0 | model != spv::ExecutionModel::MissKHR) { |
746 | 0 | if (message) { |
747 | 0 | *message = |
748 | 0 | errorVUID + |
749 | 0 | "IncomingRayPayloadKHR Storage Class is limited to " |
750 | 0 | "AnyHitKHR, ClosestHitKHR, and MissKHR execution model"; |
751 | 0 | } |
752 | 0 | return false; |
753 | 0 | } |
754 | 0 | return true; |
755 | 0 | }); |
756 | 644k | } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { |
757 | 0 | std::string errorVUID = VkErrorID(7119); |
758 | 0 | function(consumer->function()->id()) |
759 | 0 | ->RegisterExecutionModelLimitation( |
760 | 0 | [errorVUID](spv::ExecutionModel model, std::string* message) { |
761 | 0 | if (model != spv::ExecutionModel::RayGenerationKHR && |
762 | 0 | model != spv::ExecutionModel::IntersectionKHR && |
763 | 0 | model != spv::ExecutionModel::AnyHitKHR && |
764 | 0 | model != spv::ExecutionModel::ClosestHitKHR && |
765 | 0 | model != spv::ExecutionModel::CallableKHR && |
766 | 0 | model != spv::ExecutionModel::MissKHR) { |
767 | 0 | if (message) { |
768 | 0 | *message = |
769 | 0 | errorVUID + |
770 | 0 | "ShaderRecordBufferKHR Storage Class is limited to " |
771 | 0 | "RayGenerationKHR, IntersectionKHR, AnyHitKHR, " |
772 | 0 | "ClosestHitKHR, CallableKHR, and MissKHR execution model"; |
773 | 0 | } |
774 | 0 | return false; |
775 | 0 | } |
776 | 0 | return true; |
777 | 0 | }); |
778 | 644k | } else if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { |
779 | 0 | function(consumer->function()->id()) |
780 | 0 | ->RegisterExecutionModelLimitation( |
781 | 0 | [](spv::ExecutionModel model, std::string* message) { |
782 | 0 | if (model != spv::ExecutionModel::TaskEXT && |
783 | 0 | model != spv::ExecutionModel::MeshEXT) { |
784 | 0 | if (message) { |
785 | 0 | *message = |
786 | 0 | "TaskPayloadWorkgroupEXT Storage Class is limited to " |
787 | 0 | "TaskEXT and MeshKHR execution model"; |
788 | 0 | } |
789 | 0 | return false; |
790 | 0 | } |
791 | 0 | return true; |
792 | 0 | }); |
793 | 644k | } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) { |
794 | 0 | function(consumer->function()->id()) |
795 | 0 | ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, |
796 | 0 | std::string* message) { |
797 | 0 | if (model != spv::ExecutionModel::RayGenerationKHR && |
798 | 0 | model != spv::ExecutionModel::ClosestHitKHR && |
799 | 0 | model != spv::ExecutionModel::MissKHR) { |
800 | 0 | if (message) { |
801 | 0 | *message = |
802 | 0 | "HitObjectAttributeNV Storage Class is limited to " |
803 | 0 | "RayGenerationKHR, ClosestHitKHR or MissKHR execution model"; |
804 | 0 | } |
805 | 0 | return false; |
806 | 0 | } |
807 | 0 | return true; |
808 | 0 | }); |
809 | 0 | } |
810 | 644k | } |
811 | | |
812 | 3.11M | uint32_t ValidationState_t::getIdBound() const { return id_bound_; } |
813 | | |
814 | 30.5k | void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; } |
815 | | |
816 | 111k | bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction* inst) { |
817 | 111k | std::vector<uint32_t> key; |
818 | 111k | key.push_back(static_cast<uint32_t>(inst->opcode())); |
819 | 378k | for (size_t index = 0; index < inst->operands().size(); ++index) { |
820 | 266k | const spv_parsed_operand_t& operand = inst->operand(index); |
821 | | |
822 | 266k | if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue; |
823 | | |
824 | 154k | const int words_begin = operand.offset; |
825 | 154k | const int words_end = words_begin + operand.num_words; |
826 | 154k | assert(words_end <= static_cast<int>(inst->words().size())); |
827 | | |
828 | 0 | key.insert(key.end(), inst->words().begin() + words_begin, |
829 | 154k | inst->words().begin() + words_end); |
830 | 154k | } |
831 | | |
832 | 111k | return unique_type_declarations_.insert(std::move(key)).second; |
833 | 111k | } |
834 | | |
835 | 757k | uint32_t ValidationState_t::GetTypeId(uint32_t id) const { |
836 | 757k | const Instruction* inst = FindDef(id); |
837 | 757k | return inst ? inst->type_id() : 0; |
838 | 757k | } |
839 | | |
840 | 147k | spv::Op ValidationState_t::GetIdOpcode(uint32_t id) const { |
841 | 147k | const Instruction* inst = FindDef(id); |
842 | 147k | return inst ? inst->opcode() : spv::Op::OpNop; |
843 | 147k | } |
844 | | |
845 | 435k | uint32_t ValidationState_t::GetComponentType(uint32_t id) const { |
846 | 435k | const Instruction* inst = FindDef(id); |
847 | 435k | assert(inst); |
848 | | |
849 | 0 | switch (inst->opcode()) { |
850 | 7.95k | case spv::Op::OpTypeFloat: |
851 | 383k | case spv::Op::OpTypeInt: |
852 | 383k | case spv::Op::OpTypeBool: |
853 | 383k | return id; |
854 | | |
855 | 52.4k | case spv::Op::OpTypeVector: |
856 | 52.4k | return inst->word(2); |
857 | | |
858 | 4 | case spv::Op::OpTypeMatrix: |
859 | 4 | return GetComponentType(inst->word(2)); |
860 | | |
861 | 0 | case spv::Op::OpTypeCooperativeMatrixNV: |
862 | 0 | return inst->word(2); |
863 | | |
864 | 0 | default: |
865 | 0 | break; |
866 | 435k | } |
867 | | |
868 | 0 | if (inst->type_id()) return GetComponentType(inst->type_id()); |
869 | | |
870 | 0 | assert(0); |
871 | 0 | return 0; |
872 | 0 | } |
873 | | |
874 | 577k | uint32_t ValidationState_t::GetDimension(uint32_t id) const { |
875 | 577k | const Instruction* inst = FindDef(id); |
876 | 577k | assert(inst); |
877 | | |
878 | 0 | switch (inst->opcode()) { |
879 | 32.9k | case spv::Op::OpTypeFloat: |
880 | 425k | case spv::Op::OpTypeInt: |
881 | 556k | case spv::Op::OpTypeBool: |
882 | 556k | return 1; |
883 | | |
884 | 20.7k | case spv::Op::OpTypeVector: |
885 | 20.7k | case spv::Op::OpTypeMatrix: |
886 | 20.7k | return inst->word(3); |
887 | | |
888 | 0 | case spv::Op::OpTypeCooperativeMatrixNV: |
889 | | // Actual dimension isn't known, return 0 |
890 | 0 | return 0; |
891 | | |
892 | 0 | default: |
893 | 0 | break; |
894 | 577k | } |
895 | | |
896 | 0 | if (inst->type_id()) return GetDimension(inst->type_id()); |
897 | | |
898 | 0 | assert(0); |
899 | 0 | return 0; |
900 | 0 | } |
901 | | |
902 | 385k | uint32_t ValidationState_t::GetBitWidth(uint32_t id) const { |
903 | 385k | const uint32_t component_type_id = GetComponentType(id); |
904 | 385k | const Instruction* inst = FindDef(component_type_id); |
905 | 385k | assert(inst); |
906 | | |
907 | 385k | if (inst->opcode() == spv::Op::OpTypeFloat || |
908 | 385k | inst->opcode() == spv::Op::OpTypeInt) |
909 | 385k | return inst->word(2); |
910 | | |
911 | 0 | if (inst->opcode() == spv::Op::OpTypeBool) return 1; |
912 | | |
913 | 0 | assert(0); |
914 | 0 | return 0; |
915 | 0 | } |
916 | | |
917 | 53.3k | bool ValidationState_t::IsVoidType(uint32_t id) const { |
918 | 53.3k | const Instruction* inst = FindDef(id); |
919 | 53.3k | return inst && inst->opcode() == spv::Op::OpTypeVoid; |
920 | 53.3k | } |
921 | | |
922 | 120k | bool ValidationState_t::IsFloatScalarType(uint32_t id) const { |
923 | 120k | const Instruction* inst = FindDef(id); |
924 | 120k | return inst && inst->opcode() == spv::Op::OpTypeFloat; |
925 | 120k | } |
926 | | |
927 | 17.2k | bool ValidationState_t::IsFloatVectorType(uint32_t id) const { |
928 | 17.2k | const Instruction* inst = FindDef(id); |
929 | 17.2k | if (!inst) { |
930 | 5 | return false; |
931 | 5 | } |
932 | | |
933 | 17.2k | if (inst->opcode() == spv::Op::OpTypeVector) { |
934 | 17.1k | return IsFloatScalarType(GetComponentType(id)); |
935 | 17.1k | } |
936 | | |
937 | 120 | return false; |
938 | 17.2k | } |
939 | | |
940 | 25.9k | bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const { |
941 | 25.9k | const Instruction* inst = FindDef(id); |
942 | 25.9k | if (!inst) { |
943 | 4 | return false; |
944 | 4 | } |
945 | | |
946 | 25.9k | if (inst->opcode() == spv::Op::OpTypeFloat) { |
947 | 17.8k | return true; |
948 | 17.8k | } |
949 | | |
950 | 8.10k | if (inst->opcode() == spv::Op::OpTypeVector) { |
951 | 8.05k | return IsFloatScalarType(GetComponentType(id)); |
952 | 8.05k | } |
953 | | |
954 | 45 | return false; |
955 | 8.10k | } |
956 | | |
957 | 411k | bool ValidationState_t::IsIntScalarType(uint32_t id) const { |
958 | 411k | const Instruction* inst = FindDef(id); |
959 | 411k | return inst && inst->opcode() == spv::Op::OpTypeInt; |
960 | 411k | } |
961 | | |
962 | 2.88k | bool ValidationState_t::IsIntVectorType(uint32_t id) const { |
963 | 2.88k | const Instruction* inst = FindDef(id); |
964 | 2.88k | if (!inst) { |
965 | 0 | return false; |
966 | 0 | } |
967 | | |
968 | 2.88k | if (inst->opcode() == spv::Op::OpTypeVector) { |
969 | 2.47k | return IsIntScalarType(GetComponentType(id)); |
970 | 2.47k | } |
971 | | |
972 | 414 | return false; |
973 | 2.88k | } |
974 | | |
975 | 7.33k | bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const { |
976 | 7.33k | const Instruction* inst = FindDef(id); |
977 | 7.33k | if (!inst) { |
978 | 7 | return false; |
979 | 7 | } |
980 | | |
981 | 7.32k | if (inst->opcode() == spv::Op::OpTypeInt) { |
982 | 7.14k | return true; |
983 | 7.14k | } |
984 | | |
985 | 175 | if (inst->opcode() == spv::Op::OpTypeVector) { |
986 | 134 | return IsIntScalarType(GetComponentType(id)); |
987 | 134 | } |
988 | | |
989 | 41 | return false; |
990 | 175 | } |
991 | | |
992 | 339 | bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const { |
993 | 339 | const Instruction* inst = FindDef(id); |
994 | 339 | return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 0; |
995 | 339 | } |
996 | | |
997 | 128 | bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { |
998 | 128 | const Instruction* inst = FindDef(id); |
999 | 128 | if (!inst) { |
1000 | 0 | return false; |
1001 | 0 | } |
1002 | | |
1003 | 128 | if (inst->opcode() == spv::Op::OpTypeVector) { |
1004 | 98 | return IsUnsignedIntScalarType(GetComponentType(id)); |
1005 | 98 | } |
1006 | | |
1007 | 30 | return false; |
1008 | 128 | } |
1009 | | |
1010 | 0 | bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const { |
1011 | 0 | const Instruction* inst = FindDef(id); |
1012 | 0 | return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 1; |
1013 | 0 | } |
1014 | | |
1015 | 0 | bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { |
1016 | 0 | const Instruction* inst = FindDef(id); |
1017 | 0 | if (!inst) { |
1018 | 0 | return false; |
1019 | 0 | } |
1020 | | |
1021 | 0 | if (inst->opcode() == spv::Op::OpTypeVector) { |
1022 | 0 | return IsSignedIntScalarType(GetComponentType(id)); |
1023 | 0 | } |
1024 | | |
1025 | 0 | return false; |
1026 | 0 | } |
1027 | | |
1028 | 152k | bool ValidationState_t::IsBoolScalarType(uint32_t id) const { |
1029 | 152k | const Instruction* inst = FindDef(id); |
1030 | 152k | return inst && inst->opcode() == spv::Op::OpTypeBool; |
1031 | 152k | } |
1032 | | |
1033 | 139 | bool ValidationState_t::IsBoolVectorType(uint32_t id) const { |
1034 | 139 | const Instruction* inst = FindDef(id); |
1035 | 139 | if (!inst) { |
1036 | 0 | return false; |
1037 | 0 | } |
1038 | | |
1039 | 139 | if (inst->opcode() == spv::Op::OpTypeVector) { |
1040 | 76 | return IsBoolScalarType(GetComponentType(id)); |
1041 | 76 | } |
1042 | | |
1043 | 63 | return false; |
1044 | 139 | } |
1045 | | |
1046 | 0 | bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const { |
1047 | 0 | const Instruction* inst = FindDef(id); |
1048 | 0 | if (!inst) { |
1049 | 0 | return false; |
1050 | 0 | } |
1051 | | |
1052 | 0 | if (inst->opcode() == spv::Op::OpTypeBool) { |
1053 | 0 | return true; |
1054 | 0 | } |
1055 | | |
1056 | 0 | if (inst->opcode() == spv::Op::OpTypeVector) { |
1057 | 0 | return IsBoolScalarType(GetComponentType(id)); |
1058 | 0 | } |
1059 | | |
1060 | 0 | return false; |
1061 | 0 | } |
1062 | | |
1063 | 11 | bool ValidationState_t::IsFloatMatrixType(uint32_t id) const { |
1064 | 11 | const Instruction* inst = FindDef(id); |
1065 | 11 | if (!inst) { |
1066 | 0 | return false; |
1067 | 0 | } |
1068 | | |
1069 | 11 | if (inst->opcode() == spv::Op::OpTypeMatrix) { |
1070 | 2 | return IsFloatScalarType(GetComponentType(id)); |
1071 | 2 | } |
1072 | | |
1073 | 9 | return false; |
1074 | 11 | } |
1075 | | |
1076 | | bool ValidationState_t::GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, |
1077 | | uint32_t* num_cols, |
1078 | | uint32_t* column_type, |
1079 | 2.00k | uint32_t* component_type) const { |
1080 | 2.00k | if (!id) return false; |
1081 | | |
1082 | 2.00k | const Instruction* mat_inst = FindDef(id); |
1083 | 2.00k | assert(mat_inst); |
1084 | 2.00k | if (mat_inst->opcode() != spv::Op::OpTypeMatrix) return false; |
1085 | | |
1086 | 1.96k | const uint32_t vec_type = mat_inst->word(2); |
1087 | 1.96k | const Instruction* vec_inst = FindDef(vec_type); |
1088 | 1.96k | assert(vec_inst); |
1089 | | |
1090 | 1.96k | if (vec_inst->opcode() != spv::Op::OpTypeVector) { |
1091 | 0 | assert(0); |
1092 | 0 | return false; |
1093 | 0 | } |
1094 | | |
1095 | 1.96k | *num_cols = mat_inst->word(3); |
1096 | 1.96k | *num_rows = vec_inst->word(3); |
1097 | 1.96k | *column_type = mat_inst->word(2); |
1098 | 1.96k | *component_type = vec_inst->word(2); |
1099 | | |
1100 | 1.96k | return true; |
1101 | 1.96k | } |
1102 | | |
1103 | | bool ValidationState_t::GetStructMemberTypes( |
1104 | 132 | uint32_t struct_type_id, std::vector<uint32_t>* member_types) const { |
1105 | 132 | member_types->clear(); |
1106 | 132 | if (!struct_type_id) return false; |
1107 | | |
1108 | 132 | const Instruction* inst = FindDef(struct_type_id); |
1109 | 132 | assert(inst); |
1110 | 132 | if (inst->opcode() != spv::Op::OpTypeStruct) return false; |
1111 | | |
1112 | 101 | *member_types = |
1113 | 101 | std::vector<uint32_t>(inst->words().cbegin() + 2, inst->words().cend()); |
1114 | | |
1115 | 101 | if (member_types->empty()) return false; |
1116 | | |
1117 | 100 | return true; |
1118 | 101 | } |
1119 | | |
1120 | 220k | bool ValidationState_t::IsPointerType(uint32_t id) const { |
1121 | 220k | const Instruction* inst = FindDef(id); |
1122 | 220k | return inst && inst->opcode() == spv::Op::OpTypePointer; |
1123 | 220k | } |
1124 | | |
1125 | | bool ValidationState_t::GetPointerTypeInfo( |
1126 | 362k | uint32_t id, uint32_t* data_type, spv::StorageClass* storage_class) const { |
1127 | 362k | *storage_class = spv::StorageClass::Max; |
1128 | 362k | if (!id) return false; |
1129 | | |
1130 | 362k | const Instruction* inst = FindDef(id); |
1131 | 362k | assert(inst); |
1132 | 362k | if (inst->opcode() != spv::Op::OpTypePointer) return false; |
1133 | | |
1134 | 362k | *storage_class = spv::StorageClass(inst->word(2)); |
1135 | 362k | *data_type = inst->word(3); |
1136 | 362k | return true; |
1137 | 362k | } |
1138 | | |
1139 | 0 | bool ValidationState_t::IsAccelerationStructureType(uint32_t id) const { |
1140 | 0 | const Instruction* inst = FindDef(id); |
1141 | 0 | return inst && inst->opcode() == spv::Op::OpTypeAccelerationStructureKHR; |
1142 | 0 | } |
1143 | | |
1144 | 38.3k | bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const { |
1145 | 38.3k | const Instruction* inst = FindDef(id); |
1146 | 38.3k | return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV; |
1147 | 38.3k | } |
1148 | | |
1149 | 28 | bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const { |
1150 | 28 | if (!IsCooperativeMatrixType(id)) return false; |
1151 | 0 | return IsFloatScalarType(FindDef(id)->word(2)); |
1152 | 28 | } |
1153 | | |
1154 | 55 | bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const { |
1155 | 55 | if (!IsCooperativeMatrixType(id)) return false; |
1156 | 0 | return IsIntScalarType(FindDef(id)->word(2)); |
1157 | 55 | } |
1158 | | |
1159 | 31 | bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const { |
1160 | 31 | if (!IsCooperativeMatrixType(id)) return false; |
1161 | 0 | return IsUnsignedIntScalarType(FindDef(id)->word(2)); |
1162 | 31 | } |
1163 | | |
1164 | | // Either a 32 bit 2-component uint vector or a 64 bit uint scalar |
1165 | 0 | bool ValidationState_t::IsUnsigned64BitHandle(uint32_t id) const { |
1166 | 0 | return ((IsUnsignedIntScalarType(id) && GetBitWidth(id) == 64) || |
1167 | 0 | (IsUnsignedIntVectorType(id) && GetDimension(id) == 2 && |
1168 | 0 | GetBitWidth(id) == 32)); |
1169 | 0 | } |
1170 | | |
1171 | | spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( |
1172 | 0 | const Instruction* inst, uint32_t m1, uint32_t m2) { |
1173 | 0 | const auto m1_type = FindDef(m1); |
1174 | 0 | const auto m2_type = FindDef(m2); |
1175 | |
|
1176 | 0 | if (m1_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV || |
1177 | 0 | m2_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { |
1178 | 0 | return diag(SPV_ERROR_INVALID_DATA, inst) |
1179 | 0 | << "Expected cooperative matrix types"; |
1180 | 0 | } |
1181 | | |
1182 | 0 | uint32_t m1_scope_id = m1_type->GetOperandAs<uint32_t>(2); |
1183 | 0 | uint32_t m1_rows_id = m1_type->GetOperandAs<uint32_t>(3); |
1184 | 0 | uint32_t m1_cols_id = m1_type->GetOperandAs<uint32_t>(4); |
1185 | |
|
1186 | 0 | uint32_t m2_scope_id = m2_type->GetOperandAs<uint32_t>(2); |
1187 | 0 | uint32_t m2_rows_id = m2_type->GetOperandAs<uint32_t>(3); |
1188 | 0 | uint32_t m2_cols_id = m2_type->GetOperandAs<uint32_t>(4); |
1189 | |
|
1190 | 0 | bool m1_is_int32 = false, m1_is_const_int32 = false, m2_is_int32 = false, |
1191 | 0 | m2_is_const_int32 = false; |
1192 | 0 | uint32_t m1_value = 0, m2_value = 0; |
1193 | |
|
1194 | 0 | std::tie(m1_is_int32, m1_is_const_int32, m1_value) = |
1195 | 0 | EvalInt32IfConst(m1_scope_id); |
1196 | 0 | std::tie(m2_is_int32, m2_is_const_int32, m2_value) = |
1197 | 0 | EvalInt32IfConst(m2_scope_id); |
1198 | |
|
1199 | 0 | if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { |
1200 | 0 | return diag(SPV_ERROR_INVALID_DATA, inst) |
1201 | 0 | << "Expected scopes of Matrix and Result Type to be " |
1202 | 0 | << "identical"; |
1203 | 0 | } |
1204 | | |
1205 | 0 | std::tie(m1_is_int32, m1_is_const_int32, m1_value) = |
1206 | 0 | EvalInt32IfConst(m1_rows_id); |
1207 | 0 | std::tie(m2_is_int32, m2_is_const_int32, m2_value) = |
1208 | 0 | EvalInt32IfConst(m2_rows_id); |
1209 | |
|
1210 | 0 | if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { |
1211 | 0 | return diag(SPV_ERROR_INVALID_DATA, inst) |
1212 | 0 | << "Expected rows of Matrix type and Result Type to be " |
1213 | 0 | << "identical"; |
1214 | 0 | } |
1215 | | |
1216 | 0 | std::tie(m1_is_int32, m1_is_const_int32, m1_value) = |
1217 | 0 | EvalInt32IfConst(m1_cols_id); |
1218 | 0 | std::tie(m2_is_int32, m2_is_const_int32, m2_value) = |
1219 | 0 | EvalInt32IfConst(m2_cols_id); |
1220 | |
|
1221 | 0 | if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { |
1222 | 0 | return diag(SPV_ERROR_INVALID_DATA, inst) |
1223 | 0 | << "Expected columns of Matrix type and Result Type to be " |
1224 | 0 | << "identical"; |
1225 | 0 | } |
1226 | | |
1227 | 0 | return SPV_SUCCESS; |
1228 | 0 | } |
1229 | | |
1230 | | uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst, |
1231 | 620k | size_t operand_index) const { |
1232 | 620k | return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index)); |
1233 | 620k | } |
1234 | | |
1235 | 96 | bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const { |
1236 | 96 | const Instruction* inst = FindDef(id); |
1237 | 96 | if (!inst) { |
1238 | 0 | assert(0 && "Instruction not found"); |
1239 | 0 | return false; |
1240 | 0 | } |
1241 | | |
1242 | 96 | if (inst->opcode() != spv::Op::OpConstant && |
1243 | 96 | inst->opcode() != spv::Op::OpSpecConstant) |
1244 | 0 | return false; |
1245 | | |
1246 | 96 | if (!IsIntScalarType(inst->type_id())) return false; |
1247 | | |
1248 | 96 | if (inst->words().size() == 4) { |
1249 | 96 | *val = inst->word(3); |
1250 | 96 | } else { |
1251 | 0 | assert(inst->words().size() == 5); |
1252 | 0 | *val = inst->word(3); |
1253 | 0 | *val |= uint64_t(inst->word(4)) << 32; |
1254 | 0 | } |
1255 | 0 | return true; |
1256 | 96 | } |
1257 | | |
1258 | | std::tuple<bool, bool, uint32_t> ValidationState_t::EvalInt32IfConst( |
1259 | 5.41k | uint32_t id) const { |
1260 | 5.41k | const Instruction* const inst = FindDef(id); |
1261 | 5.41k | assert(inst); |
1262 | 0 | const uint32_t type = inst->type_id(); |
1263 | | |
1264 | 5.41k | if (type == 0 || !IsIntScalarType(type) || GetBitWidth(type) != 32) { |
1265 | 17 | return std::make_tuple(false, false, 0); |
1266 | 17 | } |
1267 | | |
1268 | | // Spec constant values cannot be evaluated so don't consider constant for |
1269 | | // the purpose of this method. |
1270 | 5.40k | if (!spvOpcodeIsConstant(inst->opcode()) || |
1271 | 5.40k | spvOpcodeIsSpecConstant(inst->opcode())) { |
1272 | 115 | return std::make_tuple(true, false, 0); |
1273 | 115 | } |
1274 | | |
1275 | 5.28k | if (inst->opcode() == spv::Op::OpConstantNull) { |
1276 | 13 | return std::make_tuple(true, true, 0); |
1277 | 13 | } |
1278 | | |
1279 | 5.27k | assert(inst->words().size() == 4); |
1280 | 0 | return std::make_tuple(true, true, inst->word(3)); |
1281 | 5.28k | } |
1282 | | |
1283 | 15.8k | void ValidationState_t::ComputeFunctionToEntryPointMapping() { |
1284 | 15.8k | for (const uint32_t entry_point : entry_points()) { |
1285 | 12.2k | std::stack<uint32_t> call_stack; |
1286 | 12.2k | std::set<uint32_t> visited; |
1287 | 12.2k | call_stack.push(entry_point); |
1288 | 31.7k | while (!call_stack.empty()) { |
1289 | 19.5k | const uint32_t called_func_id = call_stack.top(); |
1290 | 19.5k | call_stack.pop(); |
1291 | 19.5k | if (!visited.insert(called_func_id).second) continue; |
1292 | | |
1293 | 18.2k | function_to_entry_points_[called_func_id].push_back(entry_point); |
1294 | | |
1295 | 18.2k | const Function* called_func = function(called_func_id); |
1296 | 18.2k | if (called_func) { |
1297 | | // Other checks should error out on this invalid SPIR-V. |
1298 | 18.2k | for (const uint32_t new_call : called_func->function_call_targets()) { |
1299 | 7.30k | call_stack.push(new_call); |
1300 | 7.30k | } |
1301 | 18.2k | } |
1302 | 18.2k | } |
1303 | 12.2k | } |
1304 | 15.8k | } |
1305 | | |
1306 | 15.8k | void ValidationState_t::ComputeRecursiveEntryPoints() { |
1307 | 20.2k | for (const Function& func : functions()) { |
1308 | 20.2k | std::stack<uint32_t> call_stack; |
1309 | 20.2k | std::set<uint32_t> visited; |
1310 | | |
1311 | 20.2k | for (const uint32_t new_call : func.function_call_targets()) { |
1312 | 7.46k | call_stack.push(new_call); |
1313 | 7.46k | } |
1314 | | |
1315 | 30.8k | while (!call_stack.empty()) { |
1316 | 10.7k | const uint32_t called_func_id = call_stack.top(); |
1317 | 10.7k | call_stack.pop(); |
1318 | | |
1319 | 10.7k | if (!visited.insert(called_func_id).second) continue; |
1320 | | |
1321 | 9.43k | if (called_func_id == func.id()) { |
1322 | 88 | for (const uint32_t entry_point : |
1323 | 88 | function_to_entry_points_[called_func_id]) |
1324 | 81 | recursive_entry_points_.insert(entry_point); |
1325 | 88 | break; |
1326 | 88 | } |
1327 | | |
1328 | 9.34k | const Function* called_func = function(called_func_id); |
1329 | 9.34k | if (called_func) { |
1330 | | // Other checks should error out on this invalid SPIR-V. |
1331 | 9.34k | for (const uint32_t new_call : called_func->function_call_targets()) { |
1332 | 3.28k | call_stack.push(new_call); |
1333 | 3.28k | } |
1334 | 9.34k | } |
1335 | 9.34k | } |
1336 | 20.2k | } |
1337 | 15.8k | } |
1338 | | |
1339 | | const std::vector<uint32_t>& ValidationState_t::FunctionEntryPoints( |
1340 | 27.5k | uint32_t func) const { |
1341 | 27.5k | auto iter = function_to_entry_points_.find(func); |
1342 | 27.5k | if (iter == function_to_entry_points_.end()) { |
1343 | 1.84k | return empty_ids_; |
1344 | 25.6k | } else { |
1345 | 25.6k | return iter->second; |
1346 | 25.6k | } |
1347 | 27.5k | } |
1348 | | |
1349 | 13 | std::set<uint32_t> ValidationState_t::EntryPointReferences(uint32_t id) const { |
1350 | 13 | std::set<uint32_t> referenced_entry_points; |
1351 | 13 | const auto inst = FindDef(id); |
1352 | 13 | if (!inst) return referenced_entry_points; |
1353 | | |
1354 | 13 | std::vector<const Instruction*> stack; |
1355 | 13 | stack.push_back(inst); |
1356 | 74 | while (!stack.empty()) { |
1357 | 61 | const auto current_inst = stack.back(); |
1358 | 61 | stack.pop_back(); |
1359 | | |
1360 | 61 | if (const auto func = current_inst->function()) { |
1361 | | // Instruction lives in a function, we can stop searching. |
1362 | 0 | const auto function_entry_points = FunctionEntryPoints(func->id()); |
1363 | 0 | referenced_entry_points.insert(function_entry_points.begin(), |
1364 | 0 | function_entry_points.end()); |
1365 | 61 | } else { |
1366 | | // Instruction is in the global scope, keep searching its uses. |
1367 | 61 | for (auto pair : current_inst->uses()) { |
1368 | 48 | const auto next_inst = pair.first; |
1369 | 48 | stack.push_back(next_inst); |
1370 | 48 | } |
1371 | 61 | } |
1372 | 61 | } |
1373 | | |
1374 | 13 | return referenced_entry_points; |
1375 | 13 | } |
1376 | | |
1377 | 13.1k | std::string ValidationState_t::Disassemble(const Instruction& inst) const { |
1378 | 13.1k | const spv_parsed_instruction_t& c_inst(inst.c_inst()); |
1379 | 13.1k | return Disassemble(c_inst.words, c_inst.num_words); |
1380 | 13.1k | } |
1381 | | |
1382 | | std::string ValidationState_t::Disassemble(const uint32_t* words, |
1383 | 13.1k | uint16_t num_words) const { |
1384 | 13.1k | uint32_t disassembly_options = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | |
1385 | 13.1k | SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES; |
1386 | | |
1387 | 13.1k | return spvInstructionBinaryToText(context()->target_env, words, num_words, |
1388 | 13.1k | words_, num_words_, disassembly_options); |
1389 | 13.1k | } |
1390 | | |
1391 | | bool ValidationState_t::LogicallyMatch(const Instruction* lhs, |
1392 | | const Instruction* rhs, |
1393 | 0 | bool check_decorations) { |
1394 | 0 | if (lhs->opcode() != rhs->opcode()) { |
1395 | 0 | return false; |
1396 | 0 | } |
1397 | | |
1398 | 0 | if (check_decorations) { |
1399 | 0 | const auto& dec_a = id_decorations(lhs->id()); |
1400 | 0 | const auto& dec_b = id_decorations(rhs->id()); |
1401 | |
|
1402 | 0 | for (const auto& dec : dec_b) { |
1403 | 0 | if (std::find(dec_a.begin(), dec_a.end(), dec) == dec_a.end()) { |
1404 | 0 | return false; |
1405 | 0 | } |
1406 | 0 | } |
1407 | 0 | } |
1408 | | |
1409 | 0 | if (lhs->opcode() == spv::Op::OpTypeArray) { |
1410 | | // Size operands must match. |
1411 | 0 | if (lhs->GetOperandAs<uint32_t>(2u) != rhs->GetOperandAs<uint32_t>(2u)) { |
1412 | 0 | return false; |
1413 | 0 | } |
1414 | | |
1415 | | // Elements must match or logically match. |
1416 | 0 | const auto lhs_ele_id = lhs->GetOperandAs<uint32_t>(1u); |
1417 | 0 | const auto rhs_ele_id = rhs->GetOperandAs<uint32_t>(1u); |
1418 | 0 | if (lhs_ele_id == rhs_ele_id) { |
1419 | 0 | return true; |
1420 | 0 | } |
1421 | | |
1422 | 0 | const auto lhs_ele = FindDef(lhs_ele_id); |
1423 | 0 | const auto rhs_ele = FindDef(rhs_ele_id); |
1424 | 0 | if (!lhs_ele || !rhs_ele) { |
1425 | 0 | return false; |
1426 | 0 | } |
1427 | 0 | return LogicallyMatch(lhs_ele, rhs_ele, check_decorations); |
1428 | 0 | } else if (lhs->opcode() == spv::Op::OpTypeStruct) { |
1429 | | // Number of elements must match. |
1430 | 0 | if (lhs->operands().size() != rhs->operands().size()) { |
1431 | 0 | return false; |
1432 | 0 | } |
1433 | | |
1434 | 0 | for (size_t i = 1u; i < lhs->operands().size(); ++i) { |
1435 | 0 | const auto lhs_ele_id = lhs->GetOperandAs<uint32_t>(i); |
1436 | 0 | const auto rhs_ele_id = rhs->GetOperandAs<uint32_t>(i); |
1437 | | // Elements must match or logically match. |
1438 | 0 | if (lhs_ele_id == rhs_ele_id) { |
1439 | 0 | continue; |
1440 | 0 | } |
1441 | | |
1442 | 0 | const auto lhs_ele = FindDef(lhs_ele_id); |
1443 | 0 | const auto rhs_ele = FindDef(rhs_ele_id); |
1444 | 0 | if (!lhs_ele || !rhs_ele) { |
1445 | 0 | return false; |
1446 | 0 | } |
1447 | | |
1448 | 0 | if (!LogicallyMatch(lhs_ele, rhs_ele, check_decorations)) { |
1449 | 0 | return false; |
1450 | 0 | } |
1451 | 0 | } |
1452 | | |
1453 | | // All checks passed. |
1454 | 0 | return true; |
1455 | 0 | } |
1456 | | |
1457 | | // No other opcodes are acceptable at this point. Arrays and structs are |
1458 | | // caught above and if they're elements are not arrays or structs they are |
1459 | | // required to match exactly. |
1460 | 0 | return false; |
1461 | 0 | } |
1462 | | |
1463 | | const Instruction* ValidationState_t::TracePointer( |
1464 | 0 | const Instruction* inst) const { |
1465 | 0 | auto base_ptr = inst; |
1466 | 0 | while (base_ptr->opcode() == spv::Op::OpAccessChain || |
1467 | 0 | base_ptr->opcode() == spv::Op::OpInBoundsAccessChain || |
1468 | 0 | base_ptr->opcode() == spv::Op::OpPtrAccessChain || |
1469 | 0 | base_ptr->opcode() == spv::Op::OpInBoundsPtrAccessChain || |
1470 | 0 | base_ptr->opcode() == spv::Op::OpCopyObject) { |
1471 | 0 | base_ptr = FindDef(base_ptr->GetOperandAs<uint32_t>(2u)); |
1472 | 0 | } |
1473 | 0 | return base_ptr; |
1474 | 0 | } |
1475 | | |
1476 | | bool ValidationState_t::ContainsType( |
1477 | | uint32_t id, const std::function<bool(const Instruction*)>& f, |
1478 | 6.64M | bool traverse_all_types) const { |
1479 | 6.64M | const auto inst = FindDef(id); |
1480 | 6.64M | if (!inst) return false; |
1481 | | |
1482 | 6.15M | if (f(inst)) return true; |
1483 | | |
1484 | 6.15M | switch (inst->opcode()) { |
1485 | 75.6k | case spv::Op::OpTypeArray: |
1486 | 78.6k | case spv::Op::OpTypeRuntimeArray: |
1487 | 710k | case spv::Op::OpTypeVector: |
1488 | 760k | case spv::Op::OpTypeMatrix: |
1489 | 774k | case spv::Op::OpTypeImage: |
1490 | 786k | case spv::Op::OpTypeSampledImage: |
1491 | 786k | case spv::Op::OpTypeCooperativeMatrixNV: |
1492 | 786k | return ContainsType(inst->GetOperandAs<uint32_t>(1u), f, |
1493 | 786k | traverse_all_types); |
1494 | 549k | case spv::Op::OpTypePointer: |
1495 | 549k | if (IsForwardPointer(id)) return false; |
1496 | 549k | if (traverse_all_types) { |
1497 | 549k | return ContainsType(inst->GetOperandAs<uint32_t>(2u), f, |
1498 | 549k | traverse_all_types); |
1499 | 549k | } |
1500 | 2 | break; |
1501 | 2 | case spv::Op::OpTypeFunction: |
1502 | 167k | case spv::Op::OpTypeStruct: |
1503 | 167k | if (inst->opcode() == spv::Op::OpTypeFunction && !traverse_all_types) { |
1504 | 0 | return false; |
1505 | 0 | } |
1506 | 573k | for (uint32_t i = 1; i < inst->operands().size(); ++i) { |
1507 | 405k | if (ContainsType(inst->GetOperandAs<uint32_t>(i), f, |
1508 | 405k | traverse_all_types)) { |
1509 | 0 | return true; |
1510 | 0 | } |
1511 | 405k | } |
1512 | 167k | break; |
1513 | 4.65M | default: |
1514 | 4.65M | break; |
1515 | 6.15M | } |
1516 | | |
1517 | 4.82M | return false; |
1518 | 6.15M | } |
1519 | | |
1520 | | bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, |
1521 | 4.70M | uint32_t width) const { |
1522 | 4.70M | if (type != spv::Op::OpTypeInt && type != spv::Op::OpTypeFloat) return false; |
1523 | | |
1524 | 5.91M | const auto f = [type, width](const Instruction* inst) { |
1525 | 5.91M | if (inst->opcode() == type) { |
1526 | 2.16M | return inst->GetOperandAs<uint32_t>(1u) == width; |
1527 | 2.16M | } |
1528 | 3.75M | return false; |
1529 | 5.91M | }; |
1530 | 4.70M | return ContainsType(id, f); |
1531 | 4.70M | } |
1532 | | |
1533 | 1.44M | bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { |
1534 | 1.44M | if ((!HasCapability(spv::Capability::Int16) && |
1535 | 1.44M | ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 16)) || |
1536 | 1.44M | (!HasCapability(spv::Capability::Int8) && |
1537 | 1.44M | ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 8)) || |
1538 | 1.44M | (!HasCapability(spv::Capability::Float16) && |
1539 | 1.44M | ContainsSizedIntOrFloatType(id, spv::Op::OpTypeFloat, 16))) { |
1540 | 1 | return true; |
1541 | 1 | } |
1542 | 1.44M | return false; |
1543 | 1.44M | } |
1544 | | |
1545 | 199k | bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const { |
1546 | 239k | const auto f = [](const Instruction* inst) { |
1547 | 239k | return inst->opcode() == spv::Op::OpTypeRuntimeArray; |
1548 | 239k | }; |
1549 | 199k | return ContainsType(id, f, /* traverse_all_types = */ false); |
1550 | 199k | } |
1551 | | |
1552 | | bool ValidationState_t::IsValidStorageClass( |
1553 | 194k | spv::StorageClass storage_class) const { |
1554 | 194k | if (spvIsVulkanEnv(context()->target_env)) { |
1555 | 0 | switch (storage_class) { |
1556 | 0 | case spv::StorageClass::UniformConstant: |
1557 | 0 | case spv::StorageClass::Uniform: |
1558 | 0 | case spv::StorageClass::StorageBuffer: |
1559 | 0 | case spv::StorageClass::Input: |
1560 | 0 | case spv::StorageClass::Output: |
1561 | 0 | case spv::StorageClass::Image: |
1562 | 0 | case spv::StorageClass::Workgroup: |
1563 | 0 | case spv::StorageClass::Private: |
1564 | 0 | case spv::StorageClass::Function: |
1565 | 0 | case spv::StorageClass::PushConstant: |
1566 | 0 | case spv::StorageClass::PhysicalStorageBuffer: |
1567 | 0 | case spv::StorageClass::RayPayloadKHR: |
1568 | 0 | case spv::StorageClass::IncomingRayPayloadKHR: |
1569 | 0 | case spv::StorageClass::HitAttributeKHR: |
1570 | 0 | case spv::StorageClass::CallableDataKHR: |
1571 | 0 | case spv::StorageClass::IncomingCallableDataKHR: |
1572 | 0 | case spv::StorageClass::ShaderRecordBufferKHR: |
1573 | 0 | case spv::StorageClass::TaskPayloadWorkgroupEXT: |
1574 | 0 | case spv::StorageClass::HitObjectAttributeNV: |
1575 | 0 | return true; |
1576 | 0 | default: |
1577 | 0 | return false; |
1578 | 0 | } |
1579 | 0 | } |
1580 | | |
1581 | 194k | return true; |
1582 | 194k | } |
1583 | | |
1584 | 0 | #define VUID_WRAP(vuid) "[" #vuid "] " |
1585 | | |
1586 | | // Currently no 2 VUID share the same id, so no need for |reference| |
1587 | | std::string ValidationState_t::VkErrorID(uint32_t id, |
1588 | 103 | const char* /*reference*/) const { |
1589 | 103 | if (!spvIsVulkanEnv(context_->target_env)) { |
1590 | 103 | return ""; |
1591 | 103 | } |
1592 | | |
1593 | | // This large switch case is only searched when an error has occurred. |
1594 | | // If an id is changed, the old case must be modified or removed. Each string |
1595 | | // here is interpreted as being "implemented" |
1596 | | |
1597 | | // Clang format adds spaces between hyphens |
1598 | | // clang-format off |
1599 | 0 | switch (id) { |
1600 | 0 | case 4154: |
1601 | 0 | return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04154); |
1602 | 0 | case 4155: |
1603 | 0 | return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04155); |
1604 | 0 | case 4156: |
1605 | 0 | return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04156); |
1606 | 0 | case 4160: |
1607 | 0 | return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04160); |
1608 | 0 | case 4161: |
1609 | 0 | return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04161); |
1610 | 0 | case 4162: |
1611 | 0 | return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04162); |
1612 | 0 | case 4181: |
1613 | 0 | return VUID_WRAP(VUID-BaseInstance-BaseInstance-04181); |
1614 | 0 | case 4182: |
1615 | 0 | return VUID_WRAP(VUID-BaseInstance-BaseInstance-04182); |
1616 | 0 | case 4183: |
1617 | 0 | return VUID_WRAP(VUID-BaseInstance-BaseInstance-04183); |
1618 | 0 | case 4184: |
1619 | 0 | return VUID_WRAP(VUID-BaseVertex-BaseVertex-04184); |
1620 | 0 | case 4185: |
1621 | 0 | return VUID_WRAP(VUID-BaseVertex-BaseVertex-04185); |
1622 | 0 | case 4186: |
1623 | 0 | return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186); |
1624 | 0 | case 4187: |
1625 | 0 | return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187); |
1626 | 0 | case 4188: |
1627 | 0 | return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188); |
1628 | 0 | case 4189: |
1629 | 0 | return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189); |
1630 | 0 | case 4190: |
1631 | 0 | return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190); |
1632 | 0 | case 4191: |
1633 | 0 | return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191); |
1634 | 0 | case 4196: |
1635 | 0 | return VUID_WRAP(VUID-CullDistance-CullDistance-04196); |
1636 | 0 | case 4197: |
1637 | 0 | return VUID_WRAP(VUID-CullDistance-CullDistance-04197); |
1638 | 0 | case 4198: |
1639 | 0 | return VUID_WRAP(VUID-CullDistance-CullDistance-04198); |
1640 | 0 | case 4199: |
1641 | 0 | return VUID_WRAP(VUID-CullDistance-CullDistance-04199); |
1642 | 0 | case 4200: |
1643 | 0 | return VUID_WRAP(VUID-CullDistance-CullDistance-04200); |
1644 | 0 | case 6735: |
1645 | 0 | return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06735); // Execution Model |
1646 | 0 | case 6736: |
1647 | 0 | return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06736); // input storage |
1648 | 0 | case 6737: |
1649 | 0 | return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06737); // 32 int scalar |
1650 | 0 | case 4205: |
1651 | 0 | return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04205); |
1652 | 0 | case 4206: |
1653 | 0 | return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04206); |
1654 | 0 | case 4207: |
1655 | 0 | return VUID_WRAP(VUID-DrawIndex-DrawIndex-04207); |
1656 | 0 | case 4208: |
1657 | 0 | return VUID_WRAP(VUID-DrawIndex-DrawIndex-04208); |
1658 | 0 | case 4209: |
1659 | 0 | return VUID_WRAP(VUID-DrawIndex-DrawIndex-04209); |
1660 | 0 | case 4210: |
1661 | 0 | return VUID_WRAP(VUID-FragCoord-FragCoord-04210); |
1662 | 0 | case 4211: |
1663 | 0 | return VUID_WRAP(VUID-FragCoord-FragCoord-04211); |
1664 | 0 | case 4212: |
1665 | 0 | return VUID_WRAP(VUID-FragCoord-FragCoord-04212); |
1666 | 0 | case 4213: |
1667 | 0 | return VUID_WRAP(VUID-FragDepth-FragDepth-04213); |
1668 | 0 | case 4214: |
1669 | 0 | return VUID_WRAP(VUID-FragDepth-FragDepth-04214); |
1670 | 0 | case 4215: |
1671 | 0 | return VUID_WRAP(VUID-FragDepth-FragDepth-04215); |
1672 | 0 | case 4216: |
1673 | 0 | return VUID_WRAP(VUID-FragDepth-FragDepth-04216); |
1674 | 0 | case 4217: |
1675 | 0 | return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217); |
1676 | 0 | case 4218: |
1677 | 0 | return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218); |
1678 | 0 | case 4219: |
1679 | 0 | return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219); |
1680 | 0 | case 4220: |
1681 | 0 | return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220); |
1682 | 0 | case 4221: |
1683 | 0 | return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221); |
1684 | 0 | case 4222: |
1685 | 0 | return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222); |
1686 | 0 | case 4223: |
1687 | 0 | return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223); |
1688 | 0 | case 4224: |
1689 | 0 | return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224); |
1690 | 0 | case 4225: |
1691 | 0 | return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225); |
1692 | 0 | case 4229: |
1693 | 0 | return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229); |
1694 | 0 | case 4230: |
1695 | 0 | return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230); |
1696 | 0 | case 4231: |
1697 | 0 | return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231); |
1698 | 0 | case 4232: |
1699 | 0 | return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232); |
1700 | 0 | case 4233: |
1701 | 0 | return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233); |
1702 | 0 | case 4234: |
1703 | 0 | return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234); |
1704 | 0 | case 4236: |
1705 | 0 | return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236); |
1706 | 0 | case 4237: |
1707 | 0 | return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04237); |
1708 | 0 | case 4238: |
1709 | 0 | return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04238); |
1710 | 0 | case 4239: |
1711 | 0 | return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04239); |
1712 | 0 | case 4240: |
1713 | 0 | return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240); |
1714 | 0 | case 4241: |
1715 | 0 | return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241); |
1716 | 0 | case 4242: |
1717 | 0 | return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242); |
1718 | 0 | case 4243: |
1719 | 0 | return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243); |
1720 | 0 | case 4244: |
1721 | 0 | return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244); |
1722 | 0 | case 4245: |
1723 | 0 | return VUID_WRAP(VUID-HitTNV-HitTNV-04245); |
1724 | 0 | case 4246: |
1725 | 0 | return VUID_WRAP(VUID-HitTNV-HitTNV-04246); |
1726 | 0 | case 4247: |
1727 | 0 | return VUID_WRAP(VUID-HitTNV-HitTNV-04247); |
1728 | 0 | case 4248: |
1729 | 0 | return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248); |
1730 | 0 | case 4249: |
1731 | 0 | return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249); |
1732 | 0 | case 4250: |
1733 | 0 | return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250); |
1734 | 0 | case 4251: |
1735 | 0 | return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251); |
1736 | 0 | case 4252: |
1737 | 0 | return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252); |
1738 | 0 | case 4253: |
1739 | 0 | return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253); |
1740 | 0 | case 4254: |
1741 | 0 | return VUID_WRAP(VUID-InstanceId-InstanceId-04254); |
1742 | 0 | case 4255: |
1743 | 0 | return VUID_WRAP(VUID-InstanceId-InstanceId-04255); |
1744 | 0 | case 4256: |
1745 | 0 | return VUID_WRAP(VUID-InstanceId-InstanceId-04256); |
1746 | 0 | case 4257: |
1747 | 0 | return VUID_WRAP(VUID-InvocationId-InvocationId-04257); |
1748 | 0 | case 4258: |
1749 | 0 | return VUID_WRAP(VUID-InvocationId-InvocationId-04258); |
1750 | 0 | case 4259: |
1751 | 0 | return VUID_WRAP(VUID-InvocationId-InvocationId-04259); |
1752 | 0 | case 4263: |
1753 | 0 | return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04263); |
1754 | 0 | case 4264: |
1755 | 0 | return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264); |
1756 | 0 | case 4265: |
1757 | 0 | return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265); |
1758 | 0 | case 4266: |
1759 | 0 | return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266); |
1760 | 0 | case 4267: |
1761 | 0 | return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267); |
1762 | 0 | case 4268: |
1763 | 0 | return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268); |
1764 | 0 | case 4269: |
1765 | 0 | return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269); |
1766 | 0 | case 4270: |
1767 | 0 | return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270); |
1768 | 0 | case 4271: |
1769 | 0 | return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271); |
1770 | 0 | case 4272: |
1771 | 0 | return VUID_WRAP(VUID-Layer-Layer-04272); |
1772 | 0 | case 4273: |
1773 | 0 | return VUID_WRAP(VUID-Layer-Layer-04273); |
1774 | 0 | case 4274: |
1775 | 0 | return VUID_WRAP(VUID-Layer-Layer-04274); |
1776 | 0 | case 4275: |
1777 | 0 | return VUID_WRAP(VUID-Layer-Layer-04275); |
1778 | 0 | case 4276: |
1779 | 0 | return VUID_WRAP(VUID-Layer-Layer-04276); |
1780 | 0 | case 4281: |
1781 | 0 | return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04281); |
1782 | 0 | case 4282: |
1783 | 0 | return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04282); |
1784 | 0 | case 4283: |
1785 | 0 | return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04283); |
1786 | 0 | case 4293: |
1787 | 0 | return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04293); |
1788 | 0 | case 4294: |
1789 | 0 | return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04294); |
1790 | 0 | case 4295: |
1791 | 0 | return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04295); |
1792 | 0 | case 4296: |
1793 | 0 | return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04296); |
1794 | 0 | case 4297: |
1795 | 0 | return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297); |
1796 | 0 | case 4298: |
1797 | 0 | return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298); |
1798 | 0 | case 4299: |
1799 | 0 | return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299); |
1800 | 0 | case 4300: |
1801 | 0 | return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300); |
1802 | 0 | case 4301: |
1803 | 0 | return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301); |
1804 | 0 | case 4302: |
1805 | 0 | return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302); |
1806 | 0 | case 4303: |
1807 | 0 | return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303); |
1808 | 0 | case 4304: |
1809 | 0 | return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304); |
1810 | 0 | case 4305: |
1811 | 0 | return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305); |
1812 | 0 | case 4306: |
1813 | 0 | return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306); |
1814 | 0 | case 4307: |
1815 | 0 | return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307); |
1816 | 0 | case 4308: |
1817 | 0 | return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308); |
1818 | 0 | case 4309: |
1819 | 0 | return VUID_WRAP(VUID-PatchVertices-PatchVertices-04309); |
1820 | 0 | case 4310: |
1821 | 0 | return VUID_WRAP(VUID-PatchVertices-PatchVertices-04310); |
1822 | 0 | case 4311: |
1823 | 0 | return VUID_WRAP(VUID-PointCoord-PointCoord-04311); |
1824 | 0 | case 4312: |
1825 | 0 | return VUID_WRAP(VUID-PointCoord-PointCoord-04312); |
1826 | 0 | case 4313: |
1827 | 0 | return VUID_WRAP(VUID-PointCoord-PointCoord-04313); |
1828 | 0 | case 4314: |
1829 | 0 | return VUID_WRAP(VUID-PointSize-PointSize-04314); |
1830 | 0 | case 4315: |
1831 | 0 | return VUID_WRAP(VUID-PointSize-PointSize-04315); |
1832 | 0 | case 4316: |
1833 | 0 | return VUID_WRAP(VUID-PointSize-PointSize-04316); |
1834 | 0 | case 4317: |
1835 | 0 | return VUID_WRAP(VUID-PointSize-PointSize-04317); |
1836 | 0 | case 4318: |
1837 | 0 | return VUID_WRAP(VUID-Position-Position-04318); |
1838 | 0 | case 4319: |
1839 | 0 | return VUID_WRAP(VUID-Position-Position-04319); |
1840 | 0 | case 4320: |
1841 | 0 | return VUID_WRAP(VUID-Position-Position-04320); |
1842 | 0 | case 4321: |
1843 | 0 | return VUID_WRAP(VUID-Position-Position-04321); |
1844 | 0 | case 4330: |
1845 | 0 | return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04330); |
1846 | 0 | case 4334: |
1847 | 0 | return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334); |
1848 | 0 | case 4337: |
1849 | 0 | return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337); |
1850 | 0 | case 4345: |
1851 | 0 | return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345); |
1852 | 0 | case 4346: |
1853 | 0 | return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346); |
1854 | 0 | case 4347: |
1855 | 0 | return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347); |
1856 | 0 | case 4348: |
1857 | 0 | return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348); |
1858 | 0 | case 4349: |
1859 | 0 | return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349); |
1860 | 0 | case 4350: |
1861 | 0 | return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350); |
1862 | 0 | case 4351: |
1863 | 0 | return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351); |
1864 | 0 | case 4352: |
1865 | 0 | return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352); |
1866 | 0 | case 4353: |
1867 | 0 | return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353); |
1868 | 0 | case 4354: |
1869 | 0 | return VUID_WRAP(VUID-SampleId-SampleId-04354); |
1870 | 0 | case 4355: |
1871 | 0 | return VUID_WRAP(VUID-SampleId-SampleId-04355); |
1872 | 0 | case 4356: |
1873 | 0 | return VUID_WRAP(VUID-SampleId-SampleId-04356); |
1874 | 0 | case 4357: |
1875 | 0 | return VUID_WRAP(VUID-SampleMask-SampleMask-04357); |
1876 | 0 | case 4358: |
1877 | 0 | return VUID_WRAP(VUID-SampleMask-SampleMask-04358); |
1878 | 0 | case 4359: |
1879 | 0 | return VUID_WRAP(VUID-SampleMask-SampleMask-04359); |
1880 | 0 | case 4360: |
1881 | 0 | return VUID_WRAP(VUID-SamplePosition-SamplePosition-04360); |
1882 | 0 | case 4361: |
1883 | 0 | return VUID_WRAP(VUID-SamplePosition-SamplePosition-04361); |
1884 | 0 | case 4362: |
1885 | 0 | return VUID_WRAP(VUID-SamplePosition-SamplePosition-04362); |
1886 | 0 | case 4367: |
1887 | 0 | return VUID_WRAP(VUID-SubgroupId-SubgroupId-04367); |
1888 | 0 | case 4368: |
1889 | 0 | return VUID_WRAP(VUID-SubgroupId-SubgroupId-04368); |
1890 | 0 | case 4369: |
1891 | 0 | return VUID_WRAP(VUID-SubgroupId-SubgroupId-04369); |
1892 | 0 | case 4370: |
1893 | 0 | return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04370); |
1894 | 0 | case 4371: |
1895 | 0 | return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04371); |
1896 | 0 | case 4372: |
1897 | 0 | return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04372); |
1898 | 0 | case 4373: |
1899 | 0 | return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04373); |
1900 | 0 | case 4374: |
1901 | 0 | return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04374); |
1902 | 0 | case 4375: |
1903 | 0 | return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04375); |
1904 | 0 | case 4376: |
1905 | 0 | return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04376); |
1906 | 0 | case 4377: |
1907 | 0 | return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04377); |
1908 | 0 | case 4378: |
1909 | 0 | return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04378); |
1910 | 0 | case 4379: |
1911 | 0 | return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04379); |
1912 | 0 | case 4380: |
1913 | 0 | return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04380); |
1914 | 0 | case 4381: |
1915 | 0 | return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04381); |
1916 | 0 | case 4382: |
1917 | 0 | return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04382); |
1918 | 0 | case 4383: |
1919 | 0 | return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04383); |
1920 | 0 | case 4387: |
1921 | 0 | return VUID_WRAP(VUID-TessCoord-TessCoord-04387); |
1922 | 0 | case 4388: |
1923 | 0 | return VUID_WRAP(VUID-TessCoord-TessCoord-04388); |
1924 | 0 | case 4389: |
1925 | 0 | return VUID_WRAP(VUID-TessCoord-TessCoord-04389); |
1926 | 0 | case 4390: |
1927 | 0 | return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390); |
1928 | 0 | case 4391: |
1929 | 0 | return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391); |
1930 | 0 | case 4392: |
1931 | 0 | return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392); |
1932 | 0 | case 4393: |
1933 | 0 | return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393); |
1934 | 0 | case 4394: |
1935 | 0 | return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394); |
1936 | 0 | case 4395: |
1937 | 0 | return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395); |
1938 | 0 | case 4396: |
1939 | 0 | return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396); |
1940 | 0 | case 4397: |
1941 | 0 | return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397); |
1942 | 0 | case 4398: |
1943 | 0 | return VUID_WRAP(VUID-VertexIndex-VertexIndex-04398); |
1944 | 0 | case 4399: |
1945 | 0 | return VUID_WRAP(VUID-VertexIndex-VertexIndex-04399); |
1946 | 0 | case 4400: |
1947 | 0 | return VUID_WRAP(VUID-VertexIndex-VertexIndex-04400); |
1948 | 0 | case 4401: |
1949 | 0 | return VUID_WRAP(VUID-ViewIndex-ViewIndex-04401); |
1950 | 0 | case 4402: |
1951 | 0 | return VUID_WRAP(VUID-ViewIndex-ViewIndex-04402); |
1952 | 0 | case 4403: |
1953 | 0 | return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403); |
1954 | 0 | case 4404: |
1955 | 0 | return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404); |
1956 | 0 | case 4405: |
1957 | 0 | return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405); |
1958 | 0 | case 4406: |
1959 | 0 | return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406); |
1960 | 0 | case 4407: |
1961 | 0 | return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04407); |
1962 | 0 | case 4408: |
1963 | 0 | return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04408); |
1964 | 0 | case 4422: |
1965 | 0 | return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04422); |
1966 | 0 | case 4423: |
1967 | 0 | return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04423); |
1968 | 0 | case 4424: |
1969 | 0 | return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04424); |
1970 | 0 | case 4425: |
1971 | 0 | return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04425); |
1972 | 0 | case 4426: |
1973 | 0 | return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426); |
1974 | 0 | case 4427: |
1975 | 0 | return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427); |
1976 | 0 | case 4428: |
1977 | 0 | return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428); |
1978 | 0 | case 4429: |
1979 | 0 | return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429); |
1980 | 0 | case 4430: |
1981 | 0 | return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430); |
1982 | 0 | case 4431: |
1983 | 0 | return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431); |
1984 | 0 | case 4432: |
1985 | 0 | return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432); |
1986 | 0 | case 4433: |
1987 | 0 | return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433); |
1988 | 0 | case 4434: |
1989 | 0 | return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434); |
1990 | 0 | case 4435: |
1991 | 0 | return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435); |
1992 | 0 | case 4436: |
1993 | 0 | return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436); |
1994 | 0 | case 4484: |
1995 | 0 | return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484); |
1996 | 0 | case 4485: |
1997 | 0 | return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485); |
1998 | 0 | case 4486: |
1999 | 0 | return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04486); |
2000 | 0 | case 4490: |
2001 | 0 | return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04490); |
2002 | 0 | case 4491: |
2003 | 0 | return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04491); |
2004 | 0 | case 4492: |
2005 | 0 | return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04492); |
2006 | 0 | case 4633: |
2007 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04633); |
2008 | 0 | case 4634: |
2009 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04634); |
2010 | 0 | case 4635: |
2011 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04635); |
2012 | 0 | case 4636: |
2013 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04636); |
2014 | 0 | case 4637: |
2015 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04637); |
2016 | 0 | case 4638: |
2017 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04638); |
2018 | 0 | case 7321: |
2019 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-07321); |
2020 | 0 | case 4640: |
2021 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04640); |
2022 | 0 | case 4641: |
2023 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04641); |
2024 | 0 | case 4642: |
2025 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04642); |
2026 | 0 | case 4643: |
2027 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04643); |
2028 | 0 | case 4644: |
2029 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04644); |
2030 | 0 | case 4645: |
2031 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04645); |
2032 | 0 | case 4651: |
2033 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651); |
2034 | 0 | case 4652: |
2035 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpReadClockKHR-04652); |
2036 | 0 | case 4653: |
2037 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OriginLowerLeft-04653); |
2038 | 0 | case 4654: |
2039 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-PixelCenterInteger-04654); |
2040 | 0 | case 4655: |
2041 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-04655); |
2042 | 0 | case 4656: |
2043 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04656); |
2044 | 0 | case 4657: |
2045 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04657); |
2046 | 0 | case 4658: |
2047 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658); |
2048 | 0 | case 4659: |
2049 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659); |
2050 | 0 | case 4662: |
2051 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662); |
2052 | 0 | case 4663: |
2053 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663); |
2054 | 0 | case 4664: |
2055 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664); |
2056 | 0 | case 4667: |
2057 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04667); |
2058 | 0 | case 4669: |
2059 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669); |
2060 | 0 | case 4670: |
2061 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Flat-04670); |
2062 | 0 | case 4675: |
2063 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675); |
2064 | 0 | case 4677: |
2065 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Invariant-04677); |
2066 | 0 | case 4680: |
2067 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpTypeRuntimeArray-04680); |
2068 | 0 | case 4682: |
2069 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04682); |
2070 | 0 | case 6426: |
2071 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-LocalSize-06426); // formally 04683 |
2072 | 0 | case 4685: |
2073 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685); |
2074 | 0 | case 4686: |
2075 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-None-04686); |
2076 | 0 | case 4698: |
2077 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698); |
2078 | 0 | case 4699: |
2079 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699); |
2080 | 0 | case 4701: |
2081 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701); |
2082 | 0 | case 4703: |
2083 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703); |
2084 | 0 | case 4704: |
2085 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704); |
2086 | 0 | case 4705: |
2087 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705); |
2088 | 0 | case 7119: |
2089 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119); |
2090 | 0 | case 4708: |
2091 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708); |
2092 | 0 | case 4710: |
2093 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710); |
2094 | 0 | case 4711: |
2095 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711); |
2096 | 0 | case 4730: |
2097 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicStore-04730); |
2098 | 0 | case 4731: |
2099 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicLoad-04731); |
2100 | 0 | case 4732: |
2101 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732); |
2102 | 0 | case 4733: |
2103 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733); |
2104 | 0 | case 4734: |
2105 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734); |
2106 | 0 | case 4744: |
2107 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Flat-04744); |
2108 | 0 | case 4777: |
2109 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777); |
2110 | 0 | case 4780: |
2111 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Result-04780); |
2112 | 0 | case 4781: |
2113 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Base-04781); |
2114 | 0 | case 4915: |
2115 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Location-04915); |
2116 | 0 | case 4916: |
2117 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Location-04916); |
2118 | 0 | case 4917: |
2119 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Location-04917); |
2120 | 0 | case 4918: |
2121 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Location-04918); |
2122 | 0 | case 4919: |
2123 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Location-04919); |
2124 | 0 | case 4920: |
2125 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Component-04920); |
2126 | 0 | case 4921: |
2127 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Component-04921); |
2128 | 0 | case 4922: |
2129 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Component-04922); |
2130 | 0 | case 4923: |
2131 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Component-04923); |
2132 | 0 | case 4924: |
2133 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Component-04924); |
2134 | 0 | case 6201: |
2135 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Flat-06201); |
2136 | 0 | case 6202: |
2137 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Flat-06202); |
2138 | 0 | case 6214: |
2139 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214); |
2140 | 0 | case 6491: |
2141 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491); |
2142 | 0 | case 6671: |
2143 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671); |
2144 | 0 | case 6672: |
2145 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Location-06672); |
2146 | 0 | case 6674: |
2147 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674); |
2148 | 0 | case 6675: |
2149 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06675); |
2150 | 0 | case 6676: |
2151 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06676); |
2152 | 0 | case 6677: |
2153 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-06677); |
2154 | 0 | case 6678: |
2155 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-InputAttachmentIndex-06678); |
2156 | 0 | case 6777: |
2157 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-PerVertexKHR-06777); |
2158 | 0 | case 6778: |
2159 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Input-06778); |
2160 | 0 | case 6807: |
2161 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06807); |
2162 | 0 | case 6808: |
2163 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808); |
2164 | 0 | case 6925: |
2165 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925); |
2166 | 0 | case 6997: |
2167 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-06997); |
2168 | 0 | case 7102: |
2169 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102); |
2170 | 0 | case 7320: |
2171 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320); |
2172 | 0 | case 7290: |
2173 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Input-07290); |
2174 | 0 | case 7650: |
2175 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Base-07650); |
2176 | 0 | case 7651: |
2177 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Base-07651); |
2178 | 0 | case 7652: |
2179 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Base-07652); |
2180 | 0 | case 7703: |
2181 | 0 | return VUID_WRAP(VUID-StandaloneSpirv-Component-07703); |
2182 | 0 | default: |
2183 | 0 | return ""; // unknown id |
2184 | 0 | } |
2185 | | // clang-format on |
2186 | 0 | } |
2187 | | |
2188 | | } // namespace val |
2189 | | } // namespace spvtools |