Coverage Report

Created: 2023-03-01 07:33

/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, &current_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