Explorar o código

Updated spirv-tools.

Бранимир Караџић %!s(int64=2) %!d(string=hai) anos
pai
achega
14ebd15e2d
Modificáronse 27 ficheiros con 1922 adicións e 1095 borrados
  1. 1 1
      3rdparty/spirv-tools/include/generated/build-version.inc
  2. 294 290
      3rdparty/spirv-tools/include/generated/core.insts-unified1.inc
  3. 6 0
      3rdparty/spirv-tools/include/generated/enum_string_mapping.inc
  4. 3 0
      3rdparty/spirv-tools/include/generated/extension_enum.inc
  5. 410 382
      3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc
  6. 5 0
      3rdparty/spirv-tools/include/spirv-tools/libspirv.h
  7. 9 8
      3rdparty/spirv-tools/include/spirv-tools/linker.hpp
  8. 5 0
      3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp
  9. 10 6
      3rdparty/spirv-tools/source/assembly_grammar.cpp
  10. 10 5
      3rdparty/spirv-tools/source/link/linker.cpp
  11. 19 45
      3rdparty/spirv-tools/source/operand.cpp
  12. 8 3
      3rdparty/spirv-tools/source/opt/decoration_manager.cpp
  13. 4 3
      3rdparty/spirv-tools/source/opt/decoration_manager.h
  14. 408 208
      3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp
  15. 44 0
      3rdparty/spirv-tools/source/opt/optimizer.cpp
  16. 1 0
      3rdparty/spirv-tools/source/opt/passes.h
  17. 46 0
      3rdparty/spirv-tools/source/opt/switch_descriptorset_pass.cpp
  18. 52 0
      3rdparty/spirv-tools/source/opt/switch_descriptorset_pass.h
  19. 306 101
      3rdparty/spirv-tools/source/opt/trim_capabilities_pass.cpp
  20. 51 11
      3rdparty/spirv-tools/source/opt/trim_capabilities_pass.h
  21. 1 1
      3rdparty/spirv-tools/source/print.cpp
  22. 2 0
      3rdparty/spirv-tools/source/val/validate.cpp
  23. 8 0
      3rdparty/spirv-tools/source/val/validate.h
  24. 157 1
      3rdparty/spirv-tools/source/val/validate_image.cpp
  25. 2 0
      3rdparty/spirv-tools/source/val/validate_memory.cpp
  26. 42 30
      3rdparty/spirv-tools/source/val/validation_state.cpp
  27. 18 0
      3rdparty/spirv-tools/source/val/validation_state.h

+ 1 - 1
3rdparty/spirv-tools/include/generated/build-version.inc

@@ -1 +1 @@
-"v2023.4", "SPIRV-Tools v2023.4 v2022.4-291-ga913df4a"
+"v2023.4", "SPIRV-Tools v2023.4 v2022.4-324-gfaa88377"

+ 294 - 290
3rdparty/spirv-tools/include/generated/core.insts-unified1.inc

@@ -61,6 +61,7 @@ static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHRRayQue
 static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader};
 static const spv::Capability pygen_variable_caps_ShaderBitInstructions[] = {spv::Capability::Shader, spv::Capability::BitInstructions};
 static const spv::Capability pygen_variable_caps_ShaderClockKHR[] = {spv::Capability::ShaderClockKHR};
+static const spv::Capability pygen_variable_caps_ShaderEnqueueAMDX[] = {spv::Capability::ShaderEnqueueAMDX};
 static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNV[] = {spv::Capability::ShaderInvocationReorderNV};
 static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV[] = {spv::Capability::ShaderInvocationReorderNV, spv::Capability::RayTracingMotionBlurNV};
 static const spv::Capability pygen_variable_caps_SparseResidency[] = {spv::Capability::SparseResidency};
@@ -116,300 +117,300 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footpri
 static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned};
 
 static const spv_opcode_desc_t kOpcodeTableEntries[] = {
-  {"Nop", spv::Op::OpNop, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Undef", spv::Op::OpUndef, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SourceContinued", spv::Op::OpSourceContinued, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Source", spv::Op::OpSource, 0, nullptr, 4, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SourceExtension", spv::Op::OpSourceExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Name", spv::Op::OpName, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MemberName", spv::Op::OpMemberName, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"String", spv::Op::OpString, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Line", spv::Op::OpLine, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Extension", spv::Op::OpExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ExtInstImport", spv::Op::OpExtInstImport, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ExtInst", spv::Op::OpExtInst, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MemoryModel", spv::Op::OpMemoryModel, 0, nullptr, 2, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, SPV_OPERAND_TYPE_MEMORY_MODEL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EntryPoint", spv::Op::OpEntryPoint, 0, nullptr, 4, {SPV_OPERAND_TYPE_EXECUTION_MODEL, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ExecutionMode", spv::Op::OpExecutionMode, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Capability", spv::Op::OpCapability, 0, nullptr, 1, {SPV_OPERAND_TYPE_CAPABILITY}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeVoid", spv::Op::OpTypeVoid, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeBool", spv::Op::OpTypeBool, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeInt", spv::Op::OpTypeInt, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeFloat", spv::Op::OpTypeFloat, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeVector", spv::Op::OpTypeVector, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeMatrix", spv::Op::OpTypeMatrix, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeImage", spv::Op::OpTypeImage, 0, nullptr, 9, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeSampler", spv::Op::OpTypeSampler, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeSampledImage", spv::Op::OpTypeSampledImage, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeArray", spv::Op::OpTypeArray, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeRuntimeArray", spv::Op::OpTypeRuntimeArray, 1, pygen_variable_caps_Shader, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeStruct", spv::Op::OpTypeStruct, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeOpaque", spv::Op::OpTypeOpaque, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypePointer", spv::Op::OpTypePointer, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeFunction", spv::Op::OpTypeFunction, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeEvent", spv::Op::OpTypeEvent, 1, pygen_variable_caps_Kernel, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeDeviceEvent", spv::Op::OpTypeDeviceEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeReserveId", spv::Op::OpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeQueue", spv::Op::OpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypePipe", spv::Op::OpTypePipe, 1, pygen_variable_caps_Pipes, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"TypeForwardPointer", spv::Op::OpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConstantTrue", spv::Op::OpConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConstantFalse", spv::Op::OpConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Constant", spv::Op::OpConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConstantComposite", spv::Op::OpConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConstantSampler", spv::Op::OpConstantSampler, 1, pygen_variable_caps_LiteralSampler, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConstantNull", spv::Op::OpConstantNull, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SpecConstantTrue", spv::Op::OpSpecConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SpecConstantFalse", spv::Op::OpSpecConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SpecConstant", spv::Op::OpSpecConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SpecConstantComposite", spv::Op::OpSpecConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SpecConstantOp", spv::Op::OpSpecConstantOp, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Function", spv::Op::OpFunction, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_FUNCTION_CONTROL, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FunctionParameter", spv::Op::OpFunctionParameter, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FunctionEnd", spv::Op::OpFunctionEnd, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FunctionCall", spv::Op::OpFunctionCall, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Variable", spv::Op::OpVariable, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageTexelPointer", spv::Op::OpImageTexelPointer, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Load", spv::Op::OpLoad, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Store", spv::Op::OpStore, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CopyMemory", spv::Op::OpCopyMemory, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CopyMemorySized", spv::Op::OpCopyMemorySized, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AccessChain", spv::Op::OpAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"InBoundsAccessChain", spv::Op::OpInBoundsAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"PtrAccessChain", spv::Op::OpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ArrayLength", spv::Op::OpArrayLength, 1, pygen_variable_caps_Shader, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GenericPtrMemSemantics", spv::Op::OpGenericPtrMemSemantics, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"InBoundsPtrAccessChain", spv::Op::OpInBoundsPtrAccessChain, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Decorate", spv::Op::OpDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MemberDecorate", spv::Op::OpMemberDecorate, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DecorationGroup", spv::Op::OpDecorationGroup, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupDecorate", spv::Op::OpGroupDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupMemberDecorate", spv::Op::OpGroupMemberDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"VectorExtractDynamic", spv::Op::OpVectorExtractDynamic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"VectorInsertDynamic", spv::Op::OpVectorInsertDynamic, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"VectorShuffle", spv::Op::OpVectorShuffle, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CompositeConstruct", spv::Op::OpCompositeConstruct, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CompositeExtract", spv::Op::OpCompositeExtract, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CompositeInsert", spv::Op::OpCompositeInsert, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CopyObject", spv::Op::OpCopyObject, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Transpose", spv::Op::OpTranspose, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SampledImage", spv::Op::OpSampledImage, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleImplicitLod", spv::Op::OpImageSampleImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleExplicitLod", spv::Op::OpImageSampleExplicitLod, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleDrefImplicitLod", spv::Op::OpImageSampleDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleDrefExplicitLod", spv::Op::OpImageSampleDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleProjImplicitLod", spv::Op::OpImageSampleProjImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleProjExplicitLod", spv::Op::OpImageSampleProjExplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleProjDrefImplicitLod", spv::Op::OpImageSampleProjDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSampleProjDrefExplicitLod", spv::Op::OpImageSampleProjDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageFetch", spv::Op::OpImageFetch, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageGather", spv::Op::OpImageGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageDrefGather", spv::Op::OpImageDrefGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageRead", spv::Op::OpImageRead, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageWrite", spv::Op::OpImageWrite, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Image", spv::Op::OpImage, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQueryFormat", spv::Op::OpImageQueryFormat, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQueryOrder", spv::Op::OpImageQueryOrder, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQuerySizeLod", spv::Op::OpImageQuerySizeLod, 2, pygen_variable_caps_KernelImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQuerySize", spv::Op::OpImageQuerySize, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQueryLod", spv::Op::OpImageQueryLod, 1, pygen_variable_caps_ImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQueryLevels", spv::Op::OpImageQueryLevels, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageQuerySamples", spv::Op::OpImageQuerySamples, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConvertFToU", spv::Op::OpConvertFToU, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConvertFToS", spv::Op::OpConvertFToS, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConvertSToF", spv::Op::OpConvertSToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConvertUToF", spv::Op::OpConvertUToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"UConvert", spv::Op::OpUConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SConvert", spv::Op::OpSConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FConvert", spv::Op::OpFConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"QuantizeToF16", spv::Op::OpQuantizeToF16, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConvertPtrToU", spv::Op::OpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SatConvertSToU", spv::Op::OpSatConvertSToU, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SatConvertUToS", spv::Op::OpSatConvertUToS, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ConvertUToPtr", spv::Op::OpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"PtrCastToGeneric", spv::Op::OpPtrCastToGeneric, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GenericCastToPtr", spv::Op::OpGenericCastToPtr, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GenericCastToPtrExplicit", spv::Op::OpGenericCastToPtrExplicit, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Bitcast", spv::Op::OpBitcast, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SNegate", spv::Op::OpSNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FNegate", spv::Op::OpFNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IAdd", spv::Op::OpIAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FAdd", spv::Op::OpFAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ISub", spv::Op::OpISub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FSub", spv::Op::OpFSub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IMul", spv::Op::OpIMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FMul", spv::Op::OpFMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"UDiv", spv::Op::OpUDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SDiv", spv::Op::OpSDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FDiv", spv::Op::OpFDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"UMod", spv::Op::OpUMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SRem", spv::Op::OpSRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SMod", spv::Op::OpSMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FRem", spv::Op::OpFRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FMod", spv::Op::OpFMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"VectorTimesScalar", spv::Op::OpVectorTimesScalar, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MatrixTimesScalar", spv::Op::OpMatrixTimesScalar, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"VectorTimesMatrix", spv::Op::OpVectorTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MatrixTimesVector", spv::Op::OpMatrixTimesVector, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MatrixTimesMatrix", spv::Op::OpMatrixTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"OuterProduct", spv::Op::OpOuterProduct, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Dot", spv::Op::OpDot, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IAddCarry", spv::Op::OpIAddCarry, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ISubBorrow", spv::Op::OpISubBorrow, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"UMulExtended", spv::Op::OpUMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SMulExtended", spv::Op::OpSMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Any", spv::Op::OpAny, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"All", spv::Op::OpAll, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IsNan", spv::Op::OpIsNan, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IsInf", spv::Op::OpIsInf, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IsFinite", spv::Op::OpIsFinite, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IsNormal", spv::Op::OpIsNormal, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SignBitSet", spv::Op::OpSignBitSet, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LessOrGreater", spv::Op::OpLessOrGreater, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), SPV_SPIRV_VERSION_WORD(1,5)},
-  {"Ordered", spv::Op::OpOrdered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Unordered", spv::Op::OpUnordered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LogicalEqual", spv::Op::OpLogicalEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LogicalNotEqual", spv::Op::OpLogicalNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LogicalOr", spv::Op::OpLogicalOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LogicalAnd", spv::Op::OpLogicalAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LogicalNot", spv::Op::OpLogicalNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Select", spv::Op::OpSelect, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IEqual", spv::Op::OpIEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"INotEqual", spv::Op::OpINotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"UGreaterThan", spv::Op::OpUGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SGreaterThan", spv::Op::OpSGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"UGreaterThanEqual", spv::Op::OpUGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SGreaterThanEqual", spv::Op::OpSGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ULessThan", spv::Op::OpULessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SLessThan", spv::Op::OpSLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ULessThanEqual", spv::Op::OpULessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SLessThanEqual", spv::Op::OpSLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FOrdEqual", spv::Op::OpFOrdEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FUnordEqual", spv::Op::OpFUnordEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FOrdNotEqual", spv::Op::OpFOrdNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FUnordNotEqual", spv::Op::OpFUnordNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FOrdLessThan", spv::Op::OpFOrdLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FUnordLessThan", spv::Op::OpFUnordLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FOrdGreaterThan", spv::Op::OpFOrdGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FUnordGreaterThan", spv::Op::OpFUnordGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FOrdLessThanEqual", spv::Op::OpFOrdLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FUnordLessThanEqual", spv::Op::OpFUnordLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FOrdGreaterThanEqual", spv::Op::OpFOrdGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FUnordGreaterThanEqual", spv::Op::OpFUnordGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ShiftRightLogical", spv::Op::OpShiftRightLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ShiftRightArithmetic", spv::Op::OpShiftRightArithmetic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ShiftLeftLogical", spv::Op::OpShiftLeftLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitwiseOr", spv::Op::OpBitwiseOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitwiseXor", spv::Op::OpBitwiseXor, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitwiseAnd", spv::Op::OpBitwiseAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Not", spv::Op::OpNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitFieldInsert", spv::Op::OpBitFieldInsert, 2, pygen_variable_caps_ShaderBitInstructions, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitFieldSExtract", spv::Op::OpBitFieldSExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitFieldUExtract", spv::Op::OpBitFieldUExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitReverse", spv::Op::OpBitReverse, 2, pygen_variable_caps_ShaderBitInstructions, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BitCount", spv::Op::OpBitCount, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DPdx", spv::Op::OpDPdx, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DPdy", spv::Op::OpDPdy, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Fwidth", spv::Op::OpFwidth, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DPdxFine", spv::Op::OpDPdxFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DPdyFine", spv::Op::OpDPdyFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FwidthFine", spv::Op::OpFwidthFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DPdxCoarse", spv::Op::OpDPdxCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"DPdyCoarse", spv::Op::OpDPdyCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"FwidthCoarse", spv::Op::OpFwidthCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EmitVertex", spv::Op::OpEmitVertex, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EndPrimitive", spv::Op::OpEndPrimitive, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EmitStreamVertex", spv::Op::OpEmitStreamVertex, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EndStreamPrimitive", spv::Op::OpEndStreamPrimitive, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ControlBarrier", spv::Op::OpControlBarrier, 0, nullptr, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"MemoryBarrier", spv::Op::OpMemoryBarrier, 0, nullptr, 2, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicLoad", spv::Op::OpAtomicLoad, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicStore", spv::Op::OpAtomicStore, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicExchange", spv::Op::OpAtomicExchange, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicCompareExchange", spv::Op::OpAtomicCompareExchange, 0, nullptr, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicCompareExchangeWeak", spv::Op::OpAtomicCompareExchangeWeak, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), SPV_SPIRV_VERSION_WORD(1,3)},
-  {"AtomicIIncrement", spv::Op::OpAtomicIIncrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicIDecrement", spv::Op::OpAtomicIDecrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicIAdd", spv::Op::OpAtomicIAdd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicISub", spv::Op::OpAtomicISub, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicSMin", spv::Op::OpAtomicSMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicUMin", spv::Op::OpAtomicUMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicSMax", spv::Op::OpAtomicSMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicUMax", spv::Op::OpAtomicUMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicAnd", spv::Op::OpAtomicAnd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicOr", spv::Op::OpAtomicOr, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicXor", spv::Op::OpAtomicXor, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Phi", spv::Op::OpPhi, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LoopMerge", spv::Op::OpLoopMerge, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LOOP_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SelectionMerge", spv::Op::OpSelectionMerge, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SELECTION_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Label", spv::Op::OpLabel, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Branch", spv::Op::OpBranch, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BranchConditional", spv::Op::OpBranchConditional, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Switch", spv::Op::OpSwitch, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Kill", spv::Op::OpKill, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Return", spv::Op::OpReturn, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReturnValue", spv::Op::OpReturnValue, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"Unreachable", spv::Op::OpUnreachable, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LifetimeStart", spv::Op::OpLifetimeStart, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"LifetimeStop", spv::Op::OpLifetimeStop, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupAsyncCopy", spv::Op::OpGroupAsyncCopy, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupWaitEvents", spv::Op::OpGroupWaitEvents, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupAll", spv::Op::OpGroupAll, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupAny", spv::Op::OpGroupAny, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupBroadcast", spv::Op::OpGroupBroadcast, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupIAdd", spv::Op::OpGroupIAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupFAdd", spv::Op::OpGroupFAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupFMin", spv::Op::OpGroupFMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupUMin", spv::Op::OpGroupUMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupSMin", spv::Op::OpGroupSMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupFMax", spv::Op::OpGroupFMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupUMax", spv::Op::OpGroupUMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupSMax", spv::Op::OpGroupSMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReadPipe", spv::Op::OpReadPipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"WritePipe", spv::Op::OpWritePipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReservedReadPipe", spv::Op::OpReservedReadPipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReservedWritePipe", spv::Op::OpReservedWritePipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReserveReadPipePackets", spv::Op::OpReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReserveWritePipePackets", spv::Op::OpReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CommitReadPipe", spv::Op::OpCommitReadPipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CommitWritePipe", spv::Op::OpCommitWritePipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IsValidReserveId", spv::Op::OpIsValidReserveId, 1, pygen_variable_caps_Pipes, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetNumPipePackets", spv::Op::OpGetNumPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetMaxPipePackets", spv::Op::OpGetMaxPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupReserveReadPipePackets", spv::Op::OpGroupReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupReserveWritePipePackets", spv::Op::OpGroupReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupCommitReadPipe", spv::Op::OpGroupCommitReadPipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GroupCommitWritePipe", spv::Op::OpGroupCommitWritePipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EnqueueMarker", spv::Op::OpEnqueueMarker, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"EnqueueKernel", spv::Op::OpEnqueueKernel, 1, pygen_variable_caps_DeviceEnqueue, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetKernelNDrangeSubGroupCount", spv::Op::OpGetKernelNDrangeSubGroupCount, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetKernelNDrangeMaxSubGroupSize", spv::Op::OpGetKernelNDrangeMaxSubGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetKernelWorkGroupSize", spv::Op::OpGetKernelWorkGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetKernelPreferredWorkGroupSizeMultiple", spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"RetainEvent", spv::Op::OpRetainEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ReleaseEvent", spv::Op::OpReleaseEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CreateUserEvent", spv::Op::OpCreateUserEvent, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"IsValidEvent", spv::Op::OpIsValidEvent, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"SetUserEventStatus", spv::Op::OpSetUserEventStatus, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"CaptureEventProfilingInfo", spv::Op::OpCaptureEventProfilingInfo, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"GetDefaultQueue", spv::Op::OpGetDefaultQueue, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"BuildNDRange", spv::Op::OpBuildNDRange, 1, pygen_variable_caps_DeviceEnqueue, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseSampleImplicitLod", spv::Op::OpImageSparseSampleImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseSampleExplicitLod", spv::Op::OpImageSparseSampleExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseSampleDrefImplicitLod", spv::Op::OpImageSparseSampleDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseSampleDrefExplicitLod", spv::Op::OpImageSparseSampleDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+  {"Nop", spv::Op::OpNop, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Undef", spv::Op::OpUndef, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SourceContinued", spv::Op::OpSourceContinued, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Source", spv::Op::OpSource, 0, nullptr, 4, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SourceExtension", spv::Op::OpSourceExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Name", spv::Op::OpName, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MemberName", spv::Op::OpMemberName, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"String", spv::Op::OpString, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Line", spv::Op::OpLine, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Extension", spv::Op::OpExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ExtInstImport", spv::Op::OpExtInstImport, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ExtInst", spv::Op::OpExtInst, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MemoryModel", spv::Op::OpMemoryModel, 0, nullptr, 2, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, SPV_OPERAND_TYPE_MEMORY_MODEL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EntryPoint", spv::Op::OpEntryPoint, 0, nullptr, 4, {SPV_OPERAND_TYPE_EXECUTION_MODEL, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ExecutionMode", spv::Op::OpExecutionMode, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Capability", spv::Op::OpCapability, 0, nullptr, 1, {SPV_OPERAND_TYPE_CAPABILITY}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeVoid", spv::Op::OpTypeVoid, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeBool", spv::Op::OpTypeBool, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeInt", spv::Op::OpTypeInt, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeFloat", spv::Op::OpTypeFloat, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeVector", spv::Op::OpTypeVector, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeMatrix", spv::Op::OpTypeMatrix, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeImage", spv::Op::OpTypeImage, 0, nullptr, 9, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeSampler", spv::Op::OpTypeSampler, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeSampledImage", spv::Op::OpTypeSampledImage, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeArray", spv::Op::OpTypeArray, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeRuntimeArray", spv::Op::OpTypeRuntimeArray, 1, pygen_variable_caps_Shader, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeStruct", spv::Op::OpTypeStruct, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeOpaque", spv::Op::OpTypeOpaque, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypePointer", spv::Op::OpTypePointer, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeFunction", spv::Op::OpTypeFunction, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeEvent", spv::Op::OpTypeEvent, 1, pygen_variable_caps_Kernel, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeDeviceEvent", spv::Op::OpTypeDeviceEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeReserveId", spv::Op::OpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeQueue", spv::Op::OpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypePipe", spv::Op::OpTypePipe, 1, pygen_variable_caps_Pipes, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"TypeForwardPointer", spv::Op::OpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConstantTrue", spv::Op::OpConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConstantFalse", spv::Op::OpConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Constant", spv::Op::OpConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConstantComposite", spv::Op::OpConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConstantSampler", spv::Op::OpConstantSampler, 1, pygen_variable_caps_LiteralSampler, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConstantNull", spv::Op::OpConstantNull, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SpecConstantTrue", spv::Op::OpSpecConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SpecConstantFalse", spv::Op::OpSpecConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SpecConstant", spv::Op::OpSpecConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SpecConstantComposite", spv::Op::OpSpecConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SpecConstantOp", spv::Op::OpSpecConstantOp, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Function", spv::Op::OpFunction, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_FUNCTION_CONTROL, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FunctionParameter", spv::Op::OpFunctionParameter, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FunctionEnd", spv::Op::OpFunctionEnd, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FunctionCall", spv::Op::OpFunctionCall, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Variable", spv::Op::OpVariable, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageTexelPointer", spv::Op::OpImageTexelPointer, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Load", spv::Op::OpLoad, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Store", spv::Op::OpStore, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CopyMemory", spv::Op::OpCopyMemory, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CopyMemorySized", spv::Op::OpCopyMemorySized, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AccessChain", spv::Op::OpAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"InBoundsAccessChain", spv::Op::OpInBoundsAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"PtrAccessChain", spv::Op::OpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ArrayLength", spv::Op::OpArrayLength, 1, pygen_variable_caps_Shader, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GenericPtrMemSemantics", spv::Op::OpGenericPtrMemSemantics, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"InBoundsPtrAccessChain", spv::Op::OpInBoundsPtrAccessChain, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Decorate", spv::Op::OpDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MemberDecorate", spv::Op::OpMemberDecorate, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DecorationGroup", spv::Op::OpDecorationGroup, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupDecorate", spv::Op::OpGroupDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupMemberDecorate", spv::Op::OpGroupMemberDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"VectorExtractDynamic", spv::Op::OpVectorExtractDynamic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"VectorInsertDynamic", spv::Op::OpVectorInsertDynamic, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"VectorShuffle", spv::Op::OpVectorShuffle, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CompositeConstruct", spv::Op::OpCompositeConstruct, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CompositeExtract", spv::Op::OpCompositeExtract, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CompositeInsert", spv::Op::OpCompositeInsert, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CopyObject", spv::Op::OpCopyObject, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Transpose", spv::Op::OpTranspose, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SampledImage", spv::Op::OpSampledImage, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleImplicitLod", spv::Op::OpImageSampleImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleExplicitLod", spv::Op::OpImageSampleExplicitLod, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleDrefImplicitLod", spv::Op::OpImageSampleDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleDrefExplicitLod", spv::Op::OpImageSampleDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleProjImplicitLod", spv::Op::OpImageSampleProjImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleProjExplicitLod", spv::Op::OpImageSampleProjExplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleProjDrefImplicitLod", spv::Op::OpImageSampleProjDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSampleProjDrefExplicitLod", spv::Op::OpImageSampleProjDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageFetch", spv::Op::OpImageFetch, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageGather", spv::Op::OpImageGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageDrefGather", spv::Op::OpImageDrefGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageRead", spv::Op::OpImageRead, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageWrite", spv::Op::OpImageWrite, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Image", spv::Op::OpImage, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQueryFormat", spv::Op::OpImageQueryFormat, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQueryOrder", spv::Op::OpImageQueryOrder, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQuerySizeLod", spv::Op::OpImageQuerySizeLod, 2, pygen_variable_caps_KernelImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQuerySize", spv::Op::OpImageQuerySize, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQueryLod", spv::Op::OpImageQueryLod, 1, pygen_variable_caps_ImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQueryLevels", spv::Op::OpImageQueryLevels, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageQuerySamples", spv::Op::OpImageQuerySamples, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConvertFToU", spv::Op::OpConvertFToU, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConvertFToS", spv::Op::OpConvertFToS, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConvertSToF", spv::Op::OpConvertSToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConvertUToF", spv::Op::OpConvertUToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"UConvert", spv::Op::OpUConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SConvert", spv::Op::OpSConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FConvert", spv::Op::OpFConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"QuantizeToF16", spv::Op::OpQuantizeToF16, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConvertPtrToU", spv::Op::OpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SatConvertSToU", spv::Op::OpSatConvertSToU, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SatConvertUToS", spv::Op::OpSatConvertUToS, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ConvertUToPtr", spv::Op::OpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"PtrCastToGeneric", spv::Op::OpPtrCastToGeneric, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GenericCastToPtr", spv::Op::OpGenericCastToPtr, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GenericCastToPtrExplicit", spv::Op::OpGenericCastToPtrExplicit, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Bitcast", spv::Op::OpBitcast, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SNegate", spv::Op::OpSNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FNegate", spv::Op::OpFNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IAdd", spv::Op::OpIAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FAdd", spv::Op::OpFAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ISub", spv::Op::OpISub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FSub", spv::Op::OpFSub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IMul", spv::Op::OpIMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FMul", spv::Op::OpFMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"UDiv", spv::Op::OpUDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SDiv", spv::Op::OpSDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FDiv", spv::Op::OpFDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"UMod", spv::Op::OpUMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SRem", spv::Op::OpSRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SMod", spv::Op::OpSMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FRem", spv::Op::OpFRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FMod", spv::Op::OpFMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"VectorTimesScalar", spv::Op::OpVectorTimesScalar, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MatrixTimesScalar", spv::Op::OpMatrixTimesScalar, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"VectorTimesMatrix", spv::Op::OpVectorTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MatrixTimesVector", spv::Op::OpMatrixTimesVector, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MatrixTimesMatrix", spv::Op::OpMatrixTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"OuterProduct", spv::Op::OpOuterProduct, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Dot", spv::Op::OpDot, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IAddCarry", spv::Op::OpIAddCarry, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ISubBorrow", spv::Op::OpISubBorrow, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"UMulExtended", spv::Op::OpUMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SMulExtended", spv::Op::OpSMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Any", spv::Op::OpAny, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"All", spv::Op::OpAll, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IsNan", spv::Op::OpIsNan, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IsInf", spv::Op::OpIsInf, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IsFinite", spv::Op::OpIsFinite, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IsNormal", spv::Op::OpIsNormal, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SignBitSet", spv::Op::OpSignBitSet, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LessOrGreater", spv::Op::OpLessOrGreater, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), SPV_SPIRV_VERSION_WORD(1,5)},
+  {"Ordered", spv::Op::OpOrdered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Unordered", spv::Op::OpUnordered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LogicalEqual", spv::Op::OpLogicalEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LogicalNotEqual", spv::Op::OpLogicalNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LogicalOr", spv::Op::OpLogicalOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LogicalAnd", spv::Op::OpLogicalAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LogicalNot", spv::Op::OpLogicalNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Select", spv::Op::OpSelect, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IEqual", spv::Op::OpIEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"INotEqual", spv::Op::OpINotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"UGreaterThan", spv::Op::OpUGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SGreaterThan", spv::Op::OpSGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"UGreaterThanEqual", spv::Op::OpUGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SGreaterThanEqual", spv::Op::OpSGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ULessThan", spv::Op::OpULessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SLessThan", spv::Op::OpSLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ULessThanEqual", spv::Op::OpULessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SLessThanEqual", spv::Op::OpSLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FOrdEqual", spv::Op::OpFOrdEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FUnordEqual", spv::Op::OpFUnordEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FOrdNotEqual", spv::Op::OpFOrdNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FUnordNotEqual", spv::Op::OpFUnordNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FOrdLessThan", spv::Op::OpFOrdLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FUnordLessThan", spv::Op::OpFUnordLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FOrdGreaterThan", spv::Op::OpFOrdGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FUnordGreaterThan", spv::Op::OpFUnordGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FOrdLessThanEqual", spv::Op::OpFOrdLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FUnordLessThanEqual", spv::Op::OpFUnordLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FOrdGreaterThanEqual", spv::Op::OpFOrdGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FUnordGreaterThanEqual", spv::Op::OpFUnordGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ShiftRightLogical", spv::Op::OpShiftRightLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ShiftRightArithmetic", spv::Op::OpShiftRightArithmetic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ShiftLeftLogical", spv::Op::OpShiftLeftLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitwiseOr", spv::Op::OpBitwiseOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitwiseXor", spv::Op::OpBitwiseXor, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitwiseAnd", spv::Op::OpBitwiseAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Not", spv::Op::OpNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitFieldInsert", spv::Op::OpBitFieldInsert, 2, pygen_variable_caps_ShaderBitInstructions, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitFieldSExtract", spv::Op::OpBitFieldSExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitFieldUExtract", spv::Op::OpBitFieldUExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitReverse", spv::Op::OpBitReverse, 2, pygen_variable_caps_ShaderBitInstructions, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BitCount", spv::Op::OpBitCount, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DPdx", spv::Op::OpDPdx, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DPdy", spv::Op::OpDPdy, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Fwidth", spv::Op::OpFwidth, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DPdxFine", spv::Op::OpDPdxFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DPdyFine", spv::Op::OpDPdyFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FwidthFine", spv::Op::OpFwidthFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DPdxCoarse", spv::Op::OpDPdxCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"DPdyCoarse", spv::Op::OpDPdyCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"FwidthCoarse", spv::Op::OpFwidthCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EmitVertex", spv::Op::OpEmitVertex, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EndPrimitive", spv::Op::OpEndPrimitive, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EmitStreamVertex", spv::Op::OpEmitStreamVertex, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EndStreamPrimitive", spv::Op::OpEndStreamPrimitive, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ControlBarrier", spv::Op::OpControlBarrier, 0, nullptr, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"MemoryBarrier", spv::Op::OpMemoryBarrier, 0, nullptr, 2, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicLoad", spv::Op::OpAtomicLoad, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicStore", spv::Op::OpAtomicStore, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicExchange", spv::Op::OpAtomicExchange, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicCompareExchange", spv::Op::OpAtomicCompareExchange, 0, nullptr, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicCompareExchangeWeak", spv::Op::OpAtomicCompareExchangeWeak, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), SPV_SPIRV_VERSION_WORD(1,3)},
+  {"AtomicIIncrement", spv::Op::OpAtomicIIncrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicIDecrement", spv::Op::OpAtomicIDecrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicIAdd", spv::Op::OpAtomicIAdd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicISub", spv::Op::OpAtomicISub, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicSMin", spv::Op::OpAtomicSMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicUMin", spv::Op::OpAtomicUMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicSMax", spv::Op::OpAtomicSMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicUMax", spv::Op::OpAtomicUMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicAnd", spv::Op::OpAtomicAnd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicOr", spv::Op::OpAtomicOr, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicXor", spv::Op::OpAtomicXor, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Phi", spv::Op::OpPhi, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LoopMerge", spv::Op::OpLoopMerge, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LOOP_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SelectionMerge", spv::Op::OpSelectionMerge, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SELECTION_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Label", spv::Op::OpLabel, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Branch", spv::Op::OpBranch, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BranchConditional", spv::Op::OpBranchConditional, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Switch", spv::Op::OpSwitch, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Kill", spv::Op::OpKill, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Return", spv::Op::OpReturn, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReturnValue", spv::Op::OpReturnValue, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"Unreachable", spv::Op::OpUnreachable, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LifetimeStart", spv::Op::OpLifetimeStart, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"LifetimeStop", spv::Op::OpLifetimeStop, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupAsyncCopy", spv::Op::OpGroupAsyncCopy, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupWaitEvents", spv::Op::OpGroupWaitEvents, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupAll", spv::Op::OpGroupAll, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupAny", spv::Op::OpGroupAny, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupBroadcast", spv::Op::OpGroupBroadcast, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupIAdd", spv::Op::OpGroupIAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupFAdd", spv::Op::OpGroupFAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupFMin", spv::Op::OpGroupFMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupUMin", spv::Op::OpGroupUMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupSMin", spv::Op::OpGroupSMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupFMax", spv::Op::OpGroupFMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupUMax", spv::Op::OpGroupUMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupSMax", spv::Op::OpGroupSMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReadPipe", spv::Op::OpReadPipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"WritePipe", spv::Op::OpWritePipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReservedReadPipe", spv::Op::OpReservedReadPipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReservedWritePipe", spv::Op::OpReservedWritePipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReserveReadPipePackets", spv::Op::OpReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReserveWritePipePackets", spv::Op::OpReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CommitReadPipe", spv::Op::OpCommitReadPipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CommitWritePipe", spv::Op::OpCommitWritePipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IsValidReserveId", spv::Op::OpIsValidReserveId, 1, pygen_variable_caps_Pipes, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetNumPipePackets", spv::Op::OpGetNumPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetMaxPipePackets", spv::Op::OpGetMaxPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupReserveReadPipePackets", spv::Op::OpGroupReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupReserveWritePipePackets", spv::Op::OpGroupReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupCommitReadPipe", spv::Op::OpGroupCommitReadPipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GroupCommitWritePipe", spv::Op::OpGroupCommitWritePipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EnqueueMarker", spv::Op::OpEnqueueMarker, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"EnqueueKernel", spv::Op::OpEnqueueKernel, 1, pygen_variable_caps_DeviceEnqueue, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetKernelNDrangeSubGroupCount", spv::Op::OpGetKernelNDrangeSubGroupCount, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetKernelNDrangeMaxSubGroupSize", spv::Op::OpGetKernelNDrangeMaxSubGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetKernelWorkGroupSize", spv::Op::OpGetKernelWorkGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetKernelPreferredWorkGroupSizeMultiple", spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"RetainEvent", spv::Op::OpRetainEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ReleaseEvent", spv::Op::OpReleaseEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CreateUserEvent", spv::Op::OpCreateUserEvent, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"IsValidEvent", spv::Op::OpIsValidEvent, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"SetUserEventStatus", spv::Op::OpSetUserEventStatus, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"CaptureEventProfilingInfo", spv::Op::OpCaptureEventProfilingInfo, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"GetDefaultQueue", spv::Op::OpGetDefaultQueue, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"BuildNDRange", spv::Op::OpBuildNDRange, 1, pygen_variable_caps_DeviceEnqueue, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseSampleImplicitLod", spv::Op::OpImageSparseSampleImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseSampleExplicitLod", spv::Op::OpImageSparseSampleExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseSampleDrefImplicitLod", spv::Op::OpImageSparseSampleDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseSampleDrefExplicitLod", spv::Op::OpImageSparseSampleDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
   {"ImageSparseSampleProjImplicitLod", spv::Op::OpImageSparseSampleProjImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"ImageSparseSampleProjExplicitLod", spv::Op::OpImageSparseSampleProjExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"ImageSparseSampleProjDrefImplicitLod", spv::Op::OpImageSparseSampleProjDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"ImageSparseSampleProjDrefExplicitLod", spv::Op::OpImageSparseSampleProjDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
-  {"ImageSparseFetch", spv::Op::OpImageSparseFetch, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseGather", spv::Op::OpImageSparseGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseDrefGather", spv::Op::OpImageSparseDrefGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseTexelsResident", spv::Op::OpImageSparseTexelsResident, 1, pygen_variable_caps_SparseResidency, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"NoLine", spv::Op::OpNoLine, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicFlagTestAndSet", spv::Op::OpAtomicFlagTestAndSet, 1, pygen_variable_caps_Kernel, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"AtomicFlagClear", spv::Op::OpAtomicFlagClear, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
-  {"ImageSparseRead", spv::Op::OpImageSparseRead, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+  {"ImageSparseFetch", spv::Op::OpImageSparseFetch, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseGather", spv::Op::OpImageSparseGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseDrefGather", spv::Op::OpImageSparseDrefGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseTexelsResident", spv::Op::OpImageSparseTexelsResident, 1, pygen_variable_caps_SparseResidency, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"NoLine", spv::Op::OpNoLine, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicFlagTestAndSet", spv::Op::OpAtomicFlagTestAndSet, 1, pygen_variable_caps_Kernel, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"AtomicFlagClear", spv::Op::OpAtomicFlagClear, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
+  {"ImageSparseRead", spv::Op::OpImageSparseRead, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
   {"SizeOf", spv::Op::OpSizeOf, 1, pygen_variable_caps_Addresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
   {"TypePipeStorage", spv::Op::OpTypePipeStorage, 1, pygen_variable_caps_PipeStorage, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
   {"ConstantPipeStorage", spv::Op::OpConstantPipeStorage, 1, pygen_variable_caps_PipeStorage, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
@@ -515,6 +516,9 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
   {"FragmentMaskFetchAMD", spv::Op::OpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
   {"FragmentFetchAMD", spv::Op::OpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
   {"ReadClockKHR", spv::Op::OpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"FinalizeNodePayloadsAMDX", spv::Op::OpFinalizeNodePayloadsAMDX, 1, pygen_variable_caps_ShaderEnqueueAMDX, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"FinishWritingNodePayloadAMDX", spv::Op::OpFinishWritingNodePayloadAMDX, 1, pygen_variable_caps_ShaderEnqueueAMDX, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"InitializeNodePayloadsAMDX", spv::Op::OpInitializeNodePayloadsAMDX, 1, pygen_variable_caps_ShaderEnqueueAMDX, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"HitObjectRecordHitMotionNV", spv::Op::OpHitObjectRecordHitMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 14, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"HitObjectRecordHitWithIndexMotionNV", spv::Op::OpHitObjectRecordHitWithIndexMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"HitObjectRecordMissMotionNV", spv::Op::OpHitObjectRecordMissMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 7, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
3rdparty/spirv-tools/include/generated/enum_string_mapping.inc


+ 3 - 0
3rdparty/spirv-tools/include/generated/extension_enum.inc

@@ -1,3 +1,4 @@
+kSPV_AMDX_shader_enqueue,
 kSPV_AMD_gcn_shader,
 kSPV_AMD_gpu_shader_half_float,
 kSPV_AMD_gpu_shader_half_float_fetch,
@@ -49,6 +50,8 @@ kSPV_INTEL_fpga_memory_accesses,
 kSPV_INTEL_fpga_memory_attributes,
 kSPV_INTEL_fpga_reg,
 kSPV_INTEL_function_pointers,
+kSPV_INTEL_global_variable_fpga_decorations,
+kSPV_INTEL_global_variable_host_access,
 kSPV_INTEL_inline_assembly,
 kSPV_INTEL_io_pipes,
 kSPV_INTEL_kernel_attributes,

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 410 - 382
3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc


+ 5 - 0
3rdparty/spirv-tools/include/spirv-tools/libspirv.h

@@ -294,6 +294,11 @@ typedef enum spv_operand_type_t {
   SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT,
   SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE,
 
+  // Enum type from SPV_INTEL_global_variable_fpga_decorations
+  SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER,
+  // Enum type from SPV_INTEL_global_variable_host_access
+  SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER,
+
   // This is a sentinel value, and does not represent an operand type.
   // It should come last.
   SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,

+ 9 - 8
3rdparty/spirv-tools/include/spirv-tools/linker.hpp

@@ -26,11 +26,6 @@ namespace spvtools {
 
 class LinkerOptions {
  public:
-  LinkerOptions()
-      : create_library_(false),
-        verify_ids_(false),
-        allow_partial_linkage_(false) {}
-
   // Returns whether a library or an executable should be produced by the
   // linking phase.
   //
@@ -63,10 +58,16 @@ class LinkerOptions {
     allow_partial_linkage_ = allow_partial_linkage;
   }
 
+  bool GetUseHighestVersion() const { return use_highest_version_; }
+  void SetUseHighestVersion(bool use_highest_vers) {
+    use_highest_version_ = use_highest_vers;
+  }
+
  private:
-  bool create_library_;
-  bool verify_ids_;
-  bool allow_partial_linkage_;
+  bool create_library_{false};
+  bool verify_ids_{false};
+  bool allow_partial_linkage_{false};
+  bool use_highest_version_{false};
 };
 
 // Links one or more SPIR-V modules into a new SPIR-V module. That is, combine

+ 5 - 0
3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp

@@ -992,6 +992,11 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass();
 // the unknown capability interacts with one of the trimmed capabilities.
 Optimizer::PassToken CreateTrimCapabilitiesPass();
 
+// Creates a switch-descriptorset pass.
+// This pass changes any DescriptorSet decorations with the value |ds_from| to
+// use the new value |ds_to|.
+Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t ds_from,
+                                                   uint32_t ds_to);
 }  // namespace spvtools
 
 #endif  // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_

+ 10 - 6
3rdparty/spirv-tools/source/assembly_grammar.cpp

@@ -21,6 +21,7 @@
 #include "source/ext_inst.h"
 #include "source/opcode.h"
 #include "source/operand.h"
+#include "source/spirv_target_env.h"
 #include "source/table.h"
 
 namespace spvtools {
@@ -176,15 +177,18 @@ bool AssemblyGrammar::isValid() const {
 CapabilitySet AssemblyGrammar::filterCapsAgainstTargetEnv(
     const spv::Capability* cap_array, uint32_t count) const {
   CapabilitySet cap_set;
+  const auto version = spvVersionForTargetEnv(target_env_);
   for (uint32_t i = 0; i < count; ++i) {
-    spv_operand_desc cap_desc = {};
+    spv_operand_desc entry = {};
     if (SPV_SUCCESS == lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
                                      static_cast<uint32_t>(cap_array[i]),
-                                     &cap_desc)) {
-      // spvOperandTableValueLookup() filters capabilities internally
-      // according to the current target environment by itself. So we
-      // should be safe to add this capability if the lookup succeeds.
-      cap_set.insert(cap_array[i]);
+                                     &entry)) {
+      // This token is visible in this environment if it's in an appropriate
+      // core version, or it is enabled by a capability or an extension.
+      if ((version >= entry->minVersion && version <= entry->lastVersion) ||
+          entry->numExtensions > 0u || entry->numCapabilities > 0u) {
+        cap_set.insert(cap_array[i]);
+      }
     }
   }
   return cap_set;

+ 10 - 5
3rdparty/spirv-tools/source/link/linker.cpp

@@ -91,7 +91,8 @@ spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
 // should be non-null. |max_id_bound| should be strictly greater than 0.
 spv_result_t GenerateHeader(const MessageConsumer& consumer,
                             const std::vector<opt::Module*>& modules,
-                            uint32_t max_id_bound, opt::ModuleHeader* header);
+                            uint32_t max_id_bound, opt::ModuleHeader* header,
+                            const LinkerOptions& options);
 
 // Merge all the modules from |in_modules| into a single module owned by
 // |linked_context|.
@@ -202,7 +203,8 @@ spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
 
 spv_result_t GenerateHeader(const MessageConsumer& consumer,
                             const std::vector<opt::Module*>& modules,
-                            uint32_t max_id_bound, opt::ModuleHeader* header) {
+                            uint32_t max_id_bound, opt::ModuleHeader* header,
+                            const LinkerOptions& options) {
   spv_position_t position = {};
 
   if (modules.empty())
@@ -212,10 +214,12 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer,
     return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
            << "|max_id_bound| of GenerateHeader should not be null.";
 
-  const uint32_t linked_version = modules.front()->version();
+  uint32_t linked_version = modules.front()->version();
   for (std::size_t i = 1; i < modules.size(); ++i) {
     const uint32_t module_version = modules[i]->version();
-    if (module_version != linked_version)
+    if (options.GetUseHighestVersion()) {
+      linked_version = std::max(linked_version, module_version);
+    } else if (module_version != linked_version) {
       return DiagnosticStream({0, 0, 1}, consumer, "", SPV_ERROR_INTERNAL)
              << "Conflicting SPIR-V versions: "
              << SPV_SPIRV_VERSION_MAJOR_PART(linked_version) << "."
@@ -224,6 +228,7 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer,
              << SPV_SPIRV_VERSION_MAJOR_PART(module_version) << "."
              << SPV_SPIRV_VERSION_MINOR_PART(module_version)
              << " (input module " << (i + 1) << ").";
+    }
   }
 
   header->magic_number = spv::MagicNumber;
@@ -753,7 +758,7 @@ spv_result_t Link(const Context& context, const uint32_t* const* binaries,
 
   // Phase 2: Generate the header
   opt::ModuleHeader header;
-  res = GenerateHeader(consumer, modules, max_id_bound, &header);
+  res = GenerateHeader(consumer, modules, max_id_bound, &header, options);
   if (res != SPV_SUCCESS) return res;
   IRContext linked_context(c_context->target_env, consumer);
   linked_context.module()->SetHeader(header);

+ 19 - 45
3rdparty/spirv-tools/source/operand.cpp

@@ -26,7 +26,6 @@
 #include "source/macro.h"
 #include "source/opcode.h"
 #include "source/spirv_constant.h"
-#include "source/spirv_target_env.h"
 
 // For now, assume unified1 contains up to SPIR-V 1.3 and no later
 // SPIR-V version.
@@ -48,7 +47,7 @@ spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
   return SPV_SUCCESS;
 }
 
-spv_result_t spvOperandTableNameLookup(spv_target_env env,
+spv_result_t spvOperandTableNameLookup(spv_target_env,
                                        const spv_operand_table table,
                                        const spv_operand_type_t type,
                                        const char* name,
@@ -57,31 +56,18 @@ spv_result_t spvOperandTableNameLookup(spv_target_env env,
   if (!table) return SPV_ERROR_INVALID_TABLE;
   if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
 
-  const auto version = spvVersionForTargetEnv(env);
   for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
     const auto& group = table->types[typeIndex];
     if (type != group.type) continue;
     for (uint64_t index = 0; index < group.count; ++index) {
       const auto& entry = group.entries[index];
       // We consider the current operand as available as long as
-      // 1. The target environment satisfies the minimal requirement of the
-      //    operand; or
-      // 2. There is at least one extension enabling this operand; or
-      // 3. There is at least one capability enabling this operand.
-      //
-      // Note that the second rule assumes the extension enabling this operand
-      // is indeed requested in the SPIR-V code; checking that should be
-      // validator's work.
+      // it is in the grammar.  It might not be *valid* to use,
+      // but that should be checked by the validator, not by parsing.
       if (nameLength == strlen(entry.name) &&
           !strncmp(entry.name, name, nameLength)) {
-        if ((version >= entry.minVersion && version <= entry.lastVersion) ||
-            entry.numExtensions > 0u || entry.numCapabilities > 0u) {
-          *pEntry = &entry;
-          return SPV_SUCCESS;
-        } else {
-          // if there is no extension/capability then the version is wrong
-          return SPV_ERROR_WRONG_VERSION;
-        }
+        *pEntry = &entry;
+        return SPV_SUCCESS;
       }
     }
   }
@@ -89,7 +75,7 @@ spv_result_t spvOperandTableNameLookup(spv_target_env env,
   return SPV_ERROR_INVALID_LOOKUP;
 }
 
-spv_result_t spvOperandTableValueLookup(spv_target_env env,
+spv_result_t spvOperandTableValueLookup(spv_target_env,
                                         const spv_operand_table table,
                                         const spv_operand_type_t type,
                                         const uint32_t value,
@@ -110,33 +96,15 @@ spv_result_t spvOperandTableValueLookup(spv_target_env env,
     const auto beg = group.entries;
     const auto end = group.entries + group.count;
 
-    // We need to loop here because there can exist multiple symbols for the
-    // same operand value, and they can be introduced in different target
-    // environments, which means they can have different minimal version
-    // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
-    // version as long as the SPV_KHR_shader_ballot extension is there; but
-    // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
-    // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
-    // requirements.
     // Assumes the underlying table is already sorted ascendingly according to
     // opcode value.
-    const auto version = spvVersionForTargetEnv(env);
-    for (auto it = std::lower_bound(beg, end, needle, comp);
-         it != end && it->value == value; ++it) {
-      // We consider the current operand as available as long as
-      // 1. The target environment satisfies the minimal requirement of the
-      //    operand; or
-      // 2. There is at least one extension enabling this operand; or
-      // 3. There is at least one capability enabling this operand.
-      //
-      // Note that the second rule assumes the extension enabling this operand
-      // is indeed requested in the SPIR-V code; checking that should be
-      // validator's work.
-      if ((version >= it->minVersion && version <= it->lastVersion) ||
-          it->numExtensions > 0u || it->numCapabilities > 0u) {
-        *pEntry = it;
-        return SPV_SUCCESS;
-      }
+    auto it = std::lower_bound(beg, end, needle, comp);
+    if (it != end && it->value == value) {
+      // The current operand is considered available as long as
+      // it is in the grammar.  It might not be *valid* to use,
+      // but that should be checked by the validator, not by parsing.
+      *pEntry = it;
+      return SPV_SUCCESS;
     }
   }
 
@@ -244,6 +212,10 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
       return "cooperative matrix layout";
     case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
       return "cooperative matrix use";
+    case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
+      return "initialization mode qualifier";
+    case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
+      return "host access qualifier";
     case SPV_OPERAND_TYPE_IMAGE:
     case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
       return "image";
@@ -380,6 +352,8 @@ bool spvOperandIsConcrete(spv_operand_type_t type) {
     case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
     case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
     case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
+    case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
+    case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
       return true;
     default:
       break;

+ 8 - 3
3rdparty/spirv-tools/source/opt/decoration_manager.cpp

@@ -461,7 +461,7 @@ std::vector<T> DecorationManager::InternalGetDecorationsFor(
 
 bool DecorationManager::WhileEachDecoration(
     uint32_t id, uint32_t decoration,
-    std::function<bool(const Instruction&)> f) {
+    std::function<bool(const Instruction&)> f) const {
   for (const Instruction* inst : GetDecorationsFor(id, true)) {
     switch (inst->opcode()) {
       case spv::Op::OpMemberDecorate:
@@ -485,14 +485,19 @@ bool DecorationManager::WhileEachDecoration(
 
 void DecorationManager::ForEachDecoration(
     uint32_t id, uint32_t decoration,
-    std::function<void(const Instruction&)> f) {
+    std::function<void(const Instruction&)> f) const {
   WhileEachDecoration(id, decoration, [&f](const Instruction& inst) {
     f(inst);
     return true;
   });
 }
 
-bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) {
+bool DecorationManager::HasDecoration(uint32_t id,
+                                      spv::Decoration decoration) const {
+  return HasDecoration(id, static_cast<uint32_t>(decoration));
+}
+
+bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) const {
   bool has_decoration = false;
   ForEachDecoration(id, decoration, [&has_decoration](const Instruction&) {
     has_decoration = true;

+ 4 - 3
3rdparty/spirv-tools/source/opt/decoration_manager.h

@@ -92,20 +92,21 @@ class DecorationManager {
 
   // Returns whether a decoration instruction for |id| with decoration
   // |decoration| exists or not.
-  bool HasDecoration(uint32_t id, uint32_t decoration);
+  bool HasDecoration(uint32_t id, uint32_t decoration) const;
+  bool HasDecoration(uint32_t id, spv::Decoration decoration) const;
 
   // |f| is run on each decoration instruction for |id| with decoration
   // |decoration|. Processed are all decorations which target |id| either
   // directly or indirectly by Decoration Groups.
   void ForEachDecoration(uint32_t id, uint32_t decoration,
-                         std::function<void(const Instruction&)> f);
+                         std::function<void(const Instruction&)> f) const;
 
   // |f| is run on each decoration instruction for |id| with decoration
   // |decoration|. Processes all decoration which target |id| either directly or
   // indirectly through decoration groups. If |f| returns false, iteration is
   // terminated and this function returns false.
   bool WhileEachDecoration(uint32_t id, uint32_t decoration,
-                           std::function<bool(const Instruction&)> f);
+                           std::function<bool(const Instruction&)> f) const;
 
   // |f| is run on each decoration instruction for |id| with decoration
   // |decoration|. Processes all decoration which target |id| either directly or

+ 408 - 208
3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp

@@ -132,50 +132,58 @@ void InstBindlessCheckPass::SetupInputBufferIds() {
 
 // clang-format off
 // GLSL:
-//bool inst_bindless_check_desc(uint shader_id, uint line, uvec4 stage_info, uint desc_set_idx, uint binding_idx, uint desc_idx,
-//                              uint offset)
+//bool inst_bindless_check_desc(uint shader_id, uint inst_num, uvec4 stage_info, uint desc_set, uint binding, uint desc_index,
+//                              uint byte_offset)
 //{
-//    if (desc_set_idx >= inst_bindless_input_buffer.desc_sets.length()) {
-//        // kInstErrorBindlessBounds
-//        inst_bindless_stream_write_6(shader_id, line, stage_info, 1, desc_set_idx, binding_idx, desc_idx, 0, 0);
-//        return false;
+//    uint error = 0u;
+//    uint param5 = 0u;
+//    uint param6 = 0u;
+//    uint num_bindings = 0u;
+//    uint init_state = 0u;
+//    if (desc_set >= 32u) {
+//        error = 1u;
 //    }
-//    DescriptorSetData set_data = inst_bindless_input_buffer.desc_sets[desc_set_idx];
-//    uvec2 ptr_vec = uvec2(set_data);
-//    if (ptr_vec.x == 0 && ptr_vec.y == 0) {
-//        // kInstErrorBindlessBounds
-//        inst_bindless_stream_write_6(shader_id, line, stage_info, 1, desc_set_idx, binding_idx, desc_idx, 0, 0);
-//        return false;
+//    inst_bindless_DescriptorSetData set_data;
+//    if (error == 0u) {
+//        set_data = inst_bindless_input_buffer.desc_sets[desc_set];
+//        uvec2 ptr_vec = uvec2(set_data);
+//        if ((ptr_vec.x == 0u) && (ptr_vec.y == 0u)) {
+//            error = 1u;
+//        }
 //    }
-//    uint num_bindings = set_data.num_bindings;
-//    if (binding_idx >= num_bindings) {
-//        // kInstErrorBindlessBounds
-//        inst_bindless_stream_write_6(shader_id, line, stage_info, 1, desc_set_idx, binding_idx, desc_idx, 0, 0);
-//        return false;
+//    if (error == 0u) {
+//        num_bindings = set_data.num_bindings;
+//        if (binding >= num_bindings) {
+//            error = 1u;
+//        }
 //    }
-//    uint binding_length = set_data.data[binding_idx];
-//    if (desc_idx >= binding_length) {
-//        // kInstErrorBindlessBounds
-//        inst_bindless_stream_write_6(shader_id, line, stage_info, 1, desc_set_idx, binding_idx, desc_idx, binding_length, 0);
-//        return false;
+//    if (error == 0u) {
+//        if (desc_index >= set_data.data[binding]) {
+//            error = 1u;
+//            param5 = set_data.data[binding];
+//        }
 //    }
-//    uint desc_records_start = set_data.data[num_bindings + binding_idx];
-//    uint init_or_len = set_data.data[desc_records_start + desc_idx];
-//    if (init_or_len == 0) {
-//        // kInstErrorBindlessUninit
-//        inst_bindless_stream_write_6(shader_id, line, stage_info, 2, desc_set_idx, binding_idx, desc_idx, 0, 0);
-//        return false;
+//    if (0u == error) {
+//        uint state_index = set_data.data[num_bindings + binding] + desc_index;
+//        init_state = set_data.data[state_index];
+//        if (init_state == 0u) {
+//            error = 2u;
+//        }
 //    }
-//    if (offset >= init_or_len) {
-//        // kInstErrorOOB
-//        inst_bindless_stream_write_6(shader_id, line, stage_info, 4, desc_set_idx, binding_idx, desc_idx, offset,
-//                                      init_or_len);
+//    if (error == 0u) {
+//        if (byte_offset >= init_state) {
+//            error = 4u;
+//            param5 = byte_offset;
+//            param6 = init_state;
+//        }
+//    }
+//    if (0u != error) {
+//        inst_bindless_stream_write_6(shader_id, inst_num, stage_info, error, desc_set, binding, desc_index, param5, param6);
 //        return false;
 //    }
 //    return true;
 //}
 // clang-format on
-
 uint32_t InstBindlessCheckPass::GenDescCheckFunctionId() {
   enum {
     kShaderId = 0,
@@ -205,235 +213,427 @@ uint32_t InstBindlessCheckPass::GenDescCheckFunctionId() {
 
   const std::vector<uint32_t> param_ids = AddParameters(*func, param_types);
 
+  const uint32_t func_uint_ptr =
+      type_mgr->FindPointerToType(GetUintId(), spv::StorageClass::Function);
   // Create block
   auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
   InstructionBuilder builder(
       context(), new_blk_ptr.get(),
       IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
+  Instruction* inst;
+  const uint32_t zero_id = builder.GetUintConstantId(0);
   const uint32_t false_id = builder.GetBoolConstantId(false);
   const uint32_t true_id = builder.GetBoolConstantId(true);
-  Instruction* inst;
+  const uint32_t uint_ptr = type_mgr->FindPointerToType(
+      GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
+
+  inst = builder.AddBinaryOp(func_uint_ptr, spv::Op::OpVariable,
+                             uint32_t(spv::StorageClass::Function), zero_id);
+  const uint32_t error_var = inst->result_id();
+
+  inst = builder.AddBinaryOp(func_uint_ptr, spv::Op::OpVariable,
+                             uint32_t(spv::StorageClass::Function), zero_id);
+  const uint32_t param5_var = inst->result_id();
+
+  inst = builder.AddBinaryOp(func_uint_ptr, spv::Op::OpVariable,
+                             uint32_t(spv::StorageClass::Function), zero_id);
+  const uint32_t param6_var = inst->result_id();
+
+  inst = builder.AddBinaryOp(func_uint_ptr, spv::Op::OpVariable,
+                             uint32_t(spv::StorageClass::Function), zero_id);
+  const uint32_t num_bindings_var = inst->result_id();
+  inst = builder.AddBinaryOp(func_uint_ptr, spv::Op::OpVariable,
+                             uint32_t(spv::StorageClass::Function), zero_id);
+  const uint32_t init_status_var = inst->result_id();
 
+  const uint32_t desc_set_ptr_ptr = type_mgr->FindPointerToType(
+      desc_set_ptr_id_, spv::StorageClass::Function);
+
+  inst = builder.AddUnaryOp(desc_set_ptr_ptr, spv::Op::OpVariable,
+                            uint32_t(spv::StorageClass::Function));
+  const uint32_t desc_set_ptr_var = inst->result_id();
+  get_decoration_mgr()->AddDecoration(
+      desc_set_ptr_var, uint32_t(spv::Decoration::AliasedPointer));
+
+  uint32_t check_label_id = TakeNextId();
+  auto check_label = NewLabel(check_label_id);
+  uint32_t skip_label_id = TakeNextId();
+  auto skip_label = NewLabel(skip_label_id);
   inst = builder.AddBinaryOp(
       GetBoolId(), spv::Op::OpUGreaterThanEqual, param_ids[kDescSet],
       builder.GetUintConstantId(kDebugInputBindlessMaxDescSets));
   const uint32_t desc_cmp_id = inst->result_id();
 
-  uint32_t error_blk_id = TakeNextId();
-  uint32_t merge_blk_id = TakeNextId();
-  std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
-  std::unique_ptr<Instruction> error_label(NewLabel(error_blk_id));
-  (void)builder.AddConditionalBranch(desc_cmp_id, error_blk_id, merge_blk_id,
-                                     merge_blk_id);
+  (void)builder.AddConditionalBranch(desc_cmp_id, check_label_id, skip_label_id,
+                                     skip_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
 
-  // error return
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+  // set error
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_label));
   builder.SetInsertPoint(&*new_blk_ptr);
-  (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, false_id);
+  builder.AddStore(error_var,
+                   builder.GetUintConstantId(kInstErrorBindlessBounds));
+  builder.AddBranch(skip_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
 
   // check descriptor set table entry is non-null
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
   builder.SetInsertPoint(&*new_blk_ptr);
 
-  const uint32_t desc_set_ptr_ptr = type_mgr->FindPointerToType(
-      desc_set_ptr_id_, spv::StorageClass::StorageBuffer);
-
-  inst = builder.AddAccessChain(
-      desc_set_ptr_ptr, input_buffer_id_,
-      {builder.GetUintConstantId(0), param_ids[kDescSet]});
-  const uint32_t set_access_chain_id = inst->result_id();
-
-  inst = builder.AddLoad(desc_set_ptr_id_, set_access_chain_id);
-  const uint32_t desc_set_ptr_id = inst->result_id();
-
-  inst =
-      builder.AddUnaryOp(GetVecUintId(2), spv::Op::OpBitcast, desc_set_ptr_id);
-  const uint32_t ptr_as_uvec_id = inst->result_id();
+  check_label_id = TakeNextId();
+  check_label = NewLabel(check_label_id);
+  skip_label_id = TakeNextId();
+  skip_label = NewLabel(skip_label_id);
+  inst = builder.AddLoad(GetUintId(), error_var);
+  uint32_t error_val_id = inst->result_id();
+
+  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, error_val_id,
+                             zero_id);
+  uint32_t no_error_id = inst->result_id();
+  (void)builder.AddConditionalBranch(no_error_id, check_label_id, skip_label_id,
+                                     skip_label_id);
+  func->AddBasicBlock(std::move(new_blk_ptr));
 
-  inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {0});
-  const uint32_t uvec_x = inst->result_id();
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_label));
+  builder.SetInsertPoint(&*new_blk_ptr);
 
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_x,
-                             builder.GetUintConstantId(0));
-  const uint32_t x_is_zero_id = inst->result_id();
+  {
+    const uint32_t desc_set_ptr_ptr_sb = type_mgr->FindPointerToType(
+        desc_set_ptr_id_, spv::StorageClass::StorageBuffer);
+
+    inst = builder.AddAccessChain(desc_set_ptr_ptr_sb, input_buffer_id_,
+                                  {zero_id, param_ids[kDescSet]});
+    const uint32_t set_access_chain_id = inst->result_id();
+
+    inst = builder.AddLoad(desc_set_ptr_id_, set_access_chain_id);
+    const uint32_t desc_set_ptr_id = inst->result_id();
+
+    builder.AddStore(desc_set_ptr_var, desc_set_ptr_id);
+
+    inst = builder.AddUnaryOp(GetVecUintId(2), spv::Op::OpBitcast,
+                              desc_set_ptr_id);
+    const uint32_t ptr_as_uvec_id = inst->result_id();
+
+    inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {0});
+    const uint32_t uvec_x = inst->result_id();
+
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_x, zero_id);
+    const uint32_t x_is_zero_id = inst->result_id();
+
+    inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {1});
+    const uint32_t uvec_y = inst->result_id();
+
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_y, zero_id);
+    const uint32_t y_is_zero_id = inst->result_id();
+
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpLogicalAnd, x_is_zero_id,
+                               y_is_zero_id);
+    const uint32_t is_null_id = inst->result_id();
+
+    const uint32_t error_label_id = TakeNextId();
+    auto error_label = NewLabel(error_label_id);
+    const uint32_t merge_label_id = TakeNextId();
+    auto merge_label = NewLabel(merge_label_id);
+    (void)builder.AddConditionalBranch(is_null_id, error_label_id,
+                                       merge_label_id, merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+    // set error
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddStore(error_var,
+                     builder.GetUintConstantId(kInstErrorBindlessBounds));
+    builder.AddBranch(merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddBranch(skip_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+  }
 
-  inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {1});
-  const uint32_t uvec_y = inst->result_id();
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
+  builder.SetInsertPoint(&*new_blk_ptr);
 
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_y,
-                             builder.GetUintConstantId(0));
-  const uint32_t y_is_zero_id = inst->result_id();
+  check_label_id = TakeNextId();
+  check_label = NewLabel(check_label_id);
+  skip_label_id = TakeNextId();
+  skip_label = NewLabel(skip_label_id);
 
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpLogicalAnd, x_is_zero_id,
-                             y_is_zero_id);
-  const uint32_t is_null_id = inst->result_id();
+  inst = builder.AddLoad(GetUintId(), error_var);
+  error_val_id = inst->result_id();
 
-  error_blk_id = TakeNextId();
-  merge_blk_id = TakeNextId();
-  merge_label = NewLabel(merge_blk_id);
-  error_label = NewLabel(error_blk_id);
-  (void)builder.AddConditionalBranch(is_null_id, error_blk_id, merge_blk_id,
-                                     merge_blk_id);
-  func->AddBasicBlock(std::move(new_blk_ptr));
-  // error return
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
-  builder.SetInsertPoint(&*new_blk_ptr);
-  GenDebugStreamWrite(
-      param_ids[kShaderId], param_ids[kInstructionIndex], param_ids[kStageInfo],
-      {builder.GetUintConstantId(kInstErrorBindlessBounds), param_ids[kDescSet],
-       param_ids[kDescBinding], param_ids[kDescIndex],
-       builder.GetUintConstantId(0), builder.GetUintConstantId(0)},
-      &builder);
-  (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, false_id);
+  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, error_val_id,
+                             zero_id);
+  no_error_id = inst->result_id();
+  (void)builder.AddConditionalBranch(no_error_id, check_label_id, skip_label_id,
+                                     skip_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
 
   // check binding is in range
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_label));
   builder.SetInsertPoint(&*new_blk_ptr);
+  {
+    inst = builder.AddLoad(desc_set_ptr_id_, desc_set_ptr_var);
+    const uint32_t desc_set_ptr_id = inst->result_id();
+
+    inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id, {zero_id});
+    const uint32_t binding_access_chain_id = inst->result_id();
+
+    inst = builder.AddLoad(GetUintId(), binding_access_chain_id, 8);
+    const uint32_t num_bindings_id = inst->result_id();
+
+    builder.AddStore(num_bindings_var, num_bindings_id);
+
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
+                               param_ids[kDescBinding], num_bindings_id);
+    const uint32_t bindings_cmp_id = inst->result_id();
+
+    const uint32_t error_label_id = TakeNextId();
+    auto error_label = NewLabel(error_label_id);
+    const uint32_t merge_label_id = TakeNextId();
+    auto merge_label = NewLabel(merge_label_id);
+    (void)builder.AddConditionalBranch(bindings_cmp_id, error_label_id,
+                                       merge_label_id, merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+    // set error
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddStore(error_var,
+                     builder.GetUintConstantId(kInstErrorBindlessBounds));
+    builder.AddBranch(merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddBranch(skip_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+  }
 
-  const uint32_t uint_ptr = type_mgr->FindPointerToType(
-      GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
-
-  inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
-                                {builder.GetUintConstantId(0)});
-  const uint32_t binding_access_chain_id = inst->result_id();
+  // read binding length
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
+  builder.SetInsertPoint(&*new_blk_ptr);
 
-  inst = builder.AddLoad(GetUintId(), binding_access_chain_id, 8);
-  const uint32_t num_bindings_id = inst->result_id();
+  check_label_id = TakeNextId();
+  check_label = NewLabel(check_label_id);
+  skip_label_id = TakeNextId();
+  skip_label = NewLabel(skip_label_id);
 
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
-                             param_ids[kDescBinding], num_bindings_id);
-  const uint32_t bindings_cmp_id = inst->result_id();
+  inst = builder.AddLoad(GetUintId(), error_var);
+  error_val_id = inst->result_id();
 
-  error_blk_id = TakeNextId();
-  merge_blk_id = TakeNextId();
-  merge_label = NewLabel(merge_blk_id);
-  error_label = NewLabel(error_blk_id);
-  (void)builder.AddConditionalBranch(bindings_cmp_id, error_blk_id,
-                                     merge_blk_id, merge_blk_id);
-  func->AddBasicBlock(std::move(new_blk_ptr));
-  // error return
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
-  builder.SetInsertPoint(&*new_blk_ptr);
-  GenDebugStreamWrite(
-      param_ids[kShaderId], param_ids[kInstructionIndex], param_ids[kStageInfo],
-      {builder.GetUintConstantId(kInstErrorBindlessBounds), param_ids[kDescSet],
-       param_ids[kDescBinding], param_ids[kDescIndex],
-       builder.GetUintConstantId(0), builder.GetUintConstantId(0)},
-      &builder);
-  (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, false_id);
+  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, error_val_id,
+                             zero_id);
+  no_error_id = inst->result_id();
+  (void)builder.AddConditionalBranch(no_error_id, check_label_id, skip_label_id,
+                                     skip_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
 
-  // read binding length
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_label));
   builder.SetInsertPoint(&*new_blk_ptr);
+  {
+    inst = builder.AddLoad(desc_set_ptr_id_, desc_set_ptr_var);
+    const uint32_t desc_set_ptr_id = inst->result_id();
+
+    inst = builder.AddAccessChain(
+        uint_ptr, desc_set_ptr_id,
+        {{builder.GetUintConstantId(1), param_ids[kDescBinding]}});
+    const uint32_t length_ac_id = inst->result_id();
+
+    inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
+    const uint32_t length_id = inst->result_id();
+
+    // Check descriptor index in bounds
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
+                               param_ids[kDescIndex], length_id);
+    const uint32_t desc_idx_range_id = inst->result_id();
+
+    const uint32_t error_label_id = TakeNextId();
+    auto error_label = NewLabel(error_label_id);
+    const uint32_t merge_label_id = TakeNextId();
+    auto merge_label = NewLabel(merge_label_id);
+    (void)builder.AddConditionalBranch(desc_idx_range_id, error_label_id,
+                                       merge_label_id, merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+    // set error
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddStore(error_var,
+                     builder.GetUintConstantId(kInstErrorBindlessBounds));
+    builder.AddStore(param5_var, length_id);
+    builder.AddBranch(merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddBranch(skip_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+  }
 
-  inst = builder.AddAccessChain(
-      uint_ptr, desc_set_ptr_id,
-      {{builder.GetUintConstantId(1), param_ids[kDescBinding]}});
-  const uint32_t length_ac_id = inst->result_id();
-
-  inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
-  const uint32_t length_id = inst->result_id();
-
-  // Check descriptor index in bounds
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
-                             param_ids[kDescIndex], length_id);
-  const uint32_t desc_idx_range_id = inst->result_id();
-
-  error_blk_id = TakeNextId();
-  merge_blk_id = TakeNextId();
-  merge_label = NewLabel(merge_blk_id);
-  error_label = NewLabel(error_blk_id);
-  (void)builder.AddConditionalBranch(desc_idx_range_id, error_blk_id,
-                                     merge_blk_id, merge_blk_id);
-  func->AddBasicBlock(std::move(new_blk_ptr));
-  // Error return
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
   builder.SetInsertPoint(&*new_blk_ptr);
-  GenDebugStreamWrite(
-      param_ids[kShaderId], param_ids[kInstructionIndex], param_ids[kStageInfo],
-      {builder.GetUintConstantId(kInstErrorBindlessBounds), param_ids[kDescSet],
-       param_ids[kDescBinding], param_ids[kDescIndex], length_id,
-       builder.GetUintConstantId(0)},
-      &builder);
-  (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, false_id);
+  inst = builder.AddLoad(GetUintId(), error_var);
+  error_val_id = inst->result_id();
+
+  check_label_id = TakeNextId();
+  check_label = NewLabel(check_label_id);
+  skip_label_id = TakeNextId();
+  skip_label = NewLabel(skip_label_id);
+
+  inst = builder.AddLoad(GetUintId(), error_var);
+  error_val_id = inst->result_id();
+  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, zero_id,
+                             error_val_id);
+  no_error_id = inst->result_id();
+
+  (void)builder.AddConditionalBranch(no_error_id, check_label_id, skip_label_id,
+                                     skip_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
 
   // Read descriptor init status
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_label));
   builder.SetInsertPoint(&*new_blk_ptr);
+  {
+    inst = builder.AddLoad(desc_set_ptr_id_, desc_set_ptr_var);
+    const uint32_t desc_set_ptr_id = inst->result_id();
+
+    inst = builder.AddLoad(GetUintId(), num_bindings_var);
+    const uint32_t num_bindings_id = inst->result_id();
+
+    inst =
+        builder.AddIAdd(GetUintId(), num_bindings_id, param_ids[kDescBinding]);
+    const uint32_t state_offset_id = inst->result_id();
+
+    inst = builder.AddAccessChain(
+        uint_ptr, desc_set_ptr_id,
+        {{builder.GetUintConstantId(1), state_offset_id}});
+    const uint32_t state_start_ac_id = inst->result_id();
+
+    inst = builder.AddLoad(GetUintId(), state_start_ac_id, sizeof(uint32_t));
+    const uint32_t state_start_id = inst->result_id();
+
+    inst = builder.AddIAdd(GetUintId(), state_start_id, param_ids[kDescIndex]);
+    const uint32_t state_entry_id = inst->result_id();
+
+    // Note: length starts from the beginning of the buffer, not the beginning
+    // of the data array
+    inst = builder.AddAccessChain(
+        uint_ptr, desc_set_ptr_id,
+        {{builder.GetUintConstantId(1), state_entry_id}});
+    const uint32_t init_ac_id = inst->result_id();
+
+    inst = builder.AddLoad(GetUintId(), init_ac_id, sizeof(uint32_t));
+    const uint32_t init_status_id = inst->result_id();
+
+    builder.AddStore(init_status_var, init_status_id);
+
+    // Check for uninitialized descriptor
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, init_status_id,
+                               zero_id);
+    const uint32_t uninit_check_id = inst->result_id();
+    const uint32_t error_label_id = TakeNextId();
+    auto error_label = NewLabel(error_label_id);
+    const uint32_t merge_label_id = TakeNextId();
+    auto merge_label = NewLabel(merge_label_id);
+    (void)builder.AddConditionalBranch(uninit_check_id, error_label_id,
+                                       merge_label_id, merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddStore(error_var,
+                     builder.GetUintConstantId(kInstErrorBindlessUninit));
+    builder.AddBranch(merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddBranch(skip_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+  }
 
-  inst = builder.AddIAdd(GetUintId(), num_bindings_id, param_ids[kDescBinding]);
-  const uint32_t state_offset_id = inst->result_id();
-
-  inst =
-      builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
-                             {{builder.GetUintConstantId(1), state_offset_id}});
-  const uint32_t state_start_ac_id = inst->result_id();
-
-  inst = builder.AddLoad(GetUintId(), state_start_ac_id, sizeof(uint32_t));
-  const uint32_t state_start_id = inst->result_id();
-
-  inst = builder.AddIAdd(GetUintId(), state_start_id, param_ids[kDescIndex]);
-  const uint32_t state_entry_id = inst->result_id();
-
-  // Note: length starts from the beginning of the buffer, not the beginning of
-  // the data array
-  inst =
-      builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
-                             {{builder.GetUintConstantId(1), state_entry_id}});
-  const uint32_t init_ac_id = inst->result_id();
-
-  inst = builder.AddLoad(GetUintId(), init_ac_id, sizeof(uint32_t));
-  const uint32_t init_status_id = inst->result_id();
-
-  // Check for uninitialized descriptor
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, init_status_id,
-                             builder.GetUintConstantId(0));
-  const uint32_t uninit_check_id = inst->result_id();
-  error_blk_id = TakeNextId();
-  merge_blk_id = TakeNextId();
-  merge_label = NewLabel(merge_blk_id);
-  error_label = NewLabel(error_blk_id);
-  (void)builder.AddConditionalBranch(uninit_check_id, error_blk_id,
-                                     merge_blk_id, merge_blk_id);
-  func->AddBasicBlock(std::move(new_blk_ptr));
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+  // Check for OOB.
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
   builder.SetInsertPoint(&*new_blk_ptr);
-  GenDebugStreamWrite(
-      param_ids[kShaderId], param_ids[kInstructionIndex], param_ids[kStageInfo],
-      {builder.GetUintConstantId(kInstErrorBindlessUninit), param_ids[kDescSet],
-       param_ids[kDescBinding], param_ids[kDescIndex],
-       builder.GetUintConstantId(0), builder.GetUintConstantId(0)},
-      &builder);
-  (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, false_id);
+
+  check_label_id = TakeNextId();
+  check_label = NewLabel(check_label_id);
+  skip_label_id = TakeNextId();
+  skip_label = NewLabel(skip_label_id);
+
+  inst = builder.AddLoad(GetUintId(), error_var);
+  error_val_id = inst->result_id();
+
+  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, error_val_id,
+                             zero_id);
+  no_error_id = inst->result_id();
+  (void)builder.AddConditionalBranch(no_error_id, check_label_id, skip_label_id,
+                                     skip_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
 
-  // Check for OOB.
-  new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_label));
+  builder.SetInsertPoint(&*new_blk_ptr);
+  {
+    inst = builder.AddLoad(GetUintId(), init_status_var);
+    const uint32_t init_status_id = inst->result_id();
+
+    inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
+                               param_ids[kByteOffset], init_status_id);
+    const uint32_t buf_offset_range_id = inst->result_id();
+
+    const uint32_t error_label_id = TakeNextId();
+    const uint32_t merge_label_id = TakeNextId();
+    auto error_label = NewLabel(error_label_id);
+    auto merge_label = NewLabel(merge_label_id);
+    (void)builder.AddConditionalBranch(buf_offset_range_id, error_label_id,
+                                       merge_label_id, merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+
+    // set error
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddStore(error_var, builder.GetUintConstantId(kInstErrorOOB));
+    builder.AddStore(param5_var, param_ids[kByteOffset]);
+    builder.AddStore(param6_var, init_status_id);
+    builder.AddBranch(merge_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+
+    new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+    builder.SetInsertPoint(&*new_blk_ptr);
+    builder.AddBranch(skip_label_id);
+    func->AddBasicBlock(std::move(new_blk_ptr));
+  }
+
+  // check for error
+  new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
   builder.SetInsertPoint(&*new_blk_ptr);
-  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
-                             param_ids[kByteOffset], init_status_id);
-  const uint32_t buf_offset_range_id = inst->result_id();
-
-  error_blk_id = TakeNextId();
-  merge_blk_id = TakeNextId();
-  merge_label = NewLabel(merge_blk_id);
-  error_label = NewLabel(error_blk_id);
-  (void)builder.AddConditionalBranch(buf_offset_range_id, error_blk_id,
-                                     merge_blk_id, merge_blk_id);
+  inst = builder.AddLoad(GetUintId(), error_var);
+  error_val_id = inst->result_id();
+
+  inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpINotEqual, zero_id,
+                             error_val_id);
+  const uint32_t is_error_id = inst->result_id();
+
+  const uint32_t error_label_id = TakeNextId();
+  auto error_label = NewLabel(error_label_id);
+  const uint32_t merge_label_id = TakeNextId();
+  auto merge_label = NewLabel(merge_label_id);
+  (void)builder.AddConditionalBranch(is_error_id, error_label_id,
+                                     merge_label_id, merge_label_id);
   func->AddBasicBlock(std::move(new_blk_ptr));
-  // Error return
+
   new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
   builder.SetInsertPoint(&*new_blk_ptr);
+
+  // error output
+  inst = builder.AddLoad(GetUintId(), param5_var);
+  const uint32_t param5_val_id = inst->result_id();
+
+  inst = builder.AddLoad(GetUintId(), param6_var);
+  const uint32_t param6_val_id = inst->result_id();
+
   GenDebugStreamWrite(
       param_ids[kShaderId], param_ids[kInstructionIndex], param_ids[kStageInfo],
-      {builder.GetUintConstantId(kInstErrorOOB), param_ids[kDescSet],
-       param_ids[kDescBinding], param_ids[kDescIndex], param_ids[kByteOffset],
-       init_status_id},
+      {error_val_id, param_ids[kDescSet], param_ids[kDescBinding],
+       param_ids[kDescIndex], param5_val_id, param6_val_id},
       &builder);
   (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, false_id);
   func->AddBasicBlock(std::move(new_blk_ptr));

+ 44 - 0
3rdparty/spirv-tools/source/opt/optimizer.cpp

@@ -15,6 +15,7 @@
 #include "spirv-tools/optimizer.hpp"
 
 #include <cassert>
+#include <charconv>
 #include <memory>
 #include <string>
 #include <unordered_map>
@@ -549,6 +550,39 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
              pass_args.c_str());
       return false;
     }
+  } else if (pass_name == "switch-descriptorset") {
+    if (pass_args.size() == 0) {
+      Error(consumer(), nullptr, {},
+            "--switch-descriptorset requires a from:to argument.");
+      return false;
+    }
+    uint32_t from_set, to_set;
+    const char* start = pass_args.data();
+    const char* end = pass_args.data() + pass_args.size();
+
+    auto result = std::from_chars(start, end, from_set);
+    if (result.ec != std::errc()) {
+      Errorf(consumer(), nullptr, {},
+             "Invalid argument for --switch-descriptorset: %s",
+             pass_args.c_str());
+      return false;
+    }
+    start = result.ptr;
+    if (start[0] != ':') {
+      Errorf(consumer(), nullptr, {},
+             "Invalid argument for --switch-descriptorset: %s",
+             pass_args.c_str());
+      return false;
+    }
+    start++;
+    result = std::from_chars(start, end, to_set);
+    if (result.ec != std::errc() || result.ptr != end) {
+      Errorf(consumer(), nullptr, {},
+             "Invalid argument for --switch-descriptorset: %s",
+             pass_args.c_str());
+      return false;
+    }
+    RegisterPass(CreateSwitchDescriptorSetPass(from_set, to_set));
   } else {
     Errorf(consumer(), nullptr, {},
            "Unknown flag '--%s'. Use --help for a list of valid flags",
@@ -1071,6 +1105,16 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass() {
   return MakeUnique<Optimizer::PassToken::Impl>(
       MakeUnique<opt::FixFuncCallArgumentsPass>());
 }
+
+Optimizer::PassToken CreateTrimCapabilitiesPass() {
+  return MakeUnique<Optimizer::PassToken::Impl>(
+      MakeUnique<opt::TrimCapabilitiesPass>());
+}
+
+Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t from, uint32_t to) {
+  return MakeUnique<Optimizer::PassToken::Impl>(
+      MakeUnique<opt::SwitchDescriptorSetPass>(from, to));
+}
 }  // namespace spvtools
 
 extern "C" {

+ 1 - 0
3rdparty/spirv-tools/source/opt/passes.h

@@ -82,6 +82,7 @@
 #include "source/opt/strength_reduction_pass.h"
 #include "source/opt/strip_debug_info_pass.h"
 #include "source/opt/strip_nonsemantic_info_pass.h"
+#include "source/opt/switch_descriptorset_pass.h"
 #include "source/opt/trim_capabilities_pass.h"
 #include "source/opt/unify_const_pass.h"
 #include "source/opt/upgrade_memory_model.h"

+ 46 - 0
3rdparty/spirv-tools/source/opt/switch_descriptorset_pass.cpp

@@ -0,0 +1,46 @@
+// Copyright (c) 2023 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/opt/switch_descriptorset_pass.h"
+
+#include "source/opt/ir_builder.h"
+#include "source/util/string_utils.h"
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status SwitchDescriptorSetPass::Process() {
+  Status status = Status::SuccessWithoutChange;
+  auto* deco_mgr = context()->get_decoration_mgr();
+
+  for (Instruction& var : context()->types_values()) {
+    if (var.opcode() != spv::Op::OpVariable) {
+      continue;
+    }
+    auto decos = deco_mgr->GetDecorationsFor(var.result_id(), false);
+    for (const auto& deco : decos) {
+      spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u));
+      if (d == spv::Decoration::DescriptorSet &&
+          deco->GetSingleWordInOperand(2u) == ds_from_) {
+        deco->SetInOperand(2u, {ds_to_});
+        status = Status::SuccessWithChange;
+        break;
+      }
+    }
+  }
+  return status;
+}
+
+}  // namespace opt
+}  // namespace spvtools

+ 52 - 0
3rdparty/spirv-tools/source/opt/switch_descriptorset_pass.h

@@ -0,0 +1,52 @@
+// Copyright (c) 2023 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <cstdio>
+#include <memory>
+#include <queue>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "source/opt/pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// See optimizer.hpp for documentation.
+class SwitchDescriptorSetPass : public Pass {
+ public:
+  SwitchDescriptorSetPass(uint32_t ds_from, uint32_t ds_to)
+      : ds_from_(ds_from), ds_to_(ds_to) {}
+
+  const char* name() const override { return "switch-descriptorset"; }
+
+  Status Process() override;
+
+  IRContext::Analysis GetPreservedAnalyses() override {
+    // this pass preserves everything except decorations
+    uint32_t mask = ((IRContext::kAnalysisEnd << 1) - 1);
+    mask &= ~static_cast<uint32_t>(IRContext::kAnalysisDecorations);
+    return static_cast<IRContext::Analysis>(mask);
+  }
+
+ private:
+  uint32_t ds_from_;
+  uint32_t ds_to_;
+};
+
+}  // namespace opt
+}  // namespace spvtools

+ 306 - 101
3rdparty/spirv-tools/source/opt/trim_capabilities_pass.cpp

@@ -20,6 +20,7 @@
 #include <functional>
 #include <optional>
 #include <queue>
+#include <stack>
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
@@ -27,6 +28,7 @@
 #include "source/enum_set.h"
 #include "source/enum_string_mapping.h"
 #include "source/opt/ir_context.h"
+#include "source/opt/reflect.h"
 #include "source/spirv_target_env.h"
 #include "source/util/string_utils.h"
 
@@ -34,53 +36,28 @@ namespace spvtools {
 namespace opt {
 
 namespace {
-constexpr uint32_t kVariableStorageClassIndex = 0;
+constexpr uint32_t kOpTypePointerStorageClassIndex = 0;
 constexpr uint32_t kTypeArrayTypeIndex = 0;
 constexpr uint32_t kOpTypeScalarBitWidthIndex = 0;
 constexpr uint32_t kTypePointerTypeIdInIdx = 1;
-}  // namespace
-
-// ============== Begin opcode handler implementations. =======================
-//
-// Adding support for a new capability should only require adding a new handler,
-// and updating the
-// kSupportedCapabilities/kUntouchableCapabilities/kFordiddenCapabilities lists.
-//
-// Handler names follow the following convention:
-//  Handler_<Opcode>_<Capability>()
-
-static std::optional<spv::Capability> Handler_OpVariable_StorageInputOutput16(
-    const Instruction* instruction) {
-  assert(instruction->opcode() == spv::Op::OpVariable &&
-         "This handler only support OpVariable opcodes.");
-
-  // This capability is only required if the variable as an Input/Output storage
-  // class.
-  spv::StorageClass storage_class = spv::StorageClass(
-      instruction->GetSingleWordInOperand(kVariableStorageClassIndex));
-  if (storage_class != spv::StorageClass::Input &&
-      storage_class != spv::StorageClass::Output) {
-    return std::nullopt;
-  }
-
-  // This capability is only required if the type involves a 16-bit component.
-  // Quick check: are 16-bit types allowed?
-  const CapabilitySet& capabilities =
-      instruction->context()->get_feature_mgr()->GetCapabilities();
-  if (!capabilities.contains(spv::Capability::Float16) &&
-      !capabilities.contains(spv::Capability::Int16)) {
-    return std::nullopt;
-  }
 
-  // We need to walk the type definition.
-  std::queue<uint32_t> instructions_to_visit;
-  instructions_to_visit.push(instruction->type_id());
+// DFS visit of the type defined by `instruction`.
+// If `condition` is true, children of the current node are visited.
+// If `condition` is false, the children of the current node are ignored.
+template <class UnaryPredicate>
+static void DFSWhile(const Instruction* instruction, UnaryPredicate condition) {
+  std::stack<uint32_t> instructions_to_visit;
+  instructions_to_visit.push(instruction->result_id());
   const auto* def_use_mgr = instruction->context()->get_def_use_mgr();
+
   while (!instructions_to_visit.empty()) {
-    const Instruction* item =
-        def_use_mgr->GetDef(instructions_to_visit.front());
+    const Instruction* item = def_use_mgr->GetDef(instructions_to_visit.top());
     instructions_to_visit.pop();
 
+    if (!condition(item)) {
+      continue;
+    }
+
     if (item->opcode() == spv::Op::OpTypePointer) {
       instructions_to_visit.push(
           item->GetSingleWordInOperand(kTypePointerTypeIdInIdx));
@@ -102,23 +79,190 @@ static std::optional<spv::Capability> Handler_OpVariable_StorageInputOutput16(
       });
       continue;
     }
+  }
+}
 
-    if (item->opcode() != spv::Op::OpTypeInt &&
-        item->opcode() != spv::Op::OpTypeFloat) {
-      continue;
+// Walks the type defined by `instruction` (OpType* only).
+// Returns `true` if any call to `predicate` with the type/subtype returns true.
+template <class UnaryPredicate>
+static bool AnyTypeOf(const Instruction* instruction,
+                      UnaryPredicate predicate) {
+  assert(IsTypeInst(instruction->opcode()) &&
+         "AnyTypeOf called with a non-type instruction.");
+
+  bool found_one = false;
+  DFSWhile(instruction, [&found_one, predicate](const Instruction* node) {
+    if (found_one || predicate(node)) {
+      found_one = true;
+      return false;
     }
 
-    if (item->GetSingleWordInOperand(kOpTypeScalarBitWidthIndex) == 16) {
-      return spv::Capability::StorageInputOutput16;
-    }
+    return true;
+  });
+  return found_one;
+}
+
+static bool is16bitType(const Instruction* instruction) {
+  if (instruction->opcode() != spv::Op::OpTypeInt &&
+      instruction->opcode() != spv::Op::OpTypeFloat) {
+    return false;
+  }
+
+  return instruction->GetSingleWordInOperand(kOpTypeScalarBitWidthIndex) == 16;
+}
+
+static bool Has16BitCapability(const FeatureManager* feature_manager) {
+  const CapabilitySet& capabilities = feature_manager->GetCapabilities();
+  return capabilities.contains(spv::Capability::Float16) ||
+         capabilities.contains(spv::Capability::Int16);
+}
+
+}  // namespace
+
+// ============== Begin opcode handler implementations. =======================
+//
+// Adding support for a new capability should only require adding a new handler,
+// and updating the
+// kSupportedCapabilities/kUntouchableCapabilities/kFordiddenCapabilities lists.
+//
+// Handler names follow the following convention:
+//  Handler_<Opcode>_<Capability>()
+
+static std::optional<spv::Capability>
+Handler_OpTypePointer_StorageInputOutput16(const Instruction* instruction) {
+  assert(instruction->opcode() == spv::Op::OpTypePointer &&
+         "This handler only support OpTypePointer opcodes.");
+
+  // This capability is only required if the variable has an Input/Output
+  // storage class.
+  spv::StorageClass storage_class = spv::StorageClass(
+      instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+  if (storage_class != spv::StorageClass::Input &&
+      storage_class != spv::StorageClass::Output) {
+    return std::nullopt;
+  }
+
+  if (!Has16BitCapability(instruction->context()->get_feature_mgr())) {
+    return std::nullopt;
+  }
+
+  return AnyTypeOf(instruction, is16bitType)
+             ? std::optional(spv::Capability::StorageInputOutput16)
+             : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpTypePointer_StoragePushConstant16(const Instruction* instruction) {
+  assert(instruction->opcode() == spv::Op::OpTypePointer &&
+         "This handler only support OpTypePointer opcodes.");
+
+  // This capability is only required if the variable has a PushConstant storage
+  // class.
+  spv::StorageClass storage_class = spv::StorageClass(
+      instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+  if (storage_class != spv::StorageClass::PushConstant) {
+    return std::nullopt;
+  }
+
+  if (!Has16BitCapability(instruction->context()->get_feature_mgr())) {
+    return std::nullopt;
+  }
+
+  return AnyTypeOf(instruction, is16bitType)
+             ? std::optional(spv::Capability::StoragePushConstant16)
+             : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpTypePointer_StorageUniformBufferBlock16(
+    const Instruction* instruction) {
+  assert(instruction->opcode() == spv::Op::OpTypePointer &&
+         "This handler only support OpTypePointer opcodes.");
+
+  // This capability is only required if the variable has a Uniform storage
+  // class.
+  spv::StorageClass storage_class = spv::StorageClass(
+      instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+  if (storage_class != spv::StorageClass::Uniform) {
+    return std::nullopt;
+  }
+
+  if (!Has16BitCapability(instruction->context()->get_feature_mgr())) {
+    return std::nullopt;
+  }
+
+  const auto* decoration_mgr = instruction->context()->get_decoration_mgr();
+  const bool matchesCondition =
+      AnyTypeOf(instruction, [decoration_mgr](const Instruction* item) {
+        if (!decoration_mgr->HasDecoration(item->result_id(),
+                                           spv::Decoration::BufferBlock)) {
+          return false;
+        }
+
+        return AnyTypeOf(item, is16bitType);
+      });
+
+  return matchesCondition
+             ? std::optional(spv::Capability::StorageUniformBufferBlock16)
+             : std::nullopt;
+}
+
+static std::optional<spv::Capability> Handler_OpTypePointer_StorageUniform16(
+    const Instruction* instruction) {
+  assert(instruction->opcode() == spv::Op::OpTypePointer &&
+         "This handler only support OpTypePointer opcodes.");
+
+  // This capability is only required if the variable has a Uniform storage
+  // class.
+  spv::StorageClass storage_class = spv::StorageClass(
+      instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+  if (storage_class != spv::StorageClass::Uniform) {
+    return std::nullopt;
   }
 
-  return std::nullopt;
+  const auto* feature_manager = instruction->context()->get_feature_mgr();
+  if (!Has16BitCapability(feature_manager)) {
+    return std::nullopt;
+  }
+
+  const bool hasBufferBlockCapability =
+      feature_manager->GetCapabilities().contains(
+          spv::Capability::StorageUniformBufferBlock16);
+  const auto* decoration_mgr = instruction->context()->get_decoration_mgr();
+  bool found16bitType = false;
+
+  DFSWhile(instruction, [decoration_mgr, hasBufferBlockCapability,
+                         &found16bitType](const Instruction* item) {
+    if (found16bitType) {
+      return false;
+    }
+
+    if (hasBufferBlockCapability &&
+        decoration_mgr->HasDecoration(item->result_id(),
+                                      spv::Decoration::BufferBlock)) {
+      return false;
+    }
+
+    if (is16bitType(item)) {
+      found16bitType = true;
+      return false;
+    }
+
+    return true;
+  });
+
+  return found16bitType ? std::optional(spv::Capability::StorageUniform16)
+                        : std::nullopt;
 }
 
 // Opcode of interest to determine capabilities requirements.
-constexpr std::array<std::pair<spv::Op, OpcodeHandler>, 1> kOpcodeHandlers{{
-    {spv::Op::OpVariable, Handler_OpVariable_StorageInputOutput16},
+constexpr std::array<std::pair<spv::Op, OpcodeHandler>, 4> kOpcodeHandlers{{
+    // clang-format off
+    {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageInputOutput16},
+    {spv::Op::OpTypePointer, Handler_OpTypePointer_StoragePushConstant16},
+    {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniformBufferBlock16},
+    {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16}
+    // clang-format on
 }};
 
 // ==============  End opcode handler implementations.  =======================
@@ -156,57 +300,89 @@ TrimCapabilitiesPass::TrimCapabilitiesPass()
           TrimCapabilitiesPass::kUntouchableCapabilities.cend()),
       opcodeHandlers_(kOpcodeHandlers.cbegin(), kOpcodeHandlers.cend()) {}
 
-void TrimCapabilitiesPass::addInstructionRequirements(
-    Instruction* instruction, CapabilitySet* capabilities,
+void TrimCapabilitiesPass::addInstructionRequirementsForOpcode(
+    spv::Op opcode, CapabilitySet* capabilities,
     ExtensionSet* extensions) const {
-  // Ignoring OpCapability instructions.
-  if (instruction->opcode() == spv::Op::OpCapability) {
+  // Ignoring OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT
+  // because they have three possible capabilities, only one of which is needed
+  if (opcode == spv::Op::OpBeginInvocationInterlockEXT ||
+      opcode == spv::Op::OpEndInvocationInterlockEXT) {
     return;
   }
 
-  // First case: the opcode is itself gated by a capability.
-  {
-    const spv_opcode_desc_t* desc = {};
-    auto result =
-        context()->grammar().lookupOpcode(instruction->opcode(), &desc);
-    if (result == SPV_SUCCESS) {
-      addSupportedCapabilitiesToSet(desc->numCapabilities, desc->capabilities,
-                                    capabilities);
-      if (desc->minVersion <=
-          spvVersionForTargetEnv(context()->GetTargetEnv())) {
-        extensions->insert(desc->extensions,
-                           desc->extensions + desc->numExtensions);
-      }
-    }
+  const spv_opcode_desc_t* desc = {};
+  auto result = context()->grammar().lookupOpcode(opcode, &desc);
+  if (result != SPV_SUCCESS) {
+    return;
   }
 
-  // Second case: one of the opcode operand is gated by a capability.
-  const uint32_t operandCount = instruction->NumOperands();
-  for (uint32_t i = 0; i < operandCount; i++) {
-    const auto& operand = instruction->GetOperand(i);
-    // No supported capability relies on a 2+-word operand.
-    if (operand.words.size() != 1) {
-      continue;
-    }
+  addSupportedCapabilitiesToSet(desc, capabilities);
+  addSupportedExtensionsToSet(desc, extensions);
+}
 
-    // No supported capability relies on a literal string operand.
-    if (operand.type == SPV_OPERAND_TYPE_LITERAL_STRING) {
-      continue;
-    }
+void TrimCapabilitiesPass::addInstructionRequirementsForOperand(
+    const Operand& operand, CapabilitySet* capabilities,
+    ExtensionSet* extensions) const {
+  // No supported capability relies on a 2+-word operand.
+  if (operand.words.size() != 1) {
+    return;
+  }
 
+  // No supported capability relies on a literal string operand or an ID.
+  if (operand.type == SPV_OPERAND_TYPE_LITERAL_STRING ||
+      operand.type == SPV_OPERAND_TYPE_ID ||
+      operand.type == SPV_OPERAND_TYPE_RESULT_ID) {
+    return;
+  }
+
+  // case 1: Operand is a single value, can directly lookup.
+  if (!spvOperandIsConcreteMask(operand.type)) {
     const spv_operand_desc_t* desc = {};
     auto result = context()->grammar().lookupOperand(operand.type,
                                                      operand.words[0], &desc);
     if (result != SPV_SUCCESS) {
+      return;
+    }
+    addSupportedCapabilitiesToSet(desc, capabilities);
+    addSupportedExtensionsToSet(desc, extensions);
+    return;
+  }
+
+  // case 2: operand can be a bitmask, we need to decompose the lookup.
+  for (uint32_t i = 0; i < 32; i++) {
+    const uint32_t mask = (1 << i) & operand.words[0];
+    if (!mask) {
       continue;
     }
 
-    addSupportedCapabilitiesToSet(desc->numCapabilities, desc->capabilities,
-                                  capabilities);
-    if (desc->minVersion <= spvVersionForTargetEnv(context()->GetTargetEnv())) {
-      extensions->insert(desc->extensions,
-                         desc->extensions + desc->numExtensions);
+    const spv_operand_desc_t* desc = {};
+    auto result = context()->grammar().lookupOperand(operand.type, mask, &desc);
+    if (result != SPV_SUCCESS) {
+      continue;
     }
+
+    addSupportedCapabilitiesToSet(desc, capabilities);
+    addSupportedExtensionsToSet(desc, extensions);
+  }
+}
+
+void TrimCapabilitiesPass::addInstructionRequirements(
+    Instruction* instruction, CapabilitySet* capabilities,
+    ExtensionSet* extensions) const {
+  // Ignoring OpCapability and OpExtension instructions.
+  if (instruction->opcode() == spv::Op::OpCapability ||
+      instruction->opcode() == spv::Op::OpExtension) {
+    return;
+  }
+
+  addInstructionRequirementsForOpcode(instruction->opcode(), capabilities,
+                                      extensions);
+
+  // Second case: one of the opcode operand is gated by a capability.
+  const uint32_t operandCount = instruction->NumOperands();
+  for (uint32_t i = 0; i < operandCount; i++) {
+    addInstructionRequirementsForOperand(instruction->GetOperand(i),
+                                         capabilities, extensions);
   }
 
   // Last case: some complex logic needs to be run to determine capabilities.
@@ -214,12 +390,25 @@ void TrimCapabilitiesPass::addInstructionRequirements(
   for (auto it = begin; it != end; it++) {
     const OpcodeHandler handler = it->second;
     auto result = handler(instruction);
-    if (result.has_value()) {
-      capabilities->insert(*result);
+    if (!result.has_value()) {
+      continue;
     }
+
+    capabilities->insert(*result);
   }
 }
 
+void TrimCapabilitiesPass::AddExtensionsForOperand(
+    const spv_operand_type_t type, const uint32_t value,
+    ExtensionSet* extensions) const {
+  const spv_operand_desc_t* desc = nullptr;
+  spv_result_t result = context()->grammar().lookupOperand(type, value, &desc);
+  if (result != SPV_SUCCESS) {
+    return;
+  }
+  addSupportedExtensionsToSet(desc, extensions);
+}
+
 std::pair<CapabilitySet, ExtensionSet>
 TrimCapabilitiesPass::DetermineRequiredCapabilitiesAndExtensions() const {
   CapabilitySet required_capabilities;
@@ -230,6 +419,12 @@ TrimCapabilitiesPass::DetermineRequiredCapabilitiesAndExtensions() const {
                                &required_extensions);
   });
 
+  for (auto capability : required_capabilities) {
+    AddExtensionsForOperand(SPV_OPERAND_TYPE_CAPABILITY,
+                            static_cast<uint32_t>(capability),
+                            &required_extensions);
+  }
+
 #if !defined(NDEBUG)
   // Debug only. We check the outputted required capabilities against the
   // supported capabilities list. The supported capabilities list is useful for
@@ -254,11 +449,6 @@ Pass::Status TrimCapabilitiesPass::TrimUnrequiredCapabilities(
   const FeatureManager* feature_manager = context()->get_feature_mgr();
   CapabilitySet capabilities_to_trim;
   for (auto capability : feature_manager->GetCapabilities()) {
-    // Forbidden capability completely prevents trimming. Early exit.
-    if (forbiddenCapabilities_.contains(capability)) {
-      return Pass::Status::SuccessWithoutChange;
-    }
-
     // Some capabilities cannot be safely removed. Leaving them untouched.
     if (untouchableCapabilities_.contains(capability)) {
       continue;
@@ -291,9 +481,12 @@ Pass::Status TrimCapabilitiesPass::TrimUnrequiredExtensions(
 
   bool modified_module = false;
   for (auto extension : supported_extensions) {
-    if (!required_extensions.contains(extension)) {
+    if (required_extensions.contains(extension)) {
+      continue;
+    }
+
+    if (context()->RemoveExtension(extension)) {
       modified_module = true;
-      context()->RemoveExtension(extension);
     }
   }
 
@@ -301,19 +494,31 @@ Pass::Status TrimCapabilitiesPass::TrimUnrequiredExtensions(
                          : Pass::Status::SuccessWithoutChange;
 }
 
+bool TrimCapabilitiesPass::HasForbiddenCapabilities() const {
+  // EnumSet.HasAnyOf returns `true` if the given set is empty.
+  if (forbiddenCapabilities_.size() == 0) {
+    return false;
+  }
+
+  const auto& capabilities = context()->get_feature_mgr()->GetCapabilities();
+  return capabilities.HasAnyOf(forbiddenCapabilities_);
+}
+
 Pass::Status TrimCapabilitiesPass::Process() {
+  if (HasForbiddenCapabilities()) {
+    return Status::SuccessWithoutChange;
+  }
+
   auto[required_capabilities, required_extensions] =
       DetermineRequiredCapabilitiesAndExtensions();
 
-  Pass::Status status = TrimUnrequiredCapabilities(required_capabilities);
-  // If no capabilities were removed, we have no extension to trim.
-  // Note: this is true because this pass only removes unused extensions caused
-  // by unused capabilities.
-  //       This is not an extension trimming pass.
-  if (status == Pass::Status::SuccessWithoutChange) {
-    return status;
-  }
-  return TrimUnrequiredExtensions(required_extensions);
+  Pass::Status capStatus = TrimUnrequiredCapabilities(required_capabilities);
+  Pass::Status extStatus = TrimUnrequiredExtensions(required_extensions);
+
+  return capStatus == Pass::Status::SuccessWithChange ||
+                 extStatus == Pass::Status::SuccessWithChange
+             ? Pass::Status::SuccessWithChange
+             : Pass::Status::SuccessWithoutChange;
 }
 
 }  // namespace opt

+ 51 - 11
3rdparty/spirv-tools/source/opt/trim_capabilities_pass.h

@@ -27,6 +27,7 @@
 #include "source/opt/ir_context.h"
 #include "source/opt/module.h"
 #include "source/opt/pass.h"
+#include "source/spirv_target_env.h"
 
 namespace spvtools {
 namespace opt {
@@ -73,12 +74,18 @@ class TrimCapabilitiesPass : public Pass {
   // contains unsupported instruction, the pass could yield bad results.
   static constexpr std::array kSupportedCapabilities{
       // clang-format off
+      spv::Capability::FragmentShaderPixelInterlockEXT,
+      spv::Capability::FragmentShaderSampleInterlockEXT,
+      spv::Capability::FragmentShaderShadingRateInterlockEXT,
       spv::Capability::Groups,
       spv::Capability::Linkage,
       spv::Capability::MinLod,
       spv::Capability::Shader,
       spv::Capability::ShaderClockKHR,
-      spv::Capability::StorageInputOutput16
+      spv::Capability::StorageInputOutput16,
+      spv::Capability::StoragePushConstant16,
+      spv::Capability::StorageUniform16,
+      spv::Capability::StorageUniformBufferBlock16
       // clang-format on
   };
 
@@ -99,25 +106,55 @@ class TrimCapabilitiesPass : public Pass {
   TrimCapabilitiesPass(TrimCapabilitiesPass&&) = delete;
 
  private:
-  // Inserts every capability in `capabilities[capabilityCount]` supported by
-  // this pass into `output`.
-  inline void addSupportedCapabilitiesToSet(
-      uint32_t capabilityCount, const spv::Capability* const capabilities,
-      CapabilitySet* output) const {
+  // Inserts every capability listed by `descriptor` this pass supports into
+  // `output`. Expects a Descriptor like `spv_opcode_desc_t` or
+  // `spv_operand_desc_t`.
+  template <class Descriptor>
+  inline void addSupportedCapabilitiesToSet(const Descriptor* const descriptor,
+                                            CapabilitySet* output) const {
+    const uint32_t capabilityCount = descriptor->numCapabilities;
     for (uint32_t i = 0; i < capabilityCount; ++i) {
-      if (supportedCapabilities_.contains(capabilities[i])) {
-        output->insert(capabilities[i]);
+      const auto capability = descriptor->capabilities[i];
+      if (supportedCapabilities_.contains(capability)) {
+        output->insert(capability);
       }
     }
   }
 
-  // Given an `instruction`, determines the capabilities and extension it
-  // requires, and output them in `capabilities` and `extensions`. The returned
-  // capabilities form a subset of kSupportedCapabilities.
+  // Inserts every extension listed by `descriptor` required by the module into
+  // `output`. Expects a Descriptor like `spv_opcode_desc_t` or
+  // `spv_operand_desc_t`.
+  template <class Descriptor>
+  inline void addSupportedExtensionsToSet(const Descriptor* const descriptor,
+                                          ExtensionSet* output) const {
+    if (descriptor->minVersion <=
+        spvVersionForTargetEnv(context()->GetTargetEnv())) {
+      return;
+    }
+    output->insert(descriptor->extensions,
+                   descriptor->extensions + descriptor->numExtensions);
+  }
+
+  void addInstructionRequirementsForOpcode(spv::Op opcode,
+                                           CapabilitySet* capabilities,
+                                           ExtensionSet* extensions) const;
+  void addInstructionRequirementsForOperand(const Operand& operand,
+                                            CapabilitySet* capabilities,
+                                            ExtensionSet* extensions) const;
+
+  // Given an `instruction`, determines the capabilities it requires, and output
+  // them in `capabilities`. The returned capabilities form a subset of
+  // kSupportedCapabilities.
   void addInstructionRequirements(Instruction* instruction,
                                   CapabilitySet* capabilities,
                                   ExtensionSet* extensions) const;
 
+  // Given an operand `type` and `value`, adds the extensions it would require
+  // to `extensions`.
+  void AddExtensionsForOperand(const spv_operand_type_t type,
+                               const uint32_t value,
+                               ExtensionSet* extensions) const;
+
   // Returns the list of required capabilities and extensions for the module.
   // The returned capabilities form a subset of kSupportedCapabilities.
   std::pair<CapabilitySet, ExtensionSet>
@@ -134,6 +171,9 @@ class TrimCapabilitiesPass : public Pass {
   Pass::Status TrimUnrequiredExtensions(
       const ExtensionSet& required_extensions) const;
 
+  // Returns if the analyzed module contains any forbidden capability.
+  bool HasForbiddenCapabilities() const;
+
  public:
   const char* name() const override { return "trim-capabilities"; }
   Status Process() override;

+ 1 - 1
3rdparty/spirv-tools/source/print.cpp

@@ -17,7 +17,7 @@
 #if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || \
     defined(SPIRV_IOS) || defined(SPIRV_TVOS) || defined(SPIRV_FREEBSD) ||  \
     defined(SPIRV_OPENBSD) || defined(SPIRV_EMSCRIPTEN) ||                  \
-    defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU)
+    defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU) || defined(SPIRV_QNX)
 namespace spvtools {
 
 clr::reset::operator const char*() { return "\x1b[0m"; }

+ 2 - 0
3rdparty/spirv-tools/source/val/validate.cpp

@@ -381,6 +381,8 @@ spv_result_t ValidateBinaryUsingContextAndValidationState(
   for (const auto& inst : vstate->ordered_instructions()) {
     if (auto error = ValidateExecutionLimitations(*vstate, &inst)) return error;
     if (auto error = ValidateSmallTypeUses(*vstate, &inst)) return error;
+    if (auto error = ValidateQCOMImageProcessingTextureUsages(*vstate, &inst))
+      return error;
   }
 
   return SPV_SUCCESS;

+ 8 - 0
3rdparty/spirv-tools/source/val/validate.h

@@ -220,6 +220,14 @@ spv_result_t ValidateExecutionLimitations(ValidationState_t& _,
 spv_result_t ValidateSmallTypeUses(ValidationState_t& _,
                                    const Instruction* inst);
 
+/// Validates restricted uses of QCOM decorated textures
+///
+/// The textures that are decorated with some of QCOM image processing
+/// decorations must be used in the specified QCOM image processing built-in
+/// functions and not used in any other image functions.
+spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _,
+                                                      const Instruction* inst);
+
 /// @brief Validate the ID's within a SPIR-V binary
 ///
 /// @param[in] pInstructions array of instructions

+ 157 - 1
3rdparty/spirv-tools/source/val/validate_image.cpp

@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Google Inc.
+// Copyright (c) 2017 Google Inc.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
 // reserved.
 //
@@ -983,6 +983,10 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
     case spv::Op::OpImageSparseGather:
     case spv::Op::OpImageSparseDrefGather:
     case spv::Op::OpCopyObject:
+    case spv::Op::OpImageSampleWeightedQCOM:
+    case spv::Op::OpImageBoxFilterQCOM:
+    case spv::Op::OpImageBlockMatchSSDQCOM:
+    case spv::Op::OpImageBlockMatchSADQCOM:
       return true;
     case spv::Op::OpStore:
       if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true;
@@ -1086,6 +1090,18 @@ spv_result_t ValidateSampledImage(ValidationState_t& _,
       }
     }
   }
+
+  const Instruction* ld_inst;
+  {
+    int t_idx = inst->GetOperandAs<int>(2);
+    ld_inst = _.FindDef(t_idx);
+  }
+
+  if (ld_inst->opcode() == spv::Op::OpLoad) {
+    int texture_id = ld_inst->GetOperandAs<int>(2);  // variable to load
+    _.RegisterQCOMImageProcessingTextureConsumer(texture_id, ld_inst, inst);
+  }
+
   return SPV_SUCCESS;
 }
 
@@ -2129,6 +2145,56 @@ spv_result_t ValidateImageSparseTexelsResident(ValidationState_t& _,
   return SPV_SUCCESS;
 }
 
+spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id,
+                                                   spv::Decoration decor) {
+  const Instruction* si_inst = nullptr;
+  const Instruction* ld_inst = _.FindDef(id);
+  if (ld_inst->opcode() == spv::Op::OpSampledImage) {
+    si_inst = ld_inst;
+    int t_idx = si_inst->GetOperandAs<int>(2);  // texture
+    ld_inst = _.FindDef(t_idx);
+  }
+  if (ld_inst->opcode() != spv::Op::OpLoad) {
+    return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad";
+  }
+  int texture_id = ld_inst->GetOperandAs<int>(2);  // variable to load
+  if (!_.HasDecoration(texture_id, decor)) {
+    return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
+           << "Missing decoration WeightTextureQCOM/BlockMatchTextureQCOM";
+  }
+
+  return SPV_SUCCESS;
+}
+
+spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _,
+                                         const Instruction* inst) {
+  spv_result_t res = SPV_SUCCESS;
+  const spv::Op opcode = inst->opcode();
+  switch (opcode) {
+    case spv::Op::OpImageSampleWeightedQCOM: {
+      int wi_idx = inst->GetOperandAs<int>(4);  // weight
+      res = ValidateImageProcessingQCOMDecoration(
+          _, wi_idx, spv::Decoration::WeightTextureQCOM);
+      break;
+    }
+    case spv::Op::OpImageBlockMatchSSDQCOM:
+    case spv::Op::OpImageBlockMatchSADQCOM: {
+      int tgt_idx = inst->GetOperandAs<int>(2);  // target
+      res = ValidateImageProcessingQCOMDecoration(
+          _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
+      if (res != SPV_SUCCESS) break;
+      int ref_idx = inst->GetOperandAs<int>(4);  // reference
+      res = ValidateImageProcessingQCOMDecoration(
+          _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
+      break;
+    }
+    default:
+      break;
+  }
+
+  return res;
+}
+
 }  // namespace
 
 // Validates correctness of image instructions.
@@ -2248,6 +2314,12 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
     case spv::Op::OpImageSparseTexelsResident:
       return ValidateImageSparseTexelsResident(_, inst);
 
+    case spv::Op::OpImageSampleWeightedQCOM:
+    case spv::Op::OpImageBoxFilterQCOM:
+    case spv::Op::OpImageBlockMatchSSDQCOM:
+    case spv::Op::OpImageBlockMatchSADQCOM:
+      return ValidateImageProcessingQCOM(_, inst);
+
     default:
       break;
   }
@@ -2255,5 +2327,89 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
   return SPV_SUCCESS;
 }
 
+bool IsImageInstruction(const spv::Op opcode) {
+  switch (opcode) {
+    case spv::Op::OpImageSampleImplicitLod:
+    case spv::Op::OpImageSampleDrefImplicitLod:
+    case spv::Op::OpImageSampleProjImplicitLod:
+    case spv::Op::OpImageSampleProjDrefImplicitLod:
+    case spv::Op::OpImageSparseSampleImplicitLod:
+    case spv::Op::OpImageSparseSampleDrefImplicitLod:
+    case spv::Op::OpImageSparseSampleProjImplicitLod:
+    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
+
+    case spv::Op::OpImageSampleExplicitLod:
+    case spv::Op::OpImageSampleDrefExplicitLod:
+    case spv::Op::OpImageSampleProjExplicitLod:
+    case spv::Op::OpImageSampleProjDrefExplicitLod:
+    case spv::Op::OpImageSparseSampleExplicitLod:
+    case spv::Op::OpImageSparseSampleDrefExplicitLod:
+    case spv::Op::OpImageSparseSampleProjExplicitLod:
+    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
+
+    case spv::Op::OpImage:
+    case spv::Op::OpImageFetch:
+    case spv::Op::OpImageSparseFetch:
+    case spv::Op::OpImageGather:
+    case spv::Op::OpImageDrefGather:
+    case spv::Op::OpImageSparseGather:
+    case spv::Op::OpImageSparseDrefGather:
+    case spv::Op::OpImageRead:
+    case spv::Op::OpImageSparseRead:
+    case spv::Op::OpImageWrite:
+
+    case spv::Op::OpImageQueryFormat:
+    case spv::Op::OpImageQueryOrder:
+    case spv::Op::OpImageQuerySizeLod:
+    case spv::Op::OpImageQuerySize:
+    case spv::Op::OpImageQueryLod:
+    case spv::Op::OpImageQueryLevels:
+    case spv::Op::OpImageQuerySamples:
+
+    case spv::Op::OpImageSampleWeightedQCOM:
+    case spv::Op::OpImageBoxFilterQCOM:
+    case spv::Op::OpImageBlockMatchSSDQCOM:
+    case spv::Op::OpImageBlockMatchSADQCOM:
+      return true;
+    default:
+      break;
+  }
+  return false;
+}
+
+spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _,
+                                                      const Instruction* inst) {
+  const spv::Op opcode = inst->opcode();
+  if (!IsImageInstruction(opcode)) return SPV_SUCCESS;
+
+  switch (opcode) {
+    case spv::Op::OpImageSampleWeightedQCOM:
+    case spv::Op::OpImageBoxFilterQCOM:
+    case spv::Op::OpImageBlockMatchSSDQCOM:
+    case spv::Op::OpImageBlockMatchSADQCOM:
+      break;
+    default:
+      for (size_t i = 0; i < inst->operands().size(); ++i) {
+        int id = inst->GetOperandAs<int>(i);
+        const Instruction* operand_inst = _.FindDef(id);
+        if (operand_inst == nullptr) continue;
+        if (operand_inst->opcode() == spv::Op::OpLoad) {
+          if (_.IsQCOMImageProcessingTextureConsumer(id)) {
+            return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                   << "Illegal use of QCOM image processing decorated texture";
+          }
+        }
+        if (operand_inst->opcode() == spv::Op::OpSampledImage) {
+          if (_.IsQCOMImageProcessingTextureConsumer(id)) {
+            return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                   << "Illegal use of QCOM image processing decorated texture";
+          }
+        }
+      }
+      break;
+  }
+  return SPV_SUCCESS;
+}
+
 }  // namespace val
 }  // namespace spvtools

+ 2 - 0
3rdparty/spirv-tools/source/val/validate_memory.cpp

@@ -966,6 +966,8 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
     }
   }
 
+  _.RegisterQCOMImageProcessingTextureConsumer(pointer_id, inst, nullptr);
+
   return SPV_SUCCESS;
 }
 

+ 42 - 30
3rdparty/spirv-tools/source/val/validation_state.cpp

@@ -611,6 +611,18 @@ void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id,
   sampled_image_consumers_[sampled_image_id].push_back(consumer);
 }
 
+void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer(
+    uint32_t texture_id, const Instruction* consumer0,
+    const Instruction* consumer1) {
+  if (HasDecoration(texture_id, spv::Decoration::WeightTextureQCOM) ||
+      HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM)) {
+    qcom_image_processing_consumers_.insert(consumer0->id());
+    if (consumer1) {
+      qcom_image_processing_consumers_.insert(consumer1->id());
+    }
+  }
+}
+
 void ValidationState_t::RegisterStorageClassConsumer(
     spv::StorageClass storage_class, Instruction* consumer) {
   if (spvIsVulkanEnv(context()->target_env)) {
@@ -668,39 +680,39 @@ void ValidationState_t::RegisterStorageClassConsumer(
   if (storage_class == spv::StorageClass::CallableDataKHR) {
     std::string errorVUID = VkErrorID(4704);
     function(consumer->function()->id())
-        ->RegisterExecutionModelLimitation([errorVUID](
-                                               spv::ExecutionModel model,
-                                               std::string* message) {
-          if (model != spv::ExecutionModel::RayGenerationKHR &&
-              model != spv::ExecutionModel::ClosestHitKHR &&
-              model != spv::ExecutionModel::CallableKHR &&
-              model != spv::ExecutionModel::MissKHR) {
-            if (message) {
-              *message = errorVUID +
-                         "CallableDataKHR Storage Class is limited to "
-                         "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
-                         "MissKHR execution model";
-            }
-            return false;
-          }
-          return true;
-        });
+        ->RegisterExecutionModelLimitation(
+            [errorVUID](spv::ExecutionModel model, std::string* message) {
+              if (model != spv::ExecutionModel::RayGenerationKHR &&
+                  model != spv::ExecutionModel::ClosestHitKHR &&
+                  model != spv::ExecutionModel::CallableKHR &&
+                  model != spv::ExecutionModel::MissKHR) {
+                if (message) {
+                  *message =
+                      errorVUID +
+                      "CallableDataKHR Storage Class is limited to "
+                      "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
+                      "MissKHR execution model";
+                }
+                return false;
+              }
+              return true;
+            });
   } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) {
     std::string errorVUID = VkErrorID(4705);
     function(consumer->function()->id())
-        ->RegisterExecutionModelLimitation([errorVUID](
-                                               spv::ExecutionModel model,
-                                               std::string* message) {
-          if (model != spv::ExecutionModel::CallableKHR) {
-            if (message) {
-              *message = errorVUID +
-                         "IncomingCallableDataKHR Storage Class is limited to "
-                         "CallableKHR execution model";
-            }
-            return false;
-          }
-          return true;
-        });
+        ->RegisterExecutionModelLimitation(
+            [errorVUID](spv::ExecutionModel model, std::string* message) {
+              if (model != spv::ExecutionModel::CallableKHR) {
+                if (message) {
+                  *message =
+                      errorVUID +
+                      "IncomingCallableDataKHR Storage Class is limited to "
+                      "CallableKHR execution model";
+                }
+                return false;
+              }
+              return true;
+            });
   } else if (storage_class == spv::StorageClass::RayPayloadKHR) {
     std::string errorVUID = VkErrorID(4698);
     function(consumer->function()->id())

+ 18 - 0
3rdparty/spirv-tools/source/val/validation_state.h

@@ -485,6 +485,13 @@ class ValidationState_t {
   void RegisterSampledImageConsumer(uint32_t sampled_image_id,
                                     Instruction* consumer);
 
+  // Record a cons_id as a consumer of texture_id
+  // if texture 'texture_id' has a QCOM image processing decoration
+  // and consumer is a load or a sampled image instruction
+  void RegisterQCOMImageProcessingTextureConsumer(uint32_t texture_id,
+                                                  const Instruction* consumer0,
+                                                  const Instruction* consumer1);
+
   // Record a function's storage class consumer instruction
   void RegisterStorageClassConsumer(spv::StorageClass storage_class,
                                     Instruction* consumer);
@@ -792,6 +799,13 @@ class ValidationState_t {
     current_layout_section_ = section;
   }
 
+  // Check if instruction 'id' is a consumer of a texture decorated
+  // with a QCOM image processing decoration
+  bool IsQCOMImageProcessingTextureConsumer(uint32_t id) {
+    return qcom_image_processing_consumers_.find(id) !=
+           qcom_image_processing_consumers_.end();
+  }
+
  private:
   ValidationState_t(const ValidationState_t&);
 
@@ -826,6 +840,10 @@ class ValidationState_t {
   std::unordered_map<uint32_t, std::vector<Instruction*>>
       sampled_image_consumers_;
 
+  /// Stores load instructions that load textures used
+  //  in QCOM image processing functions
+  std::unordered_set<uint32_t> qcom_image_processing_consumers_;
+
   /// A map of operand IDs and their names defined by the OpName instruction
   std::unordered_map<uint32_t, std::string> operand_names_;
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio