1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 // Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 #include "source/val/validation_state.h"
23 #include "source/opcode.h"
24 #include "source/spirv_constant.h"
25 #include "source/spirv_target_env.h"
26 #include "source/util/make_unique.h"
27 #include "source/val/basic_block.h"
28 #include "source/val/construct.h"
29 #include "source/val/function.h"
30 #include "spirv-tools/libspirv.h"
36 ModuleLayoutSection
InstructionLayoutSection(
37 ModuleLayoutSection current_section
, spv::Op op
) {
39 if (spvOpcodeGeneratesType(op
) || spvOpcodeIsConstant(op
))
43 case spv::Op::OpCapability
:
44 return kLayoutCapabilities
;
45 case spv::Op::OpExtension
:
46 return kLayoutExtensions
;
47 case spv::Op::OpExtInstImport
:
48 return kLayoutExtInstImport
;
49 case spv::Op::OpMemoryModel
:
50 return kLayoutMemoryModel
;
51 case spv::Op::OpEntryPoint
:
52 return kLayoutEntryPoint
;
53 case spv::Op::OpExecutionMode
:
54 case spv::Op::OpExecutionModeId
:
55 return kLayoutExecutionMode
;
56 case spv::Op::OpSourceContinued
:
57 case spv::Op::OpSource
:
58 case spv::Op::OpSourceExtension
:
59 case spv::Op::OpString
:
62 case spv::Op::OpMemberName
:
64 case spv::Op::OpModuleProcessed
:
66 case spv::Op::OpDecorate
:
67 case spv::Op::OpMemberDecorate
:
68 case spv::Op::OpGroupDecorate
:
69 case spv::Op::OpGroupMemberDecorate
:
70 case spv::Op::OpDecorationGroup
:
71 case spv::Op::OpDecorateId
:
72 case spv::Op::OpDecorateStringGOOGLE
:
73 case spv::Op::OpMemberDecorateStringGOOGLE
:
74 return kLayoutAnnotations
;
75 case spv::Op::OpTypeForwardPointer
:
77 case spv::Op::OpVariable
:
78 case spv::Op::OpUntypedVariableKHR
:
79 if (current_section
== kLayoutTypes
) return kLayoutTypes
;
80 return kLayoutFunctionDefinitions
;
81 case spv::Op::OpExtInst
:
82 case spv::Op::OpExtInstWithForwardRefsKHR
:
83 // spv::Op::OpExtInst is only allowed in types section for certain
84 // extended instruction sets. This will be checked separately.
85 if (current_section
== kLayoutTypes
) return kLayoutTypes
;
86 return kLayoutFunctionDefinitions
;
88 case spv::Op::OpNoLine
:
89 case spv::Op::OpUndef
:
90 if (current_section
== kLayoutTypes
) return kLayoutTypes
;
91 return kLayoutFunctionDefinitions
;
92 case spv::Op::OpFunction
:
93 case spv::Op::OpFunctionParameter
:
94 case spv::Op::OpFunctionEnd
:
95 if (current_section
== kLayoutFunctionDeclarations
)
96 return kLayoutFunctionDeclarations
;
97 return kLayoutFunctionDefinitions
;
98 case spv::Op::OpSamplerImageAddressingModeNV
:
99 return kLayoutSamplerImageAddressMode
;
103 return kLayoutFunctionDefinitions
;
106 bool IsInstructionInLayoutSection(ModuleLayoutSection layout
, spv::Op op
) {
107 return layout
== InstructionLayoutSection(layout
, op
);
110 // Counts the number of instructions and functions in the file.
111 spv_result_t
CountInstructions(void* user_data
,
112 const spv_parsed_instruction_t
* inst
) {
113 ValidationState_t
& _
= *(reinterpret_cast<ValidationState_t
*>(user_data
));
114 if (spv::Op(inst
->opcode
) == spv::Op::OpFunction
) {
115 _
.increment_total_functions();
117 _
.increment_total_instructions();
122 spv_result_t
setHeader(void* user_data
, spv_endianness_t
, uint32_t,
123 uint32_t version
, uint32_t generator
, uint32_t id_bound
,
125 ValidationState_t
& vstate
=
126 *(reinterpret_cast<ValidationState_t
*>(user_data
));
127 vstate
.setIdBound(id_bound
);
128 vstate
.setGenerator(generator
);
129 vstate
.setVersion(version
);
134 // Add features based on SPIR-V core version number.
135 void UpdateFeaturesBasedOnSpirvVersion(ValidationState_t::Feature
* features
,
138 if (version
>= SPV_SPIRV_VERSION_WORD(1, 4)) {
139 features
->select_between_composites
= true;
140 features
->copy_memory_permits_two_memory_accesses
= true;
141 features
->uconvert_spec_constant_op
= true;
142 features
->nonwritable_var_in_function_or_private
= true;
148 ValidationState_t::ValidationState_t(const spv_const_context ctx
,
149 const spv_const_validator_options opt
,
150 const uint32_t* words
,
151 const size_t num_words
,
152 const uint32_t max_warnings
)
156 num_words_(num_words
),
157 unresolved_forward_ids_
{},
159 current_layout_section_(kLayoutCapabilities
),
161 module_capabilities_(),
162 module_extensions_(),
163 ordered_instructions_(),
167 struct_nesting_depth_(),
168 struct_has_nested_blockorbufferblock_struct_(),
170 addressing_model_(spv::AddressingModel::Max
),
171 memory_model_(spv::MemoryModel::Max
),
172 pointer_size_and_alignment_(0),
173 sampler_image_addressing_mode_(0),
176 max_num_of_warnings_(max_warnings
) {
177 assert(opt
&& "Validator options may not be Null.");
179 const auto env
= context_
->target_env
;
181 if (spvIsVulkanEnv(env
)) {
182 // Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core.
183 if (env
!= SPV_ENV_VULKAN_1_0
) {
184 features_
.env_relaxed_block_layout
= true;
188 // LocalSizeId is only disallowed prior to Vulkan 1.3 without maintenance4.
190 case SPV_ENV_VULKAN_1_0
:
191 case SPV_ENV_VULKAN_1_1
:
192 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
193 case SPV_ENV_VULKAN_1_2
:
194 features_
.env_allow_localsizeid
= false;
197 features_
.env_allow_localsizeid
= true;
201 // Only attempt to count if we have words, otherwise let the other validation
202 // fail and generate an error.
204 // Count the number of instructions in the binary.
205 // This parse should not produce any error messages. Hijack the context and
206 // replace the message consumer so that we do not pollute any state in input
208 spv_context_t hijacked_context
= *ctx
;
209 hijacked_context
.consumer
= [](spv_message_level_t
, const char*,
210 const spv_position_t
&, const char*) {};
211 spvBinaryParse(&hijacked_context
, this, words
, num_words
, setHeader
,
213 /* diagnostic = */ nullptr);
214 preallocateStorage();
216 UpdateFeaturesBasedOnSpirvVersion(&features_
, version_
);
218 name_mapper_
= spvtools::GetTrivialNameMapper();
219 if (options_
->use_friendly_names
) {
220 friendly_mapper_
= spvtools::MakeUnique
<spvtools::FriendlyNameMapper
>(
221 context_
, words_
, num_words_
);
222 name_mapper_
= friendly_mapper_
->GetNameMapper();
226 void ValidationState_t::preallocateStorage() {
227 ordered_instructions_
.reserve(total_instructions_
);
228 module_functions_
.reserve(total_functions_
);
231 spv_result_t
ValidationState_t::ForwardDeclareId(uint32_t id
) {
232 unresolved_forward_ids_
.insert(id
);
236 spv_result_t
ValidationState_t::RemoveIfForwardDeclared(uint32_t id
) {
237 unresolved_forward_ids_
.erase(id
);
241 spv_result_t
ValidationState_t::RegisterForwardPointer(uint32_t id
) {
242 forward_pointer_ids_
.insert(id
);
246 bool ValidationState_t::IsForwardPointer(uint32_t id
) const {
247 return (forward_pointer_ids_
.find(id
) != forward_pointer_ids_
.end());
250 void ValidationState_t::AssignNameToId(uint32_t id
, std::string name
) {
251 operand_names_
[id
] = name
;
254 std::string
ValidationState_t::getIdName(uint32_t id
) const {
255 const std::string id_name
= name_mapper_(id
);
257 std::stringstream out
;
258 out
<< "'" << id
<< "[%" << id_name
<< "]'";
262 size_t ValidationState_t::unresolved_forward_id_count() const {
263 return unresolved_forward_ids_
.size();
266 std::vector
<uint32_t> ValidationState_t::UnresolvedForwardIds() const {
267 std::vector
<uint32_t> out(std::begin(unresolved_forward_ids_
),
268 std::end(unresolved_forward_ids_
));
272 bool ValidationState_t::IsDefinedId(uint32_t id
) const {
273 return all_definitions_
.find(id
) != std::end(all_definitions_
);
276 const Instruction
* ValidationState_t::FindDef(uint32_t id
) const {
277 auto it
= all_definitions_
.find(id
);
278 if (it
== all_definitions_
.end()) return nullptr;
282 Instruction
* ValidationState_t::FindDef(uint32_t id
) {
283 auto it
= all_definitions_
.find(id
);
284 if (it
== all_definitions_
.end()) return nullptr;
288 ModuleLayoutSection
ValidationState_t::current_layout_section() const {
289 return current_layout_section_
;
292 void ValidationState_t::ProgressToNextLayoutSectionOrder() {
293 // Guard against going past the last element(kLayoutFunctionDefinitions)
294 if (current_layout_section_
<= kLayoutFunctionDefinitions
) {
295 current_layout_section_
=
296 static_cast<ModuleLayoutSection
>(current_layout_section_
+ 1);
300 bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op
) {
301 ModuleLayoutSection section
=
302 InstructionLayoutSection(current_layout_section_
, op
);
303 return section
< current_layout_section_
;
306 bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op
) {
307 return IsInstructionInLayoutSection(current_layout_section_
, op
);
310 DiagnosticStream
ValidationState_t::diag(spv_result_t error_code
,
311 const Instruction
* inst
) {
312 if (error_code
== SPV_WARNING
) {
313 if (num_of_warnings_
== max_num_of_warnings_
) {
314 DiagnosticStream({0, 0, 0}, context_
->consumer
, "", error_code
)
315 << "Other warnings have been suppressed.\n";
317 if (num_of_warnings_
>= max_num_of_warnings_
) {
318 return DiagnosticStream({0, 0, 0}, nullptr, "", error_code
);
323 std::string disassembly
;
324 if (inst
) disassembly
= Disassemble(*inst
);
326 return DiagnosticStream({0, 0, inst
? inst
->LineNum() : 0},
327 context_
->consumer
, disassembly
, error_code
);
330 std::vector
<Function
>& ValidationState_t::functions() {
331 return module_functions_
;
334 Function
& ValidationState_t::current_function() {
335 assert(in_function_body());
336 return module_functions_
.back();
339 const Function
& ValidationState_t::current_function() const {
340 assert(in_function_body());
341 return module_functions_
.back();
344 const Function
* ValidationState_t::function(uint32_t id
) const {
345 const auto it
= id_to_function_
.find(id
);
346 if (it
== id_to_function_
.end()) return nullptr;
350 Function
* ValidationState_t::function(uint32_t id
) {
351 auto it
= id_to_function_
.find(id
);
352 if (it
== id_to_function_
.end()) return nullptr;
356 bool ValidationState_t::in_function_body() const { return in_function_
; }
358 bool ValidationState_t::in_block() const {
359 return module_functions_
.empty() == false &&
360 module_functions_
.back().current_block() != nullptr;
363 void ValidationState_t::RegisterCapability(spv::Capability cap
) {
364 // Avoid redundant work. Otherwise the recursion could induce work
365 // quadrdatic in the capability dependency depth. (Ok, not much, but
367 if (module_capabilities_
.contains(cap
)) return;
369 module_capabilities_
.insert(cap
);
370 spv_operand_desc desc
;
371 if (SPV_SUCCESS
== grammar_
.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY
,
372 uint32_t(cap
), &desc
)) {
373 for (auto capability
:
374 CapabilitySet(desc
->numCapabilities
, desc
->capabilities
)) {
375 RegisterCapability(capability
);
380 case spv::Capability::Kernel
:
381 features_
.group_ops_reduce_and_scans
= true;
383 case spv::Capability::Int8
:
384 features_
.use_int8_type
= true;
385 features_
.declare_int8_type
= true;
387 case spv::Capability::StorageBuffer8BitAccess
:
388 case spv::Capability::UniformAndStorageBuffer8BitAccess
:
389 case spv::Capability::StoragePushConstant8
:
390 case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR
:
391 features_
.declare_int8_type
= true;
393 case spv::Capability::Int16
:
394 features_
.declare_int16_type
= true;
396 case spv::Capability::Float16
:
397 case spv::Capability::Float16Buffer
:
398 features_
.declare_float16_type
= true;
400 case spv::Capability::StorageUniformBufferBlock16
:
401 case spv::Capability::StorageUniform16
:
402 case spv::Capability::StoragePushConstant16
:
403 case spv::Capability::StorageInputOutput16
:
404 case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR
:
405 features_
.declare_int16_type
= true;
406 features_
.declare_float16_type
= true;
407 features_
.free_fp_rounding_mode
= true;
409 case spv::Capability::VariablePointers
:
410 case spv::Capability::VariablePointersStorageBuffer
:
411 features_
.variable_pointers
= true;
414 // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses
415 // capability spv::Capability::RayTracingNV.
416 // spv::Capability::RayTracingProvisionalKHR would need the same
417 // treatment. One of the differences going from SPV_KHR_ray_tracing from
418 // provisional to final spec was the provisional spec uses Locations
419 // for variables in certain storage classes, just like the
420 // SPV_NV_ray_tracing extension. So it mimics the NVIDIA extension.
421 // The final SPV_KHR_ray_tracing uses a different capability token
422 // number, so it doesn't fall into this case.
427 void ValidationState_t::RegisterExtension(Extension ext
) {
428 if (module_extensions_
.contains(ext
)) return;
430 module_extensions_
.insert(ext
);
433 case kSPV_AMD_gpu_shader_half_float
:
434 case kSPV_AMD_gpu_shader_half_float_fetch
:
435 // SPV_AMD_gpu_shader_half_float enables float16 type.
436 // https://github.com/KhronosGroup/SPIRV-Tools/issues/1375
437 features_
.declare_float16_type
= true;
439 case kSPV_AMD_gpu_shader_int16
:
440 // This is not yet in the extension, but it's recommended for it.
441 // See https://github.com/KhronosGroup/glslang/issues/848
442 features_
.uconvert_spec_constant_op
= true;
444 case kSPV_AMD_shader_ballot
:
445 // The grammar doesn't encode the fact that SPV_AMD_shader_ballot
446 // enables the use of group operations Reduce, InclusiveScan,
447 // and ExclusiveScan. Enable it manually.
448 // https://github.com/KhronosGroup/SPIRV-Tools/issues/991
449 features_
.group_ops_reduce_and_scans
= true;
456 bool ValidationState_t::HasAnyOfCapabilities(
457 const CapabilitySet
& capabilities
) const {
458 return module_capabilities_
.HasAnyOf(capabilities
);
461 bool ValidationState_t::HasAnyOfExtensions(
462 const ExtensionSet
& extensions
) const {
463 return module_extensions_
.HasAnyOf(extensions
);
466 void ValidationState_t::set_addressing_model(spv::AddressingModel am
) {
467 addressing_model_
= am
;
469 case spv::AddressingModel::Physical32
:
470 pointer_size_and_alignment_
= 4;
474 case spv::AddressingModel::Physical64
:
475 case spv::AddressingModel::PhysicalStorageBuffer64
:
476 pointer_size_and_alignment_
= 8;
481 spv::AddressingModel
ValidationState_t::addressing_model() const {
482 return addressing_model_
;
485 void ValidationState_t::set_memory_model(spv::MemoryModel mm
) {
489 spv::MemoryModel
ValidationState_t::memory_model() const {
490 return memory_model_
;
493 void ValidationState_t::set_samplerimage_variable_address_mode(
494 uint32_t bit_width
) {
495 sampler_image_addressing_mode_
= bit_width
;
498 uint32_t ValidationState_t::samplerimage_variable_address_mode() const {
499 return sampler_image_addressing_mode_
;
502 spv_result_t
ValidationState_t::RegisterFunction(
503 uint32_t id
, uint32_t ret_type_id
,
504 spv::FunctionControlMask function_control
, uint32_t function_type_id
) {
505 assert(in_function_body() == false &&
506 "RegisterFunction can only be called when parsing the binary outside "
507 "of another function");
509 module_functions_
.emplace_back(id
, ret_type_id
, function_control
,
511 id_to_function_
.emplace(id
, ¤t_function());
513 // TODO(umar): validate function type and type_id
518 spv_result_t
ValidationState_t::RegisterFunctionEnd() {
519 assert(in_function_body() == true &&
520 "RegisterFunctionEnd can only be called when parsing the binary "
521 "inside of another function");
522 assert(in_block() == false &&
523 "RegisterFunctionParameter can only be called when parsing the binary "
524 "outside of a block");
525 current_function().RegisterFunctionEnd();
526 in_function_
= false;
530 Instruction
* ValidationState_t::AddOrderedInstruction(
531 const spv_parsed_instruction_t
* inst
) {
532 ordered_instructions_
.emplace_back(inst
);
533 ordered_instructions_
.back().SetLineNum(ordered_instructions_
.size());
534 return &ordered_instructions_
.back();
537 // Improves diagnostic messages by collecting names of IDs
538 void ValidationState_t::RegisterDebugInstruction(const Instruction
* inst
) {
539 switch (inst
->opcode()) {
540 case spv::Op::OpName
: {
541 const auto target
= inst
->GetOperandAs
<uint32_t>(0);
542 const std::string str
= inst
->GetOperandAs
<std::string
>(1);
543 AssignNameToId(target
, str
);
546 case spv::Op::OpMemberName
: {
547 const auto target
= inst
->GetOperandAs
<uint32_t>(0);
548 const std::string str
= inst
->GetOperandAs
<std::string
>(2);
549 AssignNameToId(target
, str
);
552 case spv::Op::OpSourceContinued
:
553 case spv::Op::OpSource
:
554 case spv::Op::OpSourceExtension
:
555 case spv::Op::OpString
:
556 case spv::Op::OpLine
:
557 case spv::Op::OpNoLine
:
563 void ValidationState_t::RegisterInstruction(Instruction
* inst
) {
564 if (inst
->id()) all_definitions_
.insert(std::make_pair(inst
->id(), inst
));
566 // Some validation checks are easier by getting all the consumers
567 for (size_t i
= 0; i
< inst
->operands().size(); ++i
) {
568 const spv_parsed_operand_t
& operand
= inst
->operand(i
);
569 if ((SPV_OPERAND_TYPE_ID
== operand
.type
) ||
570 (SPV_OPERAND_TYPE_TYPE_ID
== operand
.type
)) {
571 const uint32_t operand_word
= inst
->word(operand
.offset
);
572 Instruction
* operand_inst
= FindDef(operand_word
);
577 // If the instruction is using an OpTypeSampledImage as an operand, it
578 // should be recorded. The validator will ensure that all usages of an
579 // OpTypeSampledImage and its definition are in the same basic block.
580 if ((SPV_OPERAND_TYPE_ID
== operand
.type
) &&
581 (spv::Op::OpSampledImage
== operand_inst
->opcode())) {
582 RegisterSampledImageConsumer(operand_word
, inst
);
585 // In order to track storage classes (not Function) used per execution
586 // model we can't use RegisterExecutionModelLimitation on instructions
587 // like OpTypePointer which are going to be in the pre-function section.
588 // Instead just need to register storage class usage for consumers in a
590 if (inst
->function()) {
591 if (operand_inst
->opcode() == spv::Op::OpTypePointer
) {
592 RegisterStorageClassConsumer(
593 operand_inst
->GetOperandAs
<spv::StorageClass
>(1), inst
);
594 } else if (operand_inst
->opcode() == spv::Op::OpVariable
) {
595 RegisterStorageClassConsumer(
596 operand_inst
->GetOperandAs
<spv::StorageClass
>(2), inst
);
603 std::vector
<Instruction
*> ValidationState_t::getSampledImageConsumers(
604 uint32_t sampled_image_id
) const {
605 std::vector
<Instruction
*> result
;
606 auto iter
= sampled_image_consumers_
.find(sampled_image_id
);
607 if (iter
!= sampled_image_consumers_
.end()) {
608 result
= iter
->second
;
613 void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id
,
614 Instruction
* consumer
) {
615 sampled_image_consumers_
[sampled_image_id
].push_back(consumer
);
618 void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer(
619 uint32_t texture_id
, const Instruction
* consumer0
,
620 const Instruction
* consumer1
) {
621 if (HasDecoration(texture_id
, spv::Decoration::WeightTextureQCOM
) ||
622 HasDecoration(texture_id
, spv::Decoration::BlockMatchTextureQCOM
) ||
623 HasDecoration(texture_id
, spv::Decoration::BlockMatchSamplerQCOM
)) {
624 qcom_image_processing_consumers_
.insert(consumer0
->id());
626 qcom_image_processing_consumers_
.insert(consumer1
->id());
631 void ValidationState_t::RegisterStorageClassConsumer(
632 spv::StorageClass storage_class
, Instruction
* consumer
) {
633 if (spvIsVulkanEnv(context()->target_env
)) {
634 if (storage_class
== spv::StorageClass::Output
) {
635 std::string errorVUID
= VkErrorID(4644);
636 function(consumer
->function()->id())
637 ->RegisterExecutionModelLimitation([errorVUID
](
638 spv::ExecutionModel model
,
639 std::string
* message
) {
640 if (model
== spv::ExecutionModel::GLCompute
||
641 model
== spv::ExecutionModel::RayGenerationKHR
||
642 model
== spv::ExecutionModel::IntersectionKHR
||
643 model
== spv::ExecutionModel::AnyHitKHR
||
644 model
== spv::ExecutionModel::ClosestHitKHR
||
645 model
== spv::ExecutionModel::MissKHR
||
646 model
== spv::ExecutionModel::CallableKHR
) {
650 "in Vulkan environment, Output Storage Class must not be "
651 "used in GLCompute, RayGenerationKHR, IntersectionKHR, "
652 "AnyHitKHR, ClosestHitKHR, MissKHR, or CallableKHR "
661 if (storage_class
== spv::StorageClass::Workgroup
) {
662 std::string errorVUID
= VkErrorID(4645);
663 function(consumer
->function()->id())
664 ->RegisterExecutionModelLimitation([errorVUID
](
665 spv::ExecutionModel model
,
666 std::string
* message
) {
667 if (model
!= spv::ExecutionModel::GLCompute
&&
668 model
!= spv::ExecutionModel::TaskNV
&&
669 model
!= spv::ExecutionModel::MeshNV
&&
670 model
!= spv::ExecutionModel::TaskEXT
&&
671 model
!= spv::ExecutionModel::MeshEXT
) {
675 "in Vulkan environment, Workgroup Storage Class is limited "
676 "to MeshNV, TaskNV, and GLCompute execution model";
685 if (storage_class
== spv::StorageClass::CallableDataKHR
) {
686 std::string errorVUID
= VkErrorID(4704);
687 function(consumer
->function()->id())
688 ->RegisterExecutionModelLimitation(
689 [errorVUID
](spv::ExecutionModel model
, std::string
* message
) {
690 if (model
!= spv::ExecutionModel::RayGenerationKHR
&&
691 model
!= spv::ExecutionModel::ClosestHitKHR
&&
692 model
!= spv::ExecutionModel::CallableKHR
&&
693 model
!= spv::ExecutionModel::MissKHR
) {
697 "CallableDataKHR Storage Class is limited to "
698 "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
699 "MissKHR execution model";
705 } else if (storage_class
== spv::StorageClass::IncomingCallableDataKHR
) {
706 std::string errorVUID
= VkErrorID(4705);
707 function(consumer
->function()->id())
708 ->RegisterExecutionModelLimitation(
709 [errorVUID
](spv::ExecutionModel model
, std::string
* message
) {
710 if (model
!= spv::ExecutionModel::CallableKHR
) {
714 "IncomingCallableDataKHR Storage Class is limited to "
715 "CallableKHR execution model";
721 } else if (storage_class
== spv::StorageClass::RayPayloadKHR
) {
722 std::string errorVUID
= VkErrorID(4698);
723 function(consumer
->function()->id())
724 ->RegisterExecutionModelLimitation([errorVUID
](
725 spv::ExecutionModel model
,
726 std::string
* message
) {
727 if (model
!= spv::ExecutionModel::RayGenerationKHR
&&
728 model
!= spv::ExecutionModel::ClosestHitKHR
&&
729 model
!= spv::ExecutionModel::MissKHR
) {
733 "RayPayloadKHR Storage Class is limited to RayGenerationKHR, "
734 "ClosestHitKHR, and MissKHR execution model";
740 } else if (storage_class
== spv::StorageClass::HitAttributeKHR
) {
741 std::string errorVUID
= VkErrorID(4701);
742 function(consumer
->function()->id())
743 ->RegisterExecutionModelLimitation(
744 [errorVUID
](spv::ExecutionModel model
, std::string
* message
) {
745 if (model
!= spv::ExecutionModel::IntersectionKHR
&&
746 model
!= spv::ExecutionModel::AnyHitKHR
&&
747 model
!= spv::ExecutionModel::ClosestHitKHR
) {
749 *message
= errorVUID
+
750 "HitAttributeKHR Storage Class is limited to "
751 "IntersectionKHR, AnyHitKHR, sand ClosestHitKHR "
758 } else if (storage_class
== spv::StorageClass::IncomingRayPayloadKHR
) {
759 std::string errorVUID
= VkErrorID(4699);
760 function(consumer
->function()->id())
761 ->RegisterExecutionModelLimitation(
762 [errorVUID
](spv::ExecutionModel model
, std::string
* message
) {
763 if (model
!= spv::ExecutionModel::AnyHitKHR
&&
764 model
!= spv::ExecutionModel::ClosestHitKHR
&&
765 model
!= spv::ExecutionModel::MissKHR
) {
769 "IncomingRayPayloadKHR Storage Class is limited to "
770 "AnyHitKHR, ClosestHitKHR, and MissKHR execution model";
776 } else if (storage_class
== spv::StorageClass::ShaderRecordBufferKHR
) {
777 std::string errorVUID
= VkErrorID(7119);
778 function(consumer
->function()->id())
779 ->RegisterExecutionModelLimitation(
780 [errorVUID
](spv::ExecutionModel model
, std::string
* message
) {
781 if (model
!= spv::ExecutionModel::RayGenerationKHR
&&
782 model
!= spv::ExecutionModel::IntersectionKHR
&&
783 model
!= spv::ExecutionModel::AnyHitKHR
&&
784 model
!= spv::ExecutionModel::ClosestHitKHR
&&
785 model
!= spv::ExecutionModel::CallableKHR
&&
786 model
!= spv::ExecutionModel::MissKHR
) {
790 "ShaderRecordBufferKHR Storage Class is limited to "
791 "RayGenerationKHR, IntersectionKHR, AnyHitKHR, "
792 "ClosestHitKHR, CallableKHR, and MissKHR execution model";
798 } else if (storage_class
== spv::StorageClass::TaskPayloadWorkgroupEXT
) {
799 function(consumer
->function()->id())
800 ->RegisterExecutionModelLimitation(
801 [](spv::ExecutionModel model
, std::string
* message
) {
802 if (model
!= spv::ExecutionModel::TaskEXT
&&
803 model
!= spv::ExecutionModel::MeshEXT
) {
806 "TaskPayloadWorkgroupEXT Storage Class is limited to "
807 "TaskEXT and MeshKHR execution model";
813 } else if (storage_class
== spv::StorageClass::HitObjectAttributeNV
) {
814 function(consumer
->function()->id())
815 ->RegisterExecutionModelLimitation([](spv::ExecutionModel model
,
816 std::string
* message
) {
817 if (model
!= spv::ExecutionModel::RayGenerationKHR
&&
818 model
!= spv::ExecutionModel::ClosestHitKHR
&&
819 model
!= spv::ExecutionModel::MissKHR
) {
822 "HitObjectAttributeNV Storage Class is limited to "
823 "RayGenerationKHR, ClosestHitKHR or MissKHR execution model";
832 uint32_t ValidationState_t::getIdBound() const { return id_bound_
; }
834 void ValidationState_t::setIdBound(const uint32_t bound
) { id_bound_
= bound
; }
836 bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction
* inst
) {
837 std::vector
<uint32_t> key
;
838 key
.push_back(static_cast<uint32_t>(inst
->opcode()));
839 for (size_t index
= 0; index
< inst
->operands().size(); ++index
) {
840 const spv_parsed_operand_t
& operand
= inst
->operand(index
);
842 if (operand
.type
== SPV_OPERAND_TYPE_RESULT_ID
) continue;
844 const int words_begin
= operand
.offset
;
845 const int words_end
= words_begin
+ operand
.num_words
;
846 assert(words_end
<= static_cast<int>(inst
->words().size()));
848 key
.insert(key
.end(), inst
->words().begin() + words_begin
,
849 inst
->words().begin() + words_end
);
852 return unique_type_declarations_
.insert(std::move(key
)).second
;
855 uint32_t ValidationState_t::GetTypeId(uint32_t id
) const {
856 const Instruction
* inst
= FindDef(id
);
857 return inst
? inst
->type_id() : 0;
860 spv::Op
ValidationState_t::GetIdOpcode(uint32_t id
) const {
861 const Instruction
* inst
= FindDef(id
);
862 return inst
? inst
->opcode() : spv::Op::OpNop
;
865 uint32_t ValidationState_t::GetComponentType(uint32_t id
) const {
866 const Instruction
* inst
= FindDef(id
);
869 switch (inst
->opcode()) {
870 case spv::Op::OpTypeFloat
:
871 case spv::Op::OpTypeInt
:
872 case spv::Op::OpTypeBool
:
875 case spv::Op::OpTypeArray
:
876 return inst
->word(2);
878 case spv::Op::OpTypeVector
:
879 return inst
->word(2);
881 case spv::Op::OpTypeMatrix
:
882 return GetComponentType(inst
->word(2));
884 case spv::Op::OpTypeCooperativeMatrixNV
:
885 case spv::Op::OpTypeCooperativeMatrixKHR
:
886 case spv::Op::OpTypeCooperativeVectorNV
:
887 return inst
->word(2);
893 if (inst
->type_id()) return GetComponentType(inst
->type_id());
899 uint32_t ValidationState_t::GetDimension(uint32_t id
) const {
900 const Instruction
* inst
= FindDef(id
);
903 switch (inst
->opcode()) {
904 case spv::Op::OpTypeFloat
:
905 case spv::Op::OpTypeInt
:
906 case spv::Op::OpTypeBool
:
909 case spv::Op::OpTypeVector
:
910 case spv::Op::OpTypeMatrix
:
911 return inst
->word(3);
913 case spv::Op::OpTypeCooperativeMatrixNV
:
914 case spv::Op::OpTypeCooperativeMatrixKHR
:
915 case spv::Op::OpTypeCooperativeVectorNV
:
916 // Actual dimension isn't known, return 0
923 if (inst
->type_id()) return GetDimension(inst
->type_id());
929 uint32_t ValidationState_t::GetBitWidth(uint32_t id
) const {
930 const uint32_t component_type_id
= GetComponentType(id
);
931 const Instruction
* inst
= FindDef(component_type_id
);
934 if (inst
->opcode() == spv::Op::OpTypeFloat
||
935 inst
->opcode() == spv::Op::OpTypeInt
)
936 return inst
->word(2);
938 if (inst
->opcode() == spv::Op::OpTypeBool
) return 1;
944 bool ValidationState_t::IsVoidType(uint32_t id
) const {
945 const Instruction
* inst
= FindDef(id
);
946 return inst
&& inst
->opcode() == spv::Op::OpTypeVoid
;
949 bool ValidationState_t::IsFloatScalarType(uint32_t id
) const {
950 const Instruction
* inst
= FindDef(id
);
951 return inst
&& inst
->opcode() == spv::Op::OpTypeFloat
;
954 bool ValidationState_t::IsFloatArrayType(uint32_t id
) const {
955 const Instruction
* inst
= FindDef(id
);
960 if (inst
->opcode() == spv::Op::OpTypeArray
) {
961 return IsFloatScalarType(GetComponentType(id
));
967 bool ValidationState_t::IsFloatVectorType(uint32_t id
) const {
968 const Instruction
* inst
= FindDef(id
);
973 if (inst
->opcode() == spv::Op::OpTypeVector
) {
974 return IsFloatScalarType(GetComponentType(id
));
980 bool ValidationState_t::IsFloat16Vector2Or4Type(uint32_t id
) const {
981 const Instruction
* inst
= FindDef(id
);
984 if (inst
->opcode() == spv::Op::OpTypeVector
) {
985 uint32_t vectorDim
= GetDimension(id
);
986 return IsFloatScalarType(GetComponentType(id
)) &&
987 (vectorDim
== 2 || vectorDim
== 4) &&
988 (GetBitWidth(GetComponentType(id
)) == 16);
994 bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id
) const {
995 const Instruction
* inst
= FindDef(id
);
1000 if (inst
->opcode() == spv::Op::OpTypeFloat
) {
1004 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1005 return IsFloatScalarType(GetComponentType(id
));
1011 bool ValidationState_t::IsIntScalarType(uint32_t id
) const {
1012 const Instruction
* inst
= FindDef(id
);
1013 return inst
&& inst
->opcode() == spv::Op::OpTypeInt
;
1016 bool ValidationState_t::IsIntArrayType(uint32_t id
) const {
1017 const Instruction
* inst
= FindDef(id
);
1022 if (inst
->opcode() == spv::Op::OpTypeArray
) {
1023 return IsIntScalarType(GetComponentType(id
));
1029 bool ValidationState_t::IsIntVectorType(uint32_t id
) const {
1030 const Instruction
* inst
= FindDef(id
);
1035 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1036 return IsIntScalarType(GetComponentType(id
));
1042 bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id
) const {
1043 const Instruction
* inst
= FindDef(id
);
1048 if (inst
->opcode() == spv::Op::OpTypeInt
) {
1052 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1053 return IsIntScalarType(GetComponentType(id
));
1059 bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id
) const {
1060 const Instruction
* inst
= FindDef(id
);
1061 return inst
&& inst
->opcode() == spv::Op::OpTypeInt
&& inst
->word(3) == 0;
1064 bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id
) const {
1065 const Instruction
* inst
= FindDef(id
);
1070 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1071 return IsUnsignedIntScalarType(GetComponentType(id
));
1077 bool ValidationState_t::IsUnsignedIntScalarOrVectorType(uint32_t id
) const {
1078 const Instruction
* inst
= FindDef(id
);
1083 if (inst
->opcode() == spv::Op::OpTypeInt
) {
1084 return inst
->GetOperandAs
<uint32_t>(2) == 0;
1087 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1088 return IsUnsignedIntScalarType(GetComponentType(id
));
1094 bool ValidationState_t::IsSignedIntScalarType(uint32_t id
) const {
1095 const Instruction
* inst
= FindDef(id
);
1096 return inst
&& inst
->opcode() == spv::Op::OpTypeInt
&& inst
->word(3) == 1;
1099 bool ValidationState_t::IsSignedIntVectorType(uint32_t id
) const {
1100 const Instruction
* inst
= FindDef(id
);
1105 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1106 return IsSignedIntScalarType(GetComponentType(id
));
1112 bool ValidationState_t::IsBoolScalarType(uint32_t id
) const {
1113 const Instruction
* inst
= FindDef(id
);
1114 return inst
&& inst
->opcode() == spv::Op::OpTypeBool
;
1117 bool ValidationState_t::IsBoolVectorType(uint32_t id
) const {
1118 const Instruction
* inst
= FindDef(id
);
1123 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1124 return IsBoolScalarType(GetComponentType(id
));
1130 bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id
) const {
1131 const Instruction
* inst
= FindDef(id
);
1136 if (inst
->opcode() == spv::Op::OpTypeBool
) {
1140 if (inst
->opcode() == spv::Op::OpTypeVector
) {
1141 return IsBoolScalarType(GetComponentType(id
));
1147 bool ValidationState_t::IsFloatMatrixType(uint32_t id
) const {
1148 const Instruction
* inst
= FindDef(id
);
1153 if (inst
->opcode() == spv::Op::OpTypeMatrix
) {
1154 return IsFloatScalarType(GetComponentType(id
));
1160 bool ValidationState_t::GetMatrixTypeInfo(uint32_t id
, uint32_t* num_rows
,
1162 uint32_t* column_type
,
1163 uint32_t* component_type
) const {
1164 if (!id
) return false;
1166 const Instruction
* mat_inst
= FindDef(id
);
1168 if (mat_inst
->opcode() != spv::Op::OpTypeMatrix
) return false;
1170 const uint32_t vec_type
= mat_inst
->word(2);
1171 const Instruction
* vec_inst
= FindDef(vec_type
);
1174 if (vec_inst
->opcode() != spv::Op::OpTypeVector
) {
1179 *num_cols
= mat_inst
->word(3);
1180 *num_rows
= vec_inst
->word(3);
1181 *column_type
= mat_inst
->word(2);
1182 *component_type
= vec_inst
->word(2);
1187 bool ValidationState_t::GetStructMemberTypes(
1188 uint32_t struct_type_id
, std::vector
<uint32_t>* member_types
) const {
1189 member_types
->clear();
1190 if (!struct_type_id
) return false;
1192 const Instruction
* inst
= FindDef(struct_type_id
);
1194 if (inst
->opcode() != spv::Op::OpTypeStruct
) return false;
1197 std::vector
<uint32_t>(inst
->words().cbegin() + 2, inst
->words().cend());
1199 if (member_types
->empty()) return false;
1204 bool ValidationState_t::IsPointerType(uint32_t id
) const {
1205 if (!id
) return false;
1206 const Instruction
* inst
= FindDef(id
);
1208 return inst
->opcode() == spv::Op::OpTypePointer
||
1209 inst
->opcode() == spv::Op::OpTypeUntypedPointerKHR
;
1212 bool ValidationState_t::GetPointerTypeInfo(
1213 uint32_t id
, uint32_t* data_type
, spv::StorageClass
* storage_class
) const {
1214 *storage_class
= spv::StorageClass::Max
;
1215 if (!id
) return false;
1217 const Instruction
* inst
= FindDef(id
);
1219 if (inst
->opcode() == spv::Op::OpTypeUntypedPointerKHR
) {
1220 *storage_class
= spv::StorageClass(inst
->word(2));
1225 if (inst
->opcode() != spv::Op::OpTypePointer
) return false;
1227 *storage_class
= spv::StorageClass(inst
->word(2));
1228 *data_type
= inst
->word(3);
1232 bool ValidationState_t::IsAccelerationStructureType(uint32_t id
) const {
1233 const Instruction
* inst
= FindDef(id
);
1234 return inst
&& inst
->opcode() == spv::Op::OpTypeAccelerationStructureKHR
;
1237 bool ValidationState_t::IsCooperativeMatrixType(uint32_t id
) const {
1238 const Instruction
* inst
= FindDef(id
);
1239 return inst
&& (inst
->opcode() == spv::Op::OpTypeCooperativeMatrixNV
||
1240 inst
->opcode() == spv::Op::OpTypeCooperativeMatrixKHR
);
1243 bool ValidationState_t::IsCooperativeMatrixNVType(uint32_t id
) const {
1244 const Instruction
* inst
= FindDef(id
);
1245 return inst
&& inst
->opcode() == spv::Op::OpTypeCooperativeMatrixNV
;
1248 bool ValidationState_t::IsCooperativeMatrixKHRType(uint32_t id
) const {
1249 const Instruction
* inst
= FindDef(id
);
1250 return inst
&& inst
->opcode() == spv::Op::OpTypeCooperativeMatrixKHR
;
1253 bool ValidationState_t::IsCooperativeMatrixAType(uint32_t id
) const {
1254 if (!IsCooperativeMatrixKHRType(id
)) return false;
1255 const Instruction
* inst
= FindDef(id
);
1256 uint64_t matrixUse
= 0;
1257 if (EvalConstantValUint64(inst
->word(6), &matrixUse
)) {
1259 static_cast<uint64_t>(spv::CooperativeMatrixUse::MatrixAKHR
);
1264 bool ValidationState_t::IsCooperativeMatrixBType(uint32_t id
) const {
1265 if (!IsCooperativeMatrixKHRType(id
)) return false;
1266 const Instruction
* inst
= FindDef(id
);
1267 uint64_t matrixUse
= 0;
1268 if (EvalConstantValUint64(inst
->word(6), &matrixUse
)) {
1270 static_cast<uint64_t>(spv::CooperativeMatrixUse::MatrixBKHR
);
1274 bool ValidationState_t::IsCooperativeMatrixAccType(uint32_t id
) const {
1275 if (!IsCooperativeMatrixKHRType(id
)) return false;
1276 const Instruction
* inst
= FindDef(id
);
1277 uint64_t matrixUse
= 0;
1278 if (EvalConstantValUint64(inst
->word(6), &matrixUse
)) {
1279 return matrixUse
== static_cast<uint64_t>(
1280 spv::CooperativeMatrixUse::MatrixAccumulatorKHR
);
1285 bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id
) const {
1286 if (!IsCooperativeMatrixNVType(id
) && !IsCooperativeMatrixKHRType(id
))
1288 return IsFloatScalarType(FindDef(id
)->word(2));
1291 bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id
) const {
1292 if (!IsCooperativeMatrixNVType(id
) && !IsCooperativeMatrixKHRType(id
))
1294 return IsIntScalarType(FindDef(id
)->word(2));
1297 bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id
) const {
1298 if (!IsCooperativeMatrixNVType(id
) && !IsCooperativeMatrixKHRType(id
))
1300 return IsUnsignedIntScalarType(FindDef(id
)->word(2));
1303 // Either a 32 bit 2-component uint vector or a 64 bit uint scalar
1304 bool ValidationState_t::IsUnsigned64BitHandle(uint32_t id
) const {
1305 return ((IsUnsignedIntScalarType(id
) && GetBitWidth(id
) == 64) ||
1306 (IsUnsignedIntVectorType(id
) && GetDimension(id
) == 2 &&
1307 GetBitWidth(id
) == 32));
1310 bool ValidationState_t::IsCooperativeVectorNVType(uint32_t id
) const {
1311 const Instruction
* inst
= FindDef(id
);
1312 return inst
&& inst
->opcode() == spv::Op::OpTypeCooperativeVectorNV
;
1315 bool ValidationState_t::IsFloatCooperativeVectorNVType(uint32_t id
) const {
1316 if (!IsCooperativeVectorNVType(id
)) return false;
1317 return IsFloatScalarType(FindDef(id
)->word(2));
1320 bool ValidationState_t::IsIntCooperativeVectorNVType(uint32_t id
) const {
1321 if (!IsCooperativeVectorNVType(id
)) return false;
1322 return IsIntScalarType(FindDef(id
)->word(2));
1325 bool ValidationState_t::IsUnsignedIntCooperativeVectorNVType(
1326 uint32_t id
) const {
1327 if (!IsCooperativeVectorNVType(id
)) return false;
1328 return IsUnsignedIntScalarType(FindDef(id
)->word(2));
1331 spv_result_t
ValidationState_t::CooperativeMatrixShapesMatch(
1332 const Instruction
* inst
, uint32_t result_type_id
, uint32_t m2
,
1333 bool is_conversion
, bool swap_row_col
) {
1334 const auto m1_type
= FindDef(result_type_id
);
1335 const auto m2_type
= FindDef(m2
);
1337 if (m1_type
->opcode() != m2_type
->opcode()) {
1338 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1339 << "Expected cooperative matrix types";
1342 uint32_t m1_scope_id
= m1_type
->GetOperandAs
<uint32_t>(2);
1343 uint32_t m1_rows_id
= m1_type
->GetOperandAs
<uint32_t>(3);
1344 uint32_t m1_cols_id
= m1_type
->GetOperandAs
<uint32_t>(4);
1346 uint32_t m2_scope_id
= m2_type
->GetOperandAs
<uint32_t>(2);
1347 uint32_t m2_rows_id
= m2_type
->GetOperandAs
<uint32_t>(3);
1348 uint32_t m2_cols_id
= m2_type
->GetOperandAs
<uint32_t>(4);
1351 std::swap(m1_rows_id
, m1_cols_id
);
1354 bool m1_is_int32
= false, m1_is_const_int32
= false, m2_is_int32
= false,
1355 m2_is_const_int32
= false;
1356 uint32_t m1_value
= 0, m2_value
= 0;
1358 std::tie(m1_is_int32
, m1_is_const_int32
, m1_value
) =
1359 EvalInt32IfConst(m1_scope_id
);
1360 std::tie(m2_is_int32
, m2_is_const_int32
, m2_value
) =
1361 EvalInt32IfConst(m2_scope_id
);
1363 if (m1_is_const_int32
&& m2_is_const_int32
&& m1_value
!= m2_value
) {
1364 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1365 << "Expected scopes of Matrix and Result Type to be "
1369 std::tie(m1_is_int32
, m1_is_const_int32
, m1_value
) =
1370 EvalInt32IfConst(m1_rows_id
);
1371 std::tie(m2_is_int32
, m2_is_const_int32
, m2_value
) =
1372 EvalInt32IfConst(m2_rows_id
);
1374 if (m1_is_const_int32
&& m2_is_const_int32
&& m1_value
!= m2_value
) {
1375 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1376 << "Expected rows of Matrix type and Result Type to be "
1377 << (swap_row_col
? "swapped with columns" : "identical");
1380 std::tie(m1_is_int32
, m1_is_const_int32
, m1_value
) =
1381 EvalInt32IfConst(m1_cols_id
);
1382 std::tie(m2_is_int32
, m2_is_const_int32
, m2_value
) =
1383 EvalInt32IfConst(m2_cols_id
);
1385 if (m1_is_const_int32
&& m2_is_const_int32
&& m1_value
!= m2_value
) {
1386 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1387 << "Expected columns of Matrix type and Result Type to be "
1388 << (swap_row_col
? "swapped with rows" : "identical");
1391 if (m1_type
->opcode() == spv::Op::OpTypeCooperativeMatrixKHR
) {
1392 uint32_t m1_use_id
= m1_type
->GetOperandAs
<uint32_t>(5);
1393 uint32_t m2_use_id
= m2_type
->GetOperandAs
<uint32_t>(5);
1394 std::tie(m1_is_int32
, m1_is_const_int32
, m1_value
) =
1395 EvalInt32IfConst(m1_use_id
);
1396 std::tie(m2_is_int32
, m2_is_const_int32
, m2_value
) =
1397 EvalInt32IfConst(m2_use_id
);
1399 if (m1_is_const_int32
&& m2_is_const_int32
&& m1_value
!= m2_value
&&
1400 // CooperativeMatrixConversionsNV allows conversions from Acc->A/B
1402 HasCapability(spv::Capability::CooperativeMatrixConversionsNV
) &&
1404 (uint32_t)spv::CooperativeMatrixUse::MatrixAccumulatorKHR
)) {
1405 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1406 << "Expected Use of Matrix type and Result Type to be "
1414 spv_result_t
ValidationState_t::CooperativeVectorDimensionsMatch(
1415 const Instruction
* inst
, uint32_t v1
, uint32_t v2
) {
1416 const auto v1_type
= FindDef(v1
);
1417 const auto v2_type
= FindDef(v2
);
1419 if (v1_type
->opcode() != v2_type
->opcode()) {
1420 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1421 << "Expected cooperative vector types";
1424 uint32_t v1_components_id
= v1_type
->GetOperandAs
<uint32_t>(2);
1425 uint32_t v2_components_id
= v2_type
->GetOperandAs
<uint32_t>(2);
1427 bool v1_is_int32
= false, v1_is_const_int32
= false, v2_is_int32
= false,
1428 v2_is_const_int32
= false;
1429 uint32_t v1_value
= 0, v2_value
= 0;
1431 std::tie(v1_is_int32
, v1_is_const_int32
, v1_value
) =
1432 EvalInt32IfConst(v1_components_id
);
1433 std::tie(v2_is_int32
, v2_is_const_int32
, v2_value
) =
1434 EvalInt32IfConst(v2_components_id
);
1436 if (v1_is_const_int32
&& v2_is_const_int32
&& v1_value
!= v2_value
) {
1437 return diag(SPV_ERROR_INVALID_DATA
, inst
)
1438 << "Expected number of components to be identical";
1444 uint32_t ValidationState_t::GetOperandTypeId(const Instruction
* inst
,
1445 size_t operand_index
) const {
1446 return GetTypeId(inst
->GetOperandAs
<uint32_t>(operand_index
));
1449 bool ValidationState_t::EvalConstantValUint64(uint32_t id
,
1450 uint64_t* val
) const {
1451 const Instruction
* inst
= FindDef(id
);
1453 assert(0 && "Instruction not found");
1457 if (!IsIntScalarType(inst
->type_id())) return false;
1459 if (inst
->opcode() == spv::Op::OpConstantNull
) {
1461 } else if (inst
->opcode() != spv::Op::OpConstant
) {
1462 // Spec constant values cannot be evaluated so don't consider constant for
1463 // static validation
1465 } else if (inst
->words().size() == 4) {
1466 *val
= inst
->word(3);
1468 assert(inst
->words().size() == 5);
1469 *val
= inst
->word(3);
1470 *val
|= uint64_t(inst
->word(4)) << 32;
1475 bool ValidationState_t::EvalConstantValInt64(uint32_t id
, int64_t* val
) const {
1476 const Instruction
* inst
= FindDef(id
);
1478 assert(0 && "Instruction not found");
1482 if (!IsIntScalarType(inst
->type_id())) return false;
1484 if (inst
->opcode() == spv::Op::OpConstantNull
) {
1486 } else if (inst
->opcode() != spv::Op::OpConstant
) {
1487 // Spec constant values cannot be evaluated so don't consider constant for
1488 // static validation
1490 } else if (inst
->words().size() == 4) {
1491 *val
= int32_t(inst
->word(3));
1493 assert(inst
->words().size() == 5);
1494 const uint32_t lo_word
= inst
->word(3);
1495 const uint32_t hi_word
= inst
->word(4);
1496 *val
= static_cast<int64_t>(uint64_t(lo_word
) | uint64_t(hi_word
) << 32);
1501 std::tuple
<bool, bool, uint32_t> ValidationState_t::EvalInt32IfConst(
1502 uint32_t id
) const {
1503 const Instruction
* const inst
= FindDef(id
);
1505 const uint32_t type
= inst
->type_id();
1507 if (type
== 0 || !IsIntScalarType(type
) || GetBitWidth(type
) != 32) {
1508 return std::make_tuple(false, false, 0);
1511 // Spec constant values cannot be evaluated so don't consider constant for
1512 // the purpose of this method.
1513 if (!spvOpcodeIsConstant(inst
->opcode()) ||
1514 spvOpcodeIsSpecConstant(inst
->opcode())) {
1515 return std::make_tuple(true, false, 0);
1518 if (inst
->opcode() == spv::Op::OpConstantNull
) {
1519 return std::make_tuple(true, true, 0);
1522 assert(inst
->words().size() == 4);
1523 return std::make_tuple(true, true, inst
->word(3));
1526 void ValidationState_t::ComputeFunctionToEntryPointMapping() {
1527 for (const uint32_t entry_point
: entry_points()) {
1528 std::stack
<uint32_t> call_stack
;
1529 std::set
<uint32_t> visited
;
1530 call_stack
.push(entry_point
);
1531 while (!call_stack
.empty()) {
1532 const uint32_t called_func_id
= call_stack
.top();
1534 if (!visited
.insert(called_func_id
).second
) continue;
1536 function_to_entry_points_
[called_func_id
].push_back(entry_point
);
1538 const Function
* called_func
= function(called_func_id
);
1540 // Other checks should error out on this invalid SPIR-V.
1541 for (const uint32_t new_call
: called_func
->function_call_targets()) {
1542 call_stack
.push(new_call
);
1549 void ValidationState_t::ComputeRecursiveEntryPoints() {
1550 for (const Function
& func
: functions()) {
1551 std::stack
<uint32_t> call_stack
;
1552 std::set
<uint32_t> visited
;
1554 for (const uint32_t new_call
: func
.function_call_targets()) {
1555 call_stack
.push(new_call
);
1558 while (!call_stack
.empty()) {
1559 const uint32_t called_func_id
= call_stack
.top();
1562 if (!visited
.insert(called_func_id
).second
) continue;
1564 if (called_func_id
== func
.id()) {
1565 for (const uint32_t entry_point
:
1566 function_to_entry_points_
[called_func_id
])
1567 recursive_entry_points_
.insert(entry_point
);
1571 const Function
* called_func
= function(called_func_id
);
1573 // Other checks should error out on this invalid SPIR-V.
1574 for (const uint32_t new_call
: called_func
->function_call_targets()) {
1575 call_stack
.push(new_call
);
1582 const std::vector
<uint32_t>& ValidationState_t::FunctionEntryPoints(
1583 uint32_t func
) const {
1584 auto iter
= function_to_entry_points_
.find(func
);
1585 if (iter
== function_to_entry_points_
.end()) {
1588 return iter
->second
;
1592 std::set
<uint32_t> ValidationState_t::EntryPointReferences(uint32_t id
) const {
1593 std::set
<uint32_t> referenced_entry_points
;
1594 const auto inst
= FindDef(id
);
1595 if (!inst
) return referenced_entry_points
;
1597 std::vector
<const Instruction
*> stack
;
1598 stack
.push_back(inst
);
1599 while (!stack
.empty()) {
1600 const auto current_inst
= stack
.back();
1603 if (const auto func
= current_inst
->function()) {
1604 // Instruction lives in a function, we can stop searching.
1605 const auto function_entry_points
= FunctionEntryPoints(func
->id());
1606 referenced_entry_points
.insert(function_entry_points
.begin(),
1607 function_entry_points
.end());
1609 // Instruction is in the global scope, keep searching its uses.
1610 for (auto pair
: current_inst
->uses()) {
1611 const auto next_inst
= pair
.first
;
1612 stack
.push_back(next_inst
);
1617 return referenced_entry_points
;
1620 std::string
ValidationState_t::Disassemble(const Instruction
& inst
) const {
1621 const spv_parsed_instruction_t
& c_inst(inst
.c_inst());
1622 return Disassemble(c_inst
.words
, c_inst
.num_words
);
1625 std::string
ValidationState_t::Disassemble(const uint32_t* words
,
1626 uint16_t num_words
) const {
1627 uint32_t disassembly_options
= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER
|
1628 SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES
;
1630 return spvInstructionBinaryToText(context()->target_env
, words
, num_words
,
1631 words_
, num_words_
, disassembly_options
);
1634 bool ValidationState_t::LogicallyMatch(const Instruction
* lhs
,
1635 const Instruction
* rhs
,
1636 bool check_decorations
) {
1637 if (lhs
->opcode() != rhs
->opcode()) {
1641 if (check_decorations
) {
1642 const auto& dec_a
= id_decorations(lhs
->id());
1643 const auto& dec_b
= id_decorations(rhs
->id());
1645 for (const auto& dec
: dec_b
) {
1646 if (std::find(dec_a
.begin(), dec_a
.end(), dec
) == dec_a
.end()) {
1652 if (lhs
->opcode() == spv::Op::OpTypeArray
) {
1653 // Size operands must match.
1654 if (lhs
->GetOperandAs
<uint32_t>(2u) != rhs
->GetOperandAs
<uint32_t>(2u)) {
1658 // Elements must match or logically match.
1659 const auto lhs_ele_id
= lhs
->GetOperandAs
<uint32_t>(1u);
1660 const auto rhs_ele_id
= rhs
->GetOperandAs
<uint32_t>(1u);
1661 if (lhs_ele_id
== rhs_ele_id
) {
1665 const auto lhs_ele
= FindDef(lhs_ele_id
);
1666 const auto rhs_ele
= FindDef(rhs_ele_id
);
1667 if (!lhs_ele
|| !rhs_ele
) {
1670 return LogicallyMatch(lhs_ele
, rhs_ele
, check_decorations
);
1671 } else if (lhs
->opcode() == spv::Op::OpTypeStruct
) {
1672 // Number of elements must match.
1673 if (lhs
->operands().size() != rhs
->operands().size()) {
1677 for (size_t i
= 1u; i
< lhs
->operands().size(); ++i
) {
1678 const auto lhs_ele_id
= lhs
->GetOperandAs
<uint32_t>(i
);
1679 const auto rhs_ele_id
= rhs
->GetOperandAs
<uint32_t>(i
);
1680 // Elements must match or logically match.
1681 if (lhs_ele_id
== rhs_ele_id
) {
1685 const auto lhs_ele
= FindDef(lhs_ele_id
);
1686 const auto rhs_ele
= FindDef(rhs_ele_id
);
1687 if (!lhs_ele
|| !rhs_ele
) {
1691 if (!LogicallyMatch(lhs_ele
, rhs_ele
, check_decorations
)) {
1696 // All checks passed.
1700 // No other opcodes are acceptable at this point. Arrays and structs are
1701 // caught above and if they're elements are not arrays or structs they are
1702 // required to match exactly.
1706 const Instruction
* ValidationState_t::TracePointer(
1707 const Instruction
* inst
) const {
1708 auto base_ptr
= inst
;
1709 while (base_ptr
->opcode() == spv::Op::OpAccessChain
||
1710 base_ptr
->opcode() == spv::Op::OpInBoundsAccessChain
||
1711 base_ptr
->opcode() == spv::Op::OpPtrAccessChain
||
1712 base_ptr
->opcode() == spv::Op::OpInBoundsPtrAccessChain
||
1713 base_ptr
->opcode() == spv::Op::OpCopyObject
) {
1714 base_ptr
= FindDef(base_ptr
->GetOperandAs
<uint32_t>(2u));
1719 bool ValidationState_t::ContainsType(
1720 uint32_t id
, const std::function
<bool(const Instruction
*)>& f
,
1721 bool traverse_all_types
) const {
1722 const auto inst
= FindDef(id
);
1723 if (!inst
) return false;
1725 if (f(inst
)) return true;
1727 switch (inst
->opcode()) {
1728 case spv::Op::OpTypeArray
:
1729 case spv::Op::OpTypeRuntimeArray
:
1730 case spv::Op::OpTypeVector
:
1731 case spv::Op::OpTypeMatrix
:
1732 case spv::Op::OpTypeImage
:
1733 case spv::Op::OpTypeSampledImage
:
1734 case spv::Op::OpTypeCooperativeMatrixNV
:
1735 case spv::Op::OpTypeCooperativeMatrixKHR
:
1736 case spv::Op::OpTypeCooperativeVectorNV
:
1737 return ContainsType(inst
->GetOperandAs
<uint32_t>(1u), f
,
1738 traverse_all_types
);
1739 case spv::Op::OpTypePointer
:
1740 if (IsForwardPointer(id
)) return false;
1741 if (traverse_all_types
) {
1742 return ContainsType(inst
->GetOperandAs
<uint32_t>(2u), f
,
1743 traverse_all_types
);
1746 case spv::Op::OpTypeFunction
:
1747 case spv::Op::OpTypeStruct
:
1748 if (inst
->opcode() == spv::Op::OpTypeFunction
&& !traverse_all_types
) {
1751 for (uint32_t i
= 1; i
< inst
->operands().size(); ++i
) {
1752 if (ContainsType(inst
->GetOperandAs
<uint32_t>(i
), f
,
1753 traverse_all_types
)) {
1765 bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id
, spv::Op type
,
1766 uint32_t width
) const {
1767 if (type
!= spv::Op::OpTypeInt
&& type
!= spv::Op::OpTypeFloat
) return false;
1769 const auto f
= [type
, width
](const Instruction
* inst
) {
1770 if (inst
->opcode() == type
) {
1771 return inst
->GetOperandAs
<uint32_t>(1u) == width
;
1775 return ContainsType(id
, f
);
1778 bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id
) const {
1779 if ((!HasCapability(spv::Capability::Int16
) &&
1780 ContainsSizedIntOrFloatType(id
, spv::Op::OpTypeInt
, 16)) ||
1781 (!HasCapability(spv::Capability::Int8
) &&
1782 ContainsSizedIntOrFloatType(id
, spv::Op::OpTypeInt
, 8)) ||
1783 (!HasCapability(spv::Capability::Float16
) &&
1784 ContainsSizedIntOrFloatType(id
, spv::Op::OpTypeFloat
, 16))) {
1790 bool ValidationState_t::ContainsRuntimeArray(uint32_t id
) const {
1791 const auto f
= [](const Instruction
* inst
) {
1792 return inst
->opcode() == spv::Op::OpTypeRuntimeArray
;
1794 return ContainsType(id
, f
, /* traverse_all_types = */ false);
1797 bool ValidationState_t::ContainsUntypedPointer(uint32_t id
) const {
1798 const auto inst
= FindDef(id
);
1799 if (!inst
) return false;
1800 if (!spvOpcodeGeneratesType(inst
->opcode())) return false;
1801 if (inst
->opcode() == spv::Op::OpTypeUntypedPointerKHR
) return true;
1803 switch (inst
->opcode()) {
1804 case spv::Op::OpTypeArray
:
1805 case spv::Op::OpTypeRuntimeArray
:
1806 case spv::Op::OpTypeVector
:
1807 case spv::Op::OpTypeMatrix
:
1808 case spv::Op::OpTypeImage
:
1809 case spv::Op::OpTypeSampledImage
:
1810 case spv::Op::OpTypeCooperativeMatrixNV
:
1811 return ContainsUntypedPointer(inst
->GetOperandAs
<uint32_t>(1u));
1812 case spv::Op::OpTypePointer
:
1813 if (IsForwardPointer(id
)) return false;
1814 return ContainsUntypedPointer(inst
->GetOperandAs
<uint32_t>(2u));
1815 case spv::Op::OpTypeFunction
:
1816 case spv::Op::OpTypeStruct
: {
1817 for (uint32_t i
= 1; i
< inst
->operands().size(); ++i
) {
1818 if (ContainsUntypedPointer(inst
->GetOperandAs
<uint32_t>(i
)))
1830 bool ValidationState_t::IsValidStorageClass(
1831 spv::StorageClass storage_class
) const {
1832 if (spvIsVulkanEnv(context()->target_env
)) {
1833 switch (storage_class
) {
1834 case spv::StorageClass::UniformConstant
:
1835 case spv::StorageClass::Uniform
:
1836 case spv::StorageClass::StorageBuffer
:
1837 case spv::StorageClass::Input
:
1838 case spv::StorageClass::Output
:
1839 case spv::StorageClass::Image
:
1840 case spv::StorageClass::Workgroup
:
1841 case spv::StorageClass::Private
:
1842 case spv::StorageClass::Function
:
1843 case spv::StorageClass::PushConstant
:
1844 case spv::StorageClass::PhysicalStorageBuffer
:
1845 case spv::StorageClass::RayPayloadKHR
:
1846 case spv::StorageClass::IncomingRayPayloadKHR
:
1847 case spv::StorageClass::HitAttributeKHR
:
1848 case spv::StorageClass::CallableDataKHR
:
1849 case spv::StorageClass::IncomingCallableDataKHR
:
1850 case spv::StorageClass::ShaderRecordBufferKHR
:
1851 case spv::StorageClass::TaskPayloadWorkgroupEXT
:
1852 case spv::StorageClass::HitObjectAttributeNV
:
1853 case spv::StorageClass::TileImageEXT
:
1854 case spv::StorageClass::NodePayloadAMDX
:
1864 #define VUID_WRAP(vuid) "[" #vuid "] "
1866 // Currently no 2 VUID share the same id, so no need for |reference|
1867 std::string
ValidationState_t::VkErrorID(uint32_t id
,
1868 const char* /*reference*/) const {
1869 if (!spvIsVulkanEnv(context_
->target_env
)) {
1873 // This large switch case is only searched when an error has occurred.
1874 // If an id is changed, the old case must be modified or removed. Each string
1875 // here is interpreted as being "implemented"
1877 // Clang format adds spaces between hyphens
1881 return VUID_WRAP(VUID
-BaryCoordKHR
-BaryCoordKHR
-04154);
1883 return VUID_WRAP(VUID
-BaryCoordKHR
-BaryCoordKHR
-04155);
1885 return VUID_WRAP(VUID
-BaryCoordKHR
-BaryCoordKHR
-04156);
1887 return VUID_WRAP(VUID
-BaryCoordNoPerspKHR
-BaryCoordNoPerspKHR
-04160);
1889 return VUID_WRAP(VUID
-BaryCoordNoPerspKHR
-BaryCoordNoPerspKHR
-04161);
1891 return VUID_WRAP(VUID
-BaryCoordNoPerspKHR
-BaryCoordNoPerspKHR
-04162);
1893 return VUID_WRAP(VUID
-BaseInstance
-BaseInstance
-04181);
1895 return VUID_WRAP(VUID
-BaseInstance
-BaseInstance
-04182);
1897 return VUID_WRAP(VUID
-BaseInstance
-BaseInstance
-04183);
1899 return VUID_WRAP(VUID
-BaseVertex
-BaseVertex
-04184);
1901 return VUID_WRAP(VUID
-BaseVertex
-BaseVertex
-04185);
1903 return VUID_WRAP(VUID
-BaseVertex
-BaseVertex
-04186);
1905 return VUID_WRAP(VUID
-ClipDistance
-ClipDistance
-04187);
1907 return VUID_WRAP(VUID
-ClipDistance
-ClipDistance
-04188);
1909 return VUID_WRAP(VUID
-ClipDistance
-ClipDistance
-04189);
1911 return VUID_WRAP(VUID
-ClipDistance
-ClipDistance
-04190);
1913 return VUID_WRAP(VUID
-ClipDistance
-ClipDistance
-04191);
1915 return VUID_WRAP(VUID
-CullDistance
-CullDistance
-04196);
1917 return VUID_WRAP(VUID
-CullDistance
-CullDistance
-04197);
1919 return VUID_WRAP(VUID
-CullDistance
-CullDistance
-04198);
1921 return VUID_WRAP(VUID
-CullDistance
-CullDistance
-04199);
1923 return VUID_WRAP(VUID
-CullDistance
-CullDistance
-04200);
1925 return VUID_WRAP(VUID
-CullMaskKHR
-CullMaskKHR
-06735); // Execution Model
1927 return VUID_WRAP(VUID
-CullMaskKHR
-CullMaskKHR
-06736); // input storage
1929 return VUID_WRAP(VUID
-CullMaskKHR
-CullMaskKHR
-06737); // 32 int scalar
1931 return VUID_WRAP(VUID
-DeviceIndex
-DeviceIndex
-04205);
1933 return VUID_WRAP(VUID
-DeviceIndex
-DeviceIndex
-04206);
1935 return VUID_WRAP(VUID
-DrawIndex
-DrawIndex
-04207);
1937 return VUID_WRAP(VUID
-DrawIndex
-DrawIndex
-04208);
1939 return VUID_WRAP(VUID
-DrawIndex
-DrawIndex
-04209);
1941 return VUID_WRAP(VUID
-FragCoord
-FragCoord
-04210);
1943 return VUID_WRAP(VUID
-FragCoord
-FragCoord
-04211);
1945 return VUID_WRAP(VUID
-FragCoord
-FragCoord
-04212);
1947 return VUID_WRAP(VUID
-FragDepth
-FragDepth
-04213);
1949 return VUID_WRAP(VUID
-FragDepth
-FragDepth
-04214);
1951 return VUID_WRAP(VUID
-FragDepth
-FragDepth
-04215);
1953 return VUID_WRAP(VUID
-FragDepth
-FragDepth
-04216);
1955 return VUID_WRAP(VUID
-FragInvocationCountEXT
-FragInvocationCountEXT
-04217);
1957 return VUID_WRAP(VUID
-FragInvocationCountEXT
-FragInvocationCountEXT
-04218);
1959 return VUID_WRAP(VUID
-FragInvocationCountEXT
-FragInvocationCountEXT
-04219);
1961 return VUID_WRAP(VUID
-FragSizeEXT
-FragSizeEXT
-04220);
1963 return VUID_WRAP(VUID
-FragSizeEXT
-FragSizeEXT
-04221);
1965 return VUID_WRAP(VUID
-FragSizeEXT
-FragSizeEXT
-04222);
1967 return VUID_WRAP(VUID
-FragStencilRefEXT
-FragStencilRefEXT
-04223);
1969 return VUID_WRAP(VUID
-FragStencilRefEXT
-FragStencilRefEXT
-04224);
1971 return VUID_WRAP(VUID
-FragStencilRefEXT
-FragStencilRefEXT
-04225);
1973 return VUID_WRAP(VUID
-FrontFacing
-FrontFacing
-04229);
1975 return VUID_WRAP(VUID
-FrontFacing
-FrontFacing
-04230);
1977 return VUID_WRAP(VUID
-FrontFacing
-FrontFacing
-04231);
1979 return VUID_WRAP(VUID
-FullyCoveredEXT
-FullyCoveredEXT
-04232);
1981 return VUID_WRAP(VUID
-FullyCoveredEXT
-FullyCoveredEXT
-04233);
1983 return VUID_WRAP(VUID
-FullyCoveredEXT
-FullyCoveredEXT
-04234);
1985 return VUID_WRAP(VUID
-GlobalInvocationId
-GlobalInvocationId
-04236);
1987 return VUID_WRAP(VUID
-GlobalInvocationId
-GlobalInvocationId
-04237);
1989 return VUID_WRAP(VUID
-GlobalInvocationId
-GlobalInvocationId
-04238);
1991 return VUID_WRAP(VUID
-HelperInvocation
-HelperInvocation
-04239);
1993 return VUID_WRAP(VUID
-HelperInvocation
-HelperInvocation
-04240);
1995 return VUID_WRAP(VUID
-HelperInvocation
-HelperInvocation
-04241);
1997 return VUID_WRAP(VUID
-HitKindKHR
-HitKindKHR
-04242);
1999 return VUID_WRAP(VUID
-HitKindKHR
-HitKindKHR
-04243);
2001 return VUID_WRAP(VUID
-HitKindKHR
-HitKindKHR
-04244);
2003 return VUID_WRAP(VUID
-HitTNV
-HitTNV
-04245);
2005 return VUID_WRAP(VUID
-HitTNV
-HitTNV
-04246);
2007 return VUID_WRAP(VUID
-HitTNV
-HitTNV
-04247);
2009 return VUID_WRAP(VUID
-IncomingRayFlagsKHR
-IncomingRayFlagsKHR
-04248);
2011 return VUID_WRAP(VUID
-IncomingRayFlagsKHR
-IncomingRayFlagsKHR
-04249);
2013 return VUID_WRAP(VUID
-IncomingRayFlagsKHR
-IncomingRayFlagsKHR
-04250);
2015 return VUID_WRAP(VUID
-InstanceCustomIndexKHR
-InstanceCustomIndexKHR
-04251);
2017 return VUID_WRAP(VUID
-InstanceCustomIndexKHR
-InstanceCustomIndexKHR
-04252);
2019 return VUID_WRAP(VUID
-InstanceCustomIndexKHR
-InstanceCustomIndexKHR
-04253);
2021 return VUID_WRAP(VUID
-InstanceId
-InstanceId
-04254);
2023 return VUID_WRAP(VUID
-InstanceId
-InstanceId
-04255);
2025 return VUID_WRAP(VUID
-InstanceId
-InstanceId
-04256);
2027 return VUID_WRAP(VUID
-InvocationId
-InvocationId
-04257);
2029 return VUID_WRAP(VUID
-InvocationId
-InvocationId
-04258);
2031 return VUID_WRAP(VUID
-InvocationId
-InvocationId
-04259);
2033 return VUID_WRAP(VUID
-InstanceIndex
-InstanceIndex
-04263);
2035 return VUID_WRAP(VUID
-InstanceIndex
-InstanceIndex
-04264);
2037 return VUID_WRAP(VUID
-InstanceIndex
-InstanceIndex
-04265);
2039 return VUID_WRAP(VUID
-LaunchIdKHR
-LaunchIdKHR
-04266);
2041 return VUID_WRAP(VUID
-LaunchIdKHR
-LaunchIdKHR
-04267);
2043 return VUID_WRAP(VUID
-LaunchIdKHR
-LaunchIdKHR
-04268);
2045 return VUID_WRAP(VUID
-LaunchSizeKHR
-LaunchSizeKHR
-04269);
2047 return VUID_WRAP(VUID
-LaunchSizeKHR
-LaunchSizeKHR
-04270);
2049 return VUID_WRAP(VUID
-LaunchSizeKHR
-LaunchSizeKHR
-04271);
2051 return VUID_WRAP(VUID
-Layer
-Layer
-04272);
2053 return VUID_WRAP(VUID
-Layer
-Layer
-04273);
2055 return VUID_WRAP(VUID
-Layer
-Layer
-04274);
2057 return VUID_WRAP(VUID
-Layer
-Layer
-04275);
2059 return VUID_WRAP(VUID
-Layer
-Layer
-04276);
2061 return VUID_WRAP(VUID
-LocalInvocationId
-LocalInvocationId
-04281);
2063 return VUID_WRAP(VUID
-LocalInvocationId
-LocalInvocationId
-04282);
2065 return VUID_WRAP(VUID
-LocalInvocationId
-LocalInvocationId
-04283);
2067 return VUID_WRAP(VUID
-NumSubgroups
-NumSubgroups
-04293);
2069 return VUID_WRAP(VUID
-NumSubgroups
-NumSubgroups
-04294);
2071 return VUID_WRAP(VUID
-NumSubgroups
-NumSubgroups
-04295);
2073 return VUID_WRAP(VUID
-NumWorkgroups
-NumWorkgroups
-04296);
2075 return VUID_WRAP(VUID
-NumWorkgroups
-NumWorkgroups
-04297);
2077 return VUID_WRAP(VUID
-NumWorkgroups
-NumWorkgroups
-04298);
2079 return VUID_WRAP(VUID
-ObjectRayDirectionKHR
-ObjectRayDirectionKHR
-04299);
2081 return VUID_WRAP(VUID
-ObjectRayDirectionKHR
-ObjectRayDirectionKHR
-04300);
2083 return VUID_WRAP(VUID
-ObjectRayDirectionKHR
-ObjectRayDirectionKHR
-04301);
2085 return VUID_WRAP(VUID
-ObjectRayOriginKHR
-ObjectRayOriginKHR
-04302);
2087 return VUID_WRAP(VUID
-ObjectRayOriginKHR
-ObjectRayOriginKHR
-04303);
2089 return VUID_WRAP(VUID
-ObjectRayOriginKHR
-ObjectRayOriginKHR
-04304);
2091 return VUID_WRAP(VUID
-ObjectToWorldKHR
-ObjectToWorldKHR
-04305);
2093 return VUID_WRAP(VUID
-ObjectToWorldKHR
-ObjectToWorldKHR
-04306);
2095 return VUID_WRAP(VUID
-ObjectToWorldKHR
-ObjectToWorldKHR
-04307);
2097 return VUID_WRAP(VUID
-PatchVertices
-PatchVertices
-04308);
2099 return VUID_WRAP(VUID
-PatchVertices
-PatchVertices
-04309);
2101 return VUID_WRAP(VUID
-PatchVertices
-PatchVertices
-04310);
2103 return VUID_WRAP(VUID
-PointCoord
-PointCoord
-04311);
2105 return VUID_WRAP(VUID
-PointCoord
-PointCoord
-04312);
2107 return VUID_WRAP(VUID
-PointCoord
-PointCoord
-04313);
2109 return VUID_WRAP(VUID
-PointSize
-PointSize
-04314);
2111 return VUID_WRAP(VUID
-PointSize
-PointSize
-04315);
2113 return VUID_WRAP(VUID
-PointSize
-PointSize
-04316);
2115 return VUID_WRAP(VUID
-PointSize
-PointSize
-04317);
2117 return VUID_WRAP(VUID
-Position
-Position
-04318);
2119 return VUID_WRAP(VUID
-Position
-Position
-04319);
2121 return VUID_WRAP(VUID
-Position
-Position
-04320);
2123 return VUID_WRAP(VUID
-Position
-Position
-04321);
2125 return VUID_WRAP(VUID
-PrimitiveId
-PrimitiveId
-04330);
2127 return VUID_WRAP(VUID
-PrimitiveId
-PrimitiveId
-04334);
2129 return VUID_WRAP(VUID
-PrimitiveId
-PrimitiveId
-04336);
2131 return VUID_WRAP(VUID
-PrimitiveId
-PrimitiveId
-04337);
2133 return VUID_WRAP(VUID
-RayGeometryIndexKHR
-RayGeometryIndexKHR
-04345);
2135 return VUID_WRAP(VUID
-RayGeometryIndexKHR
-RayGeometryIndexKHR
-04346);
2137 return VUID_WRAP(VUID
-RayGeometryIndexKHR
-RayGeometryIndexKHR
-04347);
2139 return VUID_WRAP(VUID
-RayTmaxKHR
-RayTmaxKHR
-04348);
2141 return VUID_WRAP(VUID
-RayTmaxKHR
-RayTmaxKHR
-04349);
2143 return VUID_WRAP(VUID
-RayTmaxKHR
-RayTmaxKHR
-04350);
2145 return VUID_WRAP(VUID
-RayTminKHR
-RayTminKHR
-04351);
2147 return VUID_WRAP(VUID
-RayTminKHR
-RayTminKHR
-04352);
2149 return VUID_WRAP(VUID
-RayTminKHR
-RayTminKHR
-04353);
2151 return VUID_WRAP(VUID
-SampleId
-SampleId
-04354);
2153 return VUID_WRAP(VUID
-SampleId
-SampleId
-04355);
2155 return VUID_WRAP(VUID
-SampleId
-SampleId
-04356);
2157 return VUID_WRAP(VUID
-SampleMask
-SampleMask
-04357);
2159 return VUID_WRAP(VUID
-SampleMask
-SampleMask
-04358);
2161 return VUID_WRAP(VUID
-SampleMask
-SampleMask
-04359);
2163 return VUID_WRAP(VUID
-SamplePosition
-SamplePosition
-04360);
2165 return VUID_WRAP(VUID
-SamplePosition
-SamplePosition
-04361);
2167 return VUID_WRAP(VUID
-SamplePosition
-SamplePosition
-04362);
2169 return VUID_WRAP(VUID
-SubgroupId
-SubgroupId
-04367);
2171 return VUID_WRAP(VUID
-SubgroupId
-SubgroupId
-04368);
2173 return VUID_WRAP(VUID
-SubgroupId
-SubgroupId
-04369);
2175 return VUID_WRAP(VUID
-SubgroupEqMask
-SubgroupEqMask
-04370);
2177 return VUID_WRAP(VUID
-SubgroupEqMask
-SubgroupEqMask
-04371);
2179 return VUID_WRAP(VUID
-SubgroupGeMask
-SubgroupGeMask
-04372);
2181 return VUID_WRAP(VUID
-SubgroupGeMask
-SubgroupGeMask
-04373);
2183 return VUID_WRAP(VUID
-SubgroupGtMask
-SubgroupGtMask
-04374);
2185 return VUID_WRAP(VUID
-SubgroupGtMask
-SubgroupGtMask
-04375);
2187 return VUID_WRAP(VUID
-SubgroupLeMask
-SubgroupLeMask
-04376);
2189 return VUID_WRAP(VUID
-SubgroupLeMask
-SubgroupLeMask
-04377);
2191 return VUID_WRAP(VUID
-SubgroupLtMask
-SubgroupLtMask
-04378);
2193 return VUID_WRAP(VUID
-SubgroupLtMask
-SubgroupLtMask
-04379);
2195 return VUID_WRAP(VUID
-SubgroupLocalInvocationId
-SubgroupLocalInvocationId
-04380);
2197 return VUID_WRAP(VUID
-SubgroupLocalInvocationId
-SubgroupLocalInvocationId
-04381);
2199 return VUID_WRAP(VUID
-SubgroupSize
-SubgroupSize
-04382);
2201 return VUID_WRAP(VUID
-SubgroupSize
-SubgroupSize
-04383);
2203 return VUID_WRAP(VUID
-TessCoord
-TessCoord
-04387);
2205 return VUID_WRAP(VUID
-TessCoord
-TessCoord
-04388);
2207 return VUID_WRAP(VUID
-TessCoord
-TessCoord
-04389);
2209 return VUID_WRAP(VUID
-TessLevelOuter
-TessLevelOuter
-04390);
2211 return VUID_WRAP(VUID
-TessLevelOuter
-TessLevelOuter
-04391);
2213 return VUID_WRAP(VUID
-TessLevelOuter
-TessLevelOuter
-04392);
2215 return VUID_WRAP(VUID
-TessLevelOuter
-TessLevelOuter
-04393);
2217 return VUID_WRAP(VUID
-TessLevelInner
-TessLevelInner
-04394);
2219 return VUID_WRAP(VUID
-TessLevelInner
-TessLevelInner
-04395);
2221 return VUID_WRAP(VUID
-TessLevelInner
-TessLevelInner
-04396);
2223 return VUID_WRAP(VUID
-TessLevelInner
-TessLevelInner
-04397);
2225 return VUID_WRAP(VUID
-VertexIndex
-VertexIndex
-04398);
2227 return VUID_WRAP(VUID
-VertexIndex
-VertexIndex
-04399);
2229 return VUID_WRAP(VUID
-VertexIndex
-VertexIndex
-04400);
2231 return VUID_WRAP(VUID
-ViewIndex
-ViewIndex
-04401);
2233 return VUID_WRAP(VUID
-ViewIndex
-ViewIndex
-04402);
2235 return VUID_WRAP(VUID
-ViewIndex
-ViewIndex
-04403);
2237 return VUID_WRAP(VUID
-ViewportIndex
-ViewportIndex
-04404);
2239 return VUID_WRAP(VUID
-ViewportIndex
-ViewportIndex
-04405);
2241 return VUID_WRAP(VUID
-ViewportIndex
-ViewportIndex
-04406);
2243 return VUID_WRAP(VUID
-ViewportIndex
-ViewportIndex
-04407);
2245 return VUID_WRAP(VUID
-ViewportIndex
-ViewportIndex
-04408);
2247 return VUID_WRAP(VUID
-WorkgroupId
-WorkgroupId
-04422);
2249 return VUID_WRAP(VUID
-WorkgroupId
-WorkgroupId
-04423);
2251 return VUID_WRAP(VUID
-WorkgroupId
-WorkgroupId
-04424);
2253 return VUID_WRAP(VUID
-WorkgroupSize
-WorkgroupSize
-04425);
2255 return VUID_WRAP(VUID
-WorkgroupSize
-WorkgroupSize
-04426);
2257 return VUID_WRAP(VUID
-WorkgroupSize
-WorkgroupSize
-04427);
2259 return VUID_WRAP(VUID
-WorldRayDirectionKHR
-WorldRayDirectionKHR
-04428);
2261 return VUID_WRAP(VUID
-WorldRayDirectionKHR
-WorldRayDirectionKHR
-04429);
2263 return VUID_WRAP(VUID
-WorldRayDirectionKHR
-WorldRayDirectionKHR
-04430);
2265 return VUID_WRAP(VUID
-WorldRayOriginKHR
-WorldRayOriginKHR
-04431);
2267 return VUID_WRAP(VUID
-WorldRayOriginKHR
-WorldRayOriginKHR
-04432);
2269 return VUID_WRAP(VUID
-WorldRayOriginKHR
-WorldRayOriginKHR
-04433);
2271 return VUID_WRAP(VUID
-WorldToObjectKHR
-WorldToObjectKHR
-04434);
2273 return VUID_WRAP(VUID
-WorldToObjectKHR
-WorldToObjectKHR
-04435);
2275 return VUID_WRAP(VUID
-WorldToObjectKHR
-WorldToObjectKHR
-04436);
2277 return VUID_WRAP(VUID
-PrimitiveShadingRateKHR
-PrimitiveShadingRateKHR
-04484);
2279 return VUID_WRAP(VUID
-PrimitiveShadingRateKHR
-PrimitiveShadingRateKHR
-04485);
2281 return VUID_WRAP(VUID
-PrimitiveShadingRateKHR
-PrimitiveShadingRateKHR
-04486);
2283 return VUID_WRAP(VUID
-ShadingRateKHR
-ShadingRateKHR
-04490);
2285 return VUID_WRAP(VUID
-ShadingRateKHR
-ShadingRateKHR
-04491);
2287 return VUID_WRAP(VUID
-ShadingRateKHR
-ShadingRateKHR
-04492);
2289 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04633);
2291 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04634);
2293 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04635);
2295 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04636);
2297 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04637);
2299 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04638);
2301 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-07321);
2303 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04640);
2305 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04641);
2307 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04642);
2309 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04643);
2311 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04644);
2313 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04645);
2315 return VUID_WRAP(VUID
-StandaloneSpirv
-OpControlBarrier
-04650);
2317 return VUID_WRAP(VUID
-StandaloneSpirv
-OpVariable
-04651);
2319 return VUID_WRAP(VUID
-StandaloneSpirv
-OpReadClockKHR
-04652);
2321 return VUID_WRAP(VUID
-StandaloneSpirv
-OriginLowerLeft
-04653);
2323 return VUID_WRAP(VUID
-StandaloneSpirv
-PixelCenterInteger
-04654);
2325 return VUID_WRAP(VUID
-StandaloneSpirv
-UniformConstant
-04655);
2327 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeImage
-04656);
2329 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeImage
-04657);
2331 return VUID_WRAP(VUID
-StandaloneSpirv
-OpImageTexelPointer
-04658);
2333 return VUID_WRAP(VUID
-StandaloneSpirv
-OpImageQuerySizeLod
-04659);
2335 return VUID_WRAP(VUID
-StandaloneSpirv
-OpImageGather
-04664);
2337 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04667);
2339 return VUID_WRAP(VUID
-StandaloneSpirv
-GLSLShared
-04669);
2341 return VUID_WRAP(VUID
-StandaloneSpirv
-Flat
-04670);
2343 return VUID_WRAP(VUID
-StandaloneSpirv
-FPRoundingMode
-04675);
2345 return VUID_WRAP(VUID
-StandaloneSpirv
-Invariant
-04677);
2347 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeRuntimeArray
-04680);
2349 return VUID_WRAP(VUID
-StandaloneSpirv
-OpControlBarrier
-04682);
2351 return VUID_WRAP(VUID
-StandaloneSpirv
-LocalSize
-06426); // formally 04683
2353 return VUID_WRAP(VUID
-StandaloneSpirv
-OpGroupNonUniformBallotBitCount
-04685);
2355 return VUID_WRAP(VUID
-StandaloneSpirv
-None
-04686);
2357 return VUID_WRAP(VUID
-StandaloneSpirv
-RayPayloadKHR
-04698);
2359 return VUID_WRAP(VUID
-StandaloneSpirv
-IncomingRayPayloadKHR
-04699);
2361 return VUID_WRAP(VUID
-StandaloneSpirv
-IncomingRayPayloadKHR
-04700);
2363 return VUID_WRAP(VUID
-StandaloneSpirv
-HitAttributeKHR
-04701);
2365 return VUID_WRAP(VUID
-StandaloneSpirv
-HitAttributeKHR
-04702);
2367 return VUID_WRAP(VUID
-StandaloneSpirv
-HitAttributeKHR
-04703);
2369 return VUID_WRAP(VUID
-StandaloneSpirv
-CallableDataKHR
-04704);
2371 return VUID_WRAP(VUID
-StandaloneSpirv
-IncomingCallableDataKHR
-04705);
2373 return VUID_WRAP(VUID
-StandaloneSpirv
-IncomingCallableDataKHR
-04706);
2375 return VUID_WRAP(VUID
-StandaloneSpirv
-ShaderRecordBufferKHR
-07119);
2377 return VUID_WRAP(VUID
-StandaloneSpirv
-PhysicalStorageBuffer64
-04708);
2379 return VUID_WRAP(VUID
-StandaloneSpirv
-PhysicalStorageBuffer64
-04710);
2381 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeForwardPointer
-04711);
2383 return VUID_WRAP(VUID
-StandaloneSpirv
-OpAtomicStore
-04730);
2385 return VUID_WRAP(VUID
-StandaloneSpirv
-OpAtomicLoad
-04731);
2387 return VUID_WRAP(VUID
-StandaloneSpirv
-OpMemoryBarrier
-04732);
2389 return VUID_WRAP(VUID
-StandaloneSpirv
-OpMemoryBarrier
-04733);
2391 return VUID_WRAP(VUID
-StandaloneSpirv
-OpVariable
-04734);
2393 return VUID_WRAP(VUID
-StandaloneSpirv
-Flat
-04744);
2395 return VUID_WRAP(VUID
-StandaloneSpirv
-OpImage
-04777);
2397 return VUID_WRAP(VUID
-StandaloneSpirv
-Result
-04780);
2399 return VUID_WRAP(VUID
-StandaloneSpirv
-Base
-04781);
2401 return VUID_WRAP(VUID
-StandaloneSpirv
-Location
-04915);
2403 return VUID_WRAP(VUID
-StandaloneSpirv
-Location
-04916);
2405 return VUID_WRAP(VUID
-StandaloneSpirv
-Location
-04917);
2407 return VUID_WRAP(VUID
-StandaloneSpirv
-Location
-04918);
2409 return VUID_WRAP(VUID
-StandaloneSpirv
-Location
-04919);
2411 return VUID_WRAP(VUID
-StandaloneSpirv
-Component
-04920);
2413 return VUID_WRAP(VUID
-StandaloneSpirv
-Component
-04921);
2415 return VUID_WRAP(VUID
-StandaloneSpirv
-Component
-04922);
2417 return VUID_WRAP(VUID
-StandaloneSpirv
-Component
-04923);
2419 return VUID_WRAP(VUID
-StandaloneSpirv
-Component
-04924);
2421 return VUID_WRAP(VUID
-StandaloneSpirv
-Flat
-06201);
2423 return VUID_WRAP(VUID
-StandaloneSpirv
-Flat
-06202);
2425 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeImage
-06214);
2427 return VUID_WRAP(VUID
-StandaloneSpirv
-DescriptorSet
-06491);
2429 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeSampledImage
-06671);
2431 return VUID_WRAP(VUID
-StandaloneSpirv
-Location
-06672);
2433 return VUID_WRAP(VUID
-StandaloneSpirv
-OpVariable
-06673);
2435 return VUID_WRAP(VUID
-StandaloneSpirv
-OpEntryPoint
-06674);
2437 return VUID_WRAP(VUID
-StandaloneSpirv
-PushConstant
-06675);
2439 return VUID_WRAP(VUID
-StandaloneSpirv
-Uniform
-06676);
2441 return VUID_WRAP(VUID
-StandaloneSpirv
-UniformConstant
-06677);
2443 return VUID_WRAP(VUID
-StandaloneSpirv
-InputAttachmentIndex
-06678);
2445 return VUID_WRAP(VUID
-StandaloneSpirv
-PerVertexKHR
-06777);
2447 return VUID_WRAP(VUID
-StandaloneSpirv
-Input
-06778);
2449 return VUID_WRAP(VUID
-StandaloneSpirv
-Uniform
-06807);
2451 return VUID_WRAP(VUID
-StandaloneSpirv
-PushConstant
-06808);
2453 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeImage
-06924);
2455 return VUID_WRAP(VUID
-StandaloneSpirv
-Uniform
-06925);
2457 return VUID_WRAP(VUID
-CullPrimitiveEXT
-CullPrimitiveEXT
-07034);
2459 return VUID_WRAP(VUID
-CullPrimitiveEXT
-CullPrimitiveEXT
-07035);
2461 return VUID_WRAP(VUID
-CullPrimitiveEXT
-CullPrimitiveEXT
-07036);
2463 return VUID_WRAP(VUID
-CullPrimitiveEXT
-CullPrimitiveEXT
-07038);
2465 return VUID_WRAP(VUID
-Layer
-Layer
-07039);
2467 return VUID_WRAP(VUID
-PrimitiveId
-PrimitiveId
-07040);
2469 return VUID_WRAP(VUID
-PrimitivePointIndicesEXT
-PrimitivePointIndicesEXT
-07041);
2471 return VUID_WRAP(VUID
-PrimitivePointIndicesEXT
-PrimitivePointIndicesEXT
-07042);
2473 return VUID_WRAP(VUID
-PrimitivePointIndicesEXT
-PrimitivePointIndicesEXT
-07043);
2475 return VUID_WRAP(VUID
-PrimitivePointIndicesEXT
-PrimitivePointIndicesEXT
-07044);
2477 return VUID_WRAP(VUID
-PrimitivePointIndicesEXT
-PrimitivePointIndicesEXT
-07046);
2479 return VUID_WRAP(VUID
-PrimitiveLineIndicesEXT
-PrimitiveLineIndicesEXT
-07047);
2481 return VUID_WRAP(VUID
-PrimitiveLineIndicesEXT
-PrimitiveLineIndicesEXT
-07048);
2483 return VUID_WRAP(VUID
-PrimitiveLineIndicesEXT
-PrimitiveLineIndicesEXT
-07049);
2485 return VUID_WRAP(VUID
-PrimitiveLineIndicesEXT
-PrimitiveLineIndicesEXT
-07050);
2487 return VUID_WRAP(VUID
-PrimitiveLineIndicesEXT
-PrimitiveLineIndicesEXT
-07052);
2489 return VUID_WRAP(VUID
-PrimitiveTriangleIndicesEXT
-PrimitiveTriangleIndicesEXT
-07053);
2491 return VUID_WRAP(VUID
-PrimitiveTriangleIndicesEXT
-PrimitiveTriangleIndicesEXT
-07054);
2493 return VUID_WRAP(VUID
-PrimitiveTriangleIndicesEXT
-PrimitiveTriangleIndicesEXT
-07055);
2495 return VUID_WRAP(VUID
-PrimitiveTriangleIndicesEXT
-PrimitiveTriangleIndicesEXT
-07056);
2497 return VUID_WRAP(VUID
-PrimitiveTriangleIndicesEXT
-PrimitiveTriangleIndicesEXT
-07058);
2499 return VUID_WRAP(VUID
-PrimitiveShadingRateKHR
-PrimitiveShadingRateKHR
-07059);
2501 return VUID_WRAP(VUID
-ViewportIndex
-ViewportIndex
-07060);
2503 return VUID_WRAP(VUID
-StandaloneSpirv
-MeshEXT
-07102);
2505 return VUID_WRAP(VUID
-StandaloneSpirv
-Input
-07290);
2507 return VUID_WRAP(VUID
-StandaloneSpirv
-ExecutionModel
-07320);
2509 return VUID_WRAP(VUID
-StandaloneSpirv
-MeshEXT
-07330);
2511 return VUID_WRAP(VUID
-StandaloneSpirv
-MeshEXT
-07331);
2513 return VUID_WRAP(VUID
-StandaloneSpirv
-Base
-07650);
2515 return VUID_WRAP(VUID
-StandaloneSpirv
-Base
-07651);
2517 return VUID_WRAP(VUID
-StandaloneSpirv
-Base
-07652);
2519 return VUID_WRAP(VUID
-StandaloneSpirv
-Component
-07703);
2521 return VUID_WRAP(VUID
-StandaloneSpirv
-SubgroupVoteKHR
-07951);
2523 return VUID_WRAP(VUID
-StandaloneSpirv
-OpEntryPoint
-08721);
2525 return VUID_WRAP(VUID
-StandaloneSpirv
-OpEntryPoint
-08722);
2527 return VUID_WRAP(VUID
-StandaloneSpirv
-Pointer
-08973);
2529 return VUID_WRAP(VUID
-StandaloneSpirv
-OpTypeImage
-09638);
2531 return VUID_WRAP(VUID
-StandaloneSpirv
-OpEntryPoint
-09658);
2533 return VUID_WRAP(VUID
-StandaloneSpirv
-OpEntryPoint
-09659);
2535 // This use to be a standalone, but maintenance8 will set allow_offset_texture_operand now
2536 return VUID_WRAP(VUID
-RuntimeSpirv
-Offset
-10213);
2538 return ""; // unknown id
2544 } // namespace spvtools