Updated spirv-tools.

This commit is contained in:
Бранимир Караџић
2023-09-04 08:25:15 -07:00
parent 04b0560edb
commit 14ebd15e2d
27 changed files with 1945 additions and 1102 deletions

View File

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

View File

@@ -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},

File diff suppressed because one or more lines are too long

View File

@@ -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,

File diff suppressed because it is too large Load Diff

View File

@@ -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,

View File

@@ -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

View File

@@ -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_

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
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.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();
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,
builder.GetUintConstantId(0));
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,
builder.GetUintConstantId(0));
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();
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);
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));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_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);
{
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));
}
new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
builder.SetInsertPoint(&*new_blk_ptr);
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 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();
const uint32_t uint_ptr = type_mgr->FindPointerToType(
GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id, {zero_id});
const uint32_t binding_access_chain_id = inst->result_id();
inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{builder.GetUintConstantId(0)});
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();
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();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
param_ids[kDescBinding], num_bindings_id);
const uint32_t bindings_cmp_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);
func->AddBasicBlock(std::move(new_blk_ptr));
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));
}
// read binding length
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
builder.SetInsertPoint(&*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();
check_label_id = TakeNextId();
check_label = NewLabel(check_label_id);
skip_label_id = TakeNextId();
skip_label = NewLabel(skip_label_id);
inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
const uint32_t length_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), error_var);
error_val_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);
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));
// Error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
new_blk_ptr = MakeUnique<BasicBlock>(std::move(check_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(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));
}
new_blk_ptr = MakeUnique<BasicBlock>(std::move(skip_label));
builder.SetInsertPoint(&*new_blk_ptr);
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.AddIAdd(GetUintId(), num_bindings_id, param_ids[kDescBinding]);
const uint32_t state_offset_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), num_bindings_var);
const uint32_t num_bindings_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.AddIAdd(GetUintId(), num_bindings_id, param_ids[kDescBinding]);
const uint32_t state_offset_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.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.AddIAdd(GetUintId(), state_start_id, param_ids[kDescIndex]);
const uint32_t state_entry_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), state_start_ac_id, sizeof(uint32_t));
const uint32_t state_start_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.AddIAdd(GetUintId(), state_start_id, param_ids[kDescIndex]);
const uint32_t state_entry_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), init_ac_id, sizeof(uint32_t));
const uint32_t init_status_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();
// 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));
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);
func->AddBasicBlock(std::move(new_blk_ptr));
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));
}
// Check for OOB.
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
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);
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));
// Error return
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.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));
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));

View File

@@ -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" {

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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 std::nullopt;
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;
}
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

View File

@@ -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;

View File

@@ -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"; }

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

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

View File

@@ -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())

View File

@@ -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_;