From 78acbd557e4fd7edc8f07e1dc8e7f2633550914c Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:01:02 +0200 Subject: [PATCH 01/41] Add spirv-headers and spirv-tools as submodules --- .gitmodules | 6 ++++++ spirv-tools-sys/spirv-headers | 1 + spirv-tools-sys/spirv-tools | 1 + 3 files changed, 8 insertions(+) create mode 100644 .gitmodules create mode 160000 spirv-tools-sys/spirv-headers create mode 160000 spirv-tools-sys/spirv-tools diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..91c3a41ba1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "spirv-tools-sys/spirv-headers"] + path = spirv-tools-sys/spirv-headers + url = https://github.com/KhronosGroup/SPIRV-Headers.git +[submodule "spirv-tools-sys/spirv-tools"] + path = spirv-tools-sys/spirv-tools + url = https://github.com/KhronosGroup/SPIRV-Tools.git diff --git a/spirv-tools-sys/spirv-headers b/spirv-tools-sys/spirv-headers new file mode 160000 index 0000000000..05836bdba6 --- /dev/null +++ b/spirv-tools-sys/spirv-headers @@ -0,0 +1 @@ +Subproject commit 05836bdba63e7debce9fa9feaed42f20cd43af9d diff --git a/spirv-tools-sys/spirv-tools b/spirv-tools-sys/spirv-tools new file mode 160000 index 0000000000..99ad4f1e29 --- /dev/null +++ b/spirv-tools-sys/spirv-tools @@ -0,0 +1 @@ +Subproject commit 99ad4f1e29a382f2a2ec01c6a555edf6e8136c83 From ab5355953f545a6fca4539aa7bf3d380b592a52e Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:02:31 +0200 Subject: [PATCH 02/41] Add simple generator and the generated code needed for compilation --- spirv-tools-sys/generate.rs | 112 ++ spirv-tools-sys/generate.sh | 23 + spirv-tools-sys/generated/build-version.inc | 1 + .../generated/core.insts-unified1.inc | 642 +++++++++ spirv-tools-sys/generated/debuginfo.insts.inc | 38 + .../generated/enum_string_mapping.inc | 477 +++++++ spirv-tools-sys/generated/extension_enum.inc | 68 + spirv-tools-sys/generated/generators.inc | 25 + .../generated/glsl.std.450.insts.inc | 86 ++ .../nonsemantic.clspvreflection.insts.inc | 28 + .../generated/opencl.debuginfo.100.insts.inc | 40 + .../generated/opencl.std.insts.inc | 166 +++ .../generated/operand.kinds-unified1.inc | 1152 +++++++++++++++++ .../generated/spv-amd-gcn-shader.insts.inc | 7 + .../generated/spv-amd-shader-ballot.insts.inc | 8 + ...shader-explicit-vertex-parameter.insts.inc | 5 + .../spv-amd-shader-trinary-minmax.insts.inc | 13 + 17 files changed, 2891 insertions(+) create mode 100644 spirv-tools-sys/generate.rs create mode 100755 spirv-tools-sys/generate.sh create mode 100644 spirv-tools-sys/generated/build-version.inc create mode 100644 spirv-tools-sys/generated/core.insts-unified1.inc create mode 100644 spirv-tools-sys/generated/debuginfo.insts.inc create mode 100644 spirv-tools-sys/generated/enum_string_mapping.inc create mode 100644 spirv-tools-sys/generated/extension_enum.inc create mode 100644 spirv-tools-sys/generated/generators.inc create mode 100644 spirv-tools-sys/generated/glsl.std.450.insts.inc create mode 100644 spirv-tools-sys/generated/nonsemantic.clspvreflection.insts.inc create mode 100644 spirv-tools-sys/generated/opencl.debuginfo.100.insts.inc create mode 100644 spirv-tools-sys/generated/opencl.std.insts.inc create mode 100644 spirv-tools-sys/generated/operand.kinds-unified1.inc create mode 100644 spirv-tools-sys/generated/spv-amd-gcn-shader.insts.inc create mode 100644 spirv-tools-sys/generated/spv-amd-shader-ballot.insts.inc create mode 100644 spirv-tools-sys/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc create mode 100644 spirv-tools-sys/generated/spv-amd-shader-trinary-minmax.insts.inc diff --git a/spirv-tools-sys/generate.rs b/spirv-tools-sys/generate.rs new file mode 100644 index 0000000000..a4cb7fdd19 --- /dev/null +++ b/spirv-tools-sys/generate.rs @@ -0,0 +1,112 @@ +// The spirv tools use generated code, for now we just replicate the minimum +// generation we need here by calling the *shudders* python script(s) we need +// to in a simple script and commit them to source control, as they only need +// to be regenerated when spirv-headers is updated + +use std::{fs, process::Command}; + +fn python>(args: impl IntoIterator) -> Result<(), i32> { + Command::new("python") + .args(args.into_iter()) + .status() + .map_err(|_| -1) + .and_then(|es| { + if es.success() { + Ok(()) + } else { + Err(es.code().unwrap_or(-1)) + } + }) +} + +fn main() { + fs::create_dir_all("generated").expect("unable to create 'generated'"); + + python(&[ + "spirv-tools/utils/generate_grammar_tables.py", + "--spirv-core-grammar=spirv-headers/include/spirv/unified1/spirv.core.grammar.json", + "--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json", + "--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json", + "--extension-enum-output=generated/extension_enum.inc", + "--enum-string-mapping-output=generated/enum_string_mapping.inc", + ]).expect("failed to generate enum includes from spirv-headers"); + + python(&[ + "spirv-tools/utils/update_build_version.py", + "spirv-tools", + "generated/build-version.inc", + ]) + .expect("failed to generate build version from spirv-headers"); + + core_table("unified1"); + glsl_table("unified1"); + opencl_table("unified1"); + + vendor_table("spv-amd-shader-explicit-vertex-parameter", None); + vendor_table("spv-amd-shader-trinary-minmax", None); + vendor_table("spv-amd-gcn-shader", None); + vendor_table("spv-amd-shader-ballot", None); + vendor_table("debuginfo", None); + vendor_table("nonsemantic.clspvreflection", None); + vendor_table("opencl.debuginfo.100", Some("CLDEBUG100_")); + + registry_table(); +} + +fn vendor_table(which: &str, prefix: Option<&str>) { + python(&[ + "spirv-tools/utils/generate_grammar_tables.py".to_owned(), + format!( + "--extinst-vendor-grammar=spirv-headers/include/spirv/unified1/extinst.{}.grammar.json", + which + ), + format!("--vendor-insts-output=generated/{}.insts.inc", which), + format!( + "--vendor-operand-kind-prefix={}", + prefix.unwrap_or_default() + ), + ]) + .expect("failed to generate vendor table"); +} + +fn core_table(which: &str) { + python(&[ + "spirv-tools/utils/generate_grammar_tables.py".to_owned(), + "--spirv-core-grammar=spirv-headers/include/spirv/unified1/spirv.core.grammar.json".to_owned(), + format!("--core-insts-output=generated/core.insts-{}.inc", which), + "--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(), + "--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(), + format!("--operand-kinds-output=generated/operand.kinds-{}.inc", which), + ]).expect("failed to generate core table from spirv-headers"); +} + +fn registry_table() { + python(&[ + "spirv-tools/utils/generate_registry_tables.py", + "--xml=spirv-headers/include/spirv/spir-v.xml", + "--generator=generated/generators.inc", + ]) + .expect("failed to generate core table from spirv-headers"); +} + +fn glsl_table(version: &str) { + python(&[ + "spirv-tools/utils/generate_grammar_tables.py".to_owned(), + format!("--spirv-core-grammar=spirv-headers/include/spirv/{}/spirv.core.grammar.json", version), + "--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(), + "--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(), + format!("--extinst-glsl-grammar=spirv-headers/include/spirv/{}/extinst.glsl.std.450.grammar.json", version), + "--glsl-insts-output=generated/glsl.std.450.insts.inc".to_owned(), + ]).expect("failed to generate glsl table from spirv-headers"); +} + +fn opencl_table(version: &str) { + python(&[ + "spirv-tools/utils/generate_grammar_tables.py".to_owned(), + format!("--spirv-core-grammar=spirv-headers/include/spirv/{}/spirv.core.grammar.json", version), + "--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(), + "--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(), + format!("--extinst-opencl-grammar=spirv-headers/include/spirv/{}/extinst.opencl.std.100.grammar.json", version), + "--opencl-insts-output=generated/opencl.std.insts.inc".to_owned(), + ]).expect("failed to generate glsl table from spirv-headers"); +} diff --git a/spirv-tools-sys/generate.sh b/spirv-tools-sys/generate.sh new file mode 100755 index 0000000000..526554c90a --- /dev/null +++ b/spirv-tools-sys/generate.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -eu + +dir=$(dirname "$(dirname "$0")") + +if ! [ -d "${dir}/target" ]; then + mkdir "${dir}/target" +fi + +# Compile our "script" if the binary doesn't already exist +if [ "${1-}" == "-f" ] || ! [ -f "${dir}/target/generate" ]; then + echo "Compiling generate..." + + rustc -g -o "${dir}/target/generate" "${dir}/spirv-tools-sys/generate.rs" + + if [ "${1-}" == "-f" ]; then + # remove the force flag when sending the arguments to generate + shift + fi +fi + +gen=$(realpath "${dir}/target/generate") +(cd spirv-tools-sys && $gen "${@}") diff --git a/spirv-tools-sys/generated/build-version.inc b/spirv-tools-sys/generated/build-version.inc new file mode 100644 index 0000000000..594b63c26f --- /dev/null +++ b/spirv-tools-sys/generated/build-version.inc @@ -0,0 +1 @@ +"v2020.6", "SPIRV-Tools v2020.6 v2020.5-3-ge12087d6" diff --git a/spirv-tools-sys/generated/core.insts-unified1.inc b/spirv-tools-sys/generated/core.insts-unified1.inc new file mode 100644 index 0000000000..3b1ad6594c --- /dev/null +++ b/spirv-tools-sys/generated/core.insts-unified1.inc @@ -0,0 +1,642 @@ +static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddresses}; +static const SpvCapability pygen_variable_caps_AddressesPhysicalStorageBufferAddresses[] = {SpvCapabilityAddresses, SpvCapabilityPhysicalStorageBufferAddresses}; +static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer}; +static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer, SpvCapabilityPhysicalStorageBufferAddresses}; +static const SpvCapability pygen_variable_caps_AtomicFloat32AddEXTAtomicFloat64AddEXT[] = {SpvCapabilityAtomicFloat32AddEXT, SpvCapabilityAtomicFloat64AddEXT}; +static const SpvCapability pygen_variable_caps_BlockingPipesINTEL[] = {SpvCapabilityBlockingPipesINTEL}; +static const SpvCapability pygen_variable_caps_CooperativeMatrixNV[] = {SpvCapabilityCooperativeMatrixNV}; +static const SpvCapability pygen_variable_caps_DemoteToHelperInvocationEXT[] = {SpvCapabilityDemoteToHelperInvocationEXT}; +static const SpvCapability pygen_variable_caps_DerivativeControl[] = {SpvCapabilityDerivativeControl}; +static const SpvCapability pygen_variable_caps_DeviceEnqueue[] = {SpvCapabilityDeviceEnqueue}; +static const SpvCapability pygen_variable_caps_FPGARegINTEL[] = {SpvCapabilityFPGARegINTEL}; +static const SpvCapability pygen_variable_caps_FragmentMaskAMD[] = {SpvCapabilityFragmentMaskAMD}; +static const SpvCapability pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT[] = {SpvCapabilityFragmentShaderSampleInterlockEXT, SpvCapabilityFragmentShaderPixelInterlockEXT, SpvCapabilityFragmentShaderShadingRateInterlockEXT}; +static const SpvCapability pygen_variable_caps_FunctionPointersINTEL[] = {SpvCapabilityFunctionPointersINTEL}; +static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry}; +static const SpvCapability pygen_variable_caps_GeometryStreams[] = {SpvCapabilityGeometryStreams}; +static const SpvCapability pygen_variable_caps_GroupNonUniform[] = {SpvCapabilityGroupNonUniform}; +static const SpvCapability pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformArithmetic, SpvCapabilityGroupNonUniformClustered, SpvCapabilityGroupNonUniformPartitionedNV}; +static const SpvCapability pygen_variable_caps_GroupNonUniformBallot[] = {SpvCapabilityGroupNonUniformBallot}; +static const SpvCapability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformPartitionedNV}; +static const SpvCapability pygen_variable_caps_GroupNonUniformQuad[] = {SpvCapabilityGroupNonUniformQuad}; +static const SpvCapability pygen_variable_caps_GroupNonUniformShuffle[] = {SpvCapabilityGroupNonUniformShuffle}; +static const SpvCapability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {SpvCapabilityGroupNonUniformShuffleRelative}; +static const SpvCapability pygen_variable_caps_GroupNonUniformVote[] = {SpvCapabilityGroupNonUniformVote}; +static const SpvCapability pygen_variable_caps_Groups[] = {SpvCapabilityGroups}; +static const SpvCapability pygen_variable_caps_ImageFootprintNV[] = {SpvCapabilityImageFootprintNV}; +static const SpvCapability pygen_variable_caps_ImageQuery[] = {SpvCapabilityImageQuery}; +static const SpvCapability pygen_variable_caps_IntegerFunctions2INTEL[] = {SpvCapabilityIntegerFunctions2INTEL}; +static const SpvCapability pygen_variable_caps_Kernel[] = {SpvCapabilityKernel}; +static const SpvCapability pygen_variable_caps_KernelImageQuery[] = {SpvCapabilityKernel, SpvCapabilityImageQuery}; +static const SpvCapability pygen_variable_caps_LiteralSampler[] = {SpvCapabilityLiteralSampler}; +static const SpvCapability pygen_variable_caps_Matrix[] = {SpvCapabilityMatrix}; +static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_NamedBarrier[] = {SpvCapabilityNamedBarrier}; +static const SpvCapability pygen_variable_caps_PipeStorage[] = {SpvCapabilityPipeStorage}; +static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes}; +static const SpvCapability pygen_variable_caps_RayQueryProvisionalKHR[] = {SpvCapabilityRayQueryProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingProvisionalKHRRayQueryProvisionalKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingProvisionalKHR, SpvCapabilityRayQueryProvisionalKHR}; +static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader}; +static const SpvCapability pygen_variable_caps_ShaderClockKHR[] = {SpvCapabilityShaderClockKHR}; +static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency}; +static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupBallotKHR[] = {SpvCapabilitySubgroupBallotKHR}; +static const SpvCapability pygen_variable_caps_SubgroupBufferBlockIOINTEL[] = {SpvCapabilitySubgroupBufferBlockIOINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupDispatch[] = {SpvCapabilitySubgroupDispatch}; +static const SpvCapability pygen_variable_caps_SubgroupImageBlockIOINTEL[] = {SpvCapabilitySubgroupImageBlockIOINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupImageMediaBlockIOINTEL[] = {SpvCapabilitySubgroupImageMediaBlockIOINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupShuffleINTEL[] = {SpvCapabilitySubgroupShuffleINTEL}; +static const SpvCapability pygen_variable_caps_SubgroupVoteKHR[] = {SpvCapabilitySubgroupVoteKHR}; +static const SpvCapability pygen_variable_caps_UnstructuredLoopControlsINTEL[] = {SpvCapabilityUnstructuredLoopControlsINTEL}; + +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_decorate_string, spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_blocking_pipes[] = {spvtools::Extension::kSPV_INTEL_blocking_pipes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_reg[] = {spvtools::Extension::kSPV_INTEL_fpga_reg}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_function_pointers[] = {spvtools::Extension::kSPV_INTEL_function_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_terminate_invocation[] = {spvtools::Extension::kSPV_KHR_terminate_invocation}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint}; +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", SpvOpNop, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Undef", SpvOpUndef, 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", SpvOpSourceContinued, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Source", SpvOpSource, 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", SpvOpSourceExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Name", SpvOpName, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MemberName", SpvOpMemberName, 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", SpvOpString, 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", SpvOpLine, 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", SpvOpExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ExtInstImport", SpvOpExtInstImport, 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", SpvOpExtInst, 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", SpvOpMemoryModel, 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", SpvOpEntryPoint, 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", SpvOpExecutionMode, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Capability", SpvOpCapability, 0, nullptr, 1, {SPV_OPERAND_TYPE_CAPABILITY}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeVoid", SpvOpTypeVoid, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeBool", SpvOpTypeBool, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeInt", SpvOpTypeInt, 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", SpvOpTypeFloat, 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", SpvOpTypeVector, 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", SpvOpTypeMatrix, 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", SpvOpTypeImage, 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", SpvOpTypeSampler, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeSampledImage", SpvOpTypeSampledImage, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeArray", SpvOpTypeArray, 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", SpvOpTypeRuntimeArray, 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", SpvOpTypeStruct, 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", SpvOpTypeOpaque, 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", SpvOpTypePointer, 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", SpvOpTypeFunction, 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", SpvOpTypeEvent, 1, pygen_variable_caps_Kernel, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeDeviceEvent", SpvOpTypeDeviceEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeReserveId", SpvOpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeQueue", SpvOpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypePipe", SpvOpTypePipe, 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", SpvOpTypeForwardPointer, 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", SpvOpConstantTrue, 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", SpvOpConstantFalse, 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", SpvOpConstant, 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", SpvOpConstantComposite, 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", SpvOpConstantSampler, 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", SpvOpConstantNull, 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", SpvOpSpecConstantTrue, 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", SpvOpSpecConstantFalse, 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", SpvOpSpecConstant, 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", SpvOpSpecConstantComposite, 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", SpvOpSpecConstantOp, 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", SpvOpFunction, 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", SpvOpFunctionParameter, 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", SpvOpFunctionEnd, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FunctionCall", SpvOpFunctionCall, 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", SpvOpVariable, 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", SpvOpImageTexelPointer, 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", SpvOpLoad, 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", SpvOpStore, 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", SpvOpCopyMemory, 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", SpvOpCopyMemorySized, 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", SpvOpAccessChain, 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", SpvOpInBoundsAccessChain, 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", SpvOpPtrAccessChain, 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", SpvOpArrayLength, 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", SpvOpGenericPtrMemSemantics, 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", SpvOpInBoundsPtrAccessChain, 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", SpvOpDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MemberDecorate", SpvOpMemberDecorate, 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", SpvOpDecorationGroup, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupDecorate", SpvOpGroupDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupMemberDecorate", SpvOpGroupMemberDecorate, 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", SpvOpVectorExtractDynamic, 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", SpvOpVectorInsertDynamic, 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", SpvOpVectorShuffle, 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", SpvOpCompositeConstruct, 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", SpvOpCompositeExtract, 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", SpvOpCompositeInsert, 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", SpvOpCopyObject, 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", SpvOpTranspose, 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", SpvOpSampledImage, 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", SpvOpImageSampleImplicitLod, 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", SpvOpImageSampleExplicitLod, 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", SpvOpImageSampleDrefImplicitLod, 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", SpvOpImageSampleDrefExplicitLod, 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", SpvOpImageSampleProjImplicitLod, 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", SpvOpImageSampleProjExplicitLod, 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", SpvOpImageSampleProjDrefImplicitLod, 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", SpvOpImageSampleProjDrefExplicitLod, 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", SpvOpImageFetch, 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", SpvOpImageGather, 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", SpvOpImageDrefGather, 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", SpvOpImageRead, 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", SpvOpImageWrite, 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", SpvOpImage, 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", SpvOpImageQueryFormat, 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", SpvOpImageQueryOrder, 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", SpvOpImageQuerySizeLod, 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", SpvOpImageQuerySize, 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", SpvOpImageQueryLod, 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", SpvOpImageQueryLevels, 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", SpvOpImageQuerySamples, 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", SpvOpConvertFToU, 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", SpvOpConvertFToS, 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", SpvOpConvertSToF, 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", SpvOpConvertUToF, 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", SpvOpUConvert, 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", SpvOpSConvert, 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", SpvOpFConvert, 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", SpvOpQuantizeToF16, 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", SpvOpConvertPtrToU, 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", SpvOpSatConvertSToU, 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", SpvOpSatConvertUToS, 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", SpvOpConvertUToPtr, 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", SpvOpPtrCastToGeneric, 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", SpvOpGenericCastToPtr, 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", SpvOpGenericCastToPtrExplicit, 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", SpvOpBitcast, 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", SpvOpSNegate, 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", SpvOpFNegate, 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", SpvOpIAdd, 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", SpvOpFAdd, 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", SpvOpISub, 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", SpvOpFSub, 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", SpvOpIMul, 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", SpvOpFMul, 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", SpvOpUDiv, 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", SpvOpSDiv, 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", SpvOpFDiv, 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", SpvOpUMod, 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", SpvOpSRem, 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", SpvOpSMod, 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", SpvOpFRem, 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", SpvOpFMod, 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", SpvOpVectorTimesScalar, 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", SpvOpMatrixTimesScalar, 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", SpvOpVectorTimesMatrix, 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", SpvOpMatrixTimesVector, 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", SpvOpMatrixTimesMatrix, 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", SpvOpOuterProduct, 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", SpvOpDot, 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", SpvOpIAddCarry, 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", SpvOpISubBorrow, 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", SpvOpUMulExtended, 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", SpvOpSMulExtended, 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", SpvOpAny, 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", SpvOpAll, 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", SpvOpIsNan, 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", SpvOpIsInf, 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", SpvOpIsFinite, 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", SpvOpIsNormal, 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", SpvOpSignBitSet, 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", SpvOpLessOrGreater, 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}, + {"Ordered", SpvOpOrdered, 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", SpvOpUnordered, 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", SpvOpLogicalEqual, 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", SpvOpLogicalNotEqual, 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", SpvOpLogicalOr, 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", SpvOpLogicalAnd, 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", SpvOpLogicalNot, 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", SpvOpSelect, 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", SpvOpIEqual, 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", SpvOpINotEqual, 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", SpvOpUGreaterThan, 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", SpvOpSGreaterThan, 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", SpvOpUGreaterThanEqual, 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", SpvOpSGreaterThanEqual, 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", SpvOpULessThan, 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", SpvOpSLessThan, 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", SpvOpULessThanEqual, 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", SpvOpSLessThanEqual, 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", SpvOpFOrdEqual, 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", SpvOpFUnordEqual, 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", SpvOpFOrdNotEqual, 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", SpvOpFUnordNotEqual, 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", SpvOpFOrdLessThan, 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", SpvOpFUnordLessThan, 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", SpvOpFOrdGreaterThan, 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", SpvOpFUnordGreaterThan, 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", SpvOpFOrdLessThanEqual, 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", SpvOpFUnordLessThanEqual, 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", SpvOpFOrdGreaterThanEqual, 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", SpvOpFUnordGreaterThanEqual, 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", SpvOpShiftRightLogical, 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", SpvOpShiftRightArithmetic, 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", SpvOpShiftLeftLogical, 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", SpvOpBitwiseOr, 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", SpvOpBitwiseXor, 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", SpvOpBitwiseAnd, 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", SpvOpNot, 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", SpvOpBitFieldInsert, 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_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitFieldSExtract", SpvOpBitFieldSExtract, 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_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitFieldUExtract", SpvOpBitFieldUExtract, 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_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitReverse", SpvOpBitReverse, 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}, + {"BitCount", SpvOpBitCount, 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", SpvOpDPdx, 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", SpvOpDPdy, 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", SpvOpFwidth, 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", SpvOpDPdxFine, 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", SpvOpDPdyFine, 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", SpvOpFwidthFine, 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", SpvOpDPdxCoarse, 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", SpvOpDPdyCoarse, 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", SpvOpFwidthCoarse, 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", SpvOpEmitVertex, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EndPrimitive", SpvOpEndPrimitive, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EmitStreamVertex", SpvOpEmitStreamVertex, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EndStreamPrimitive", SpvOpEndStreamPrimitive, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ControlBarrier", SpvOpControlBarrier, 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", SpvOpMemoryBarrier, 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", SpvOpAtomicLoad, 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", SpvOpAtomicStore, 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", SpvOpAtomicExchange, 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", SpvOpAtomicCompareExchange, 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", SpvOpAtomicCompareExchangeWeak, 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", SpvOpAtomicIIncrement, 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", SpvOpAtomicIDecrement, 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", SpvOpAtomicIAdd, 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", SpvOpAtomicISub, 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", SpvOpAtomicSMin, 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", SpvOpAtomicUMin, 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", SpvOpAtomicSMax, 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", SpvOpAtomicUMax, 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", SpvOpAtomicAnd, 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", SpvOpAtomicOr, 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", SpvOpAtomicXor, 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", SpvOpPhi, 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", SpvOpLoopMerge, 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", SpvOpSelectionMerge, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SELECTION_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Label", SpvOpLabel, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Branch", SpvOpBranch, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BranchConditional", SpvOpBranchConditional, 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", SpvOpSwitch, 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", SpvOpKill, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Return", SpvOpReturn, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReturnValue", SpvOpReturnValue, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unreachable", SpvOpUnreachable, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LifetimeStart", SpvOpLifetimeStart, 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", SpvOpLifetimeStop, 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", SpvOpGroupAsyncCopy, 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", SpvOpGroupWaitEvents, 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", SpvOpGroupAll, 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", SpvOpGroupAny, 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", SpvOpGroupBroadcast, 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", SpvOpGroupIAdd, 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", SpvOpGroupFAdd, 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", SpvOpGroupFMin, 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", SpvOpGroupUMin, 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", SpvOpGroupSMin, 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", SpvOpGroupFMax, 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", SpvOpGroupUMax, 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", SpvOpGroupSMax, 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", SpvOpReadPipe, 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", SpvOpWritePipe, 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", SpvOpReservedReadPipe, 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", SpvOpReservedWritePipe, 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", SpvOpReserveReadPipePackets, 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", SpvOpReserveWritePipePackets, 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", SpvOpCommitReadPipe, 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", SpvOpCommitWritePipe, 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", SpvOpIsValidReserveId, 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", SpvOpGetNumPipePackets, 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", SpvOpGetMaxPipePackets, 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", SpvOpGroupReserveReadPipePackets, 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", SpvOpGroupReserveWritePipePackets, 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", SpvOpGroupCommitReadPipe, 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", SpvOpGroupCommitWritePipe, 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", SpvOpEnqueueMarker, 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", SpvOpEnqueueKernel, 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", SpvOpGetKernelNDrangeSubGroupCount, 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", SpvOpGetKernelNDrangeMaxSubGroupSize, 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", SpvOpGetKernelWorkGroupSize, 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", SpvOpGetKernelPreferredWorkGroupSizeMultiple, 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", SpvOpRetainEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReleaseEvent", SpvOpReleaseEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CreateUserEvent", SpvOpCreateUserEvent, 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", SpvOpIsValidEvent, 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", SpvOpSetUserEventStatus, 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", SpvOpCaptureEventProfilingInfo, 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", SpvOpGetDefaultQueue, 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", SpvOpBuildNDRange, 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", SpvOpImageSparseSampleImplicitLod, 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", SpvOpImageSparseSampleExplicitLod, 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", SpvOpImageSparseSampleDrefImplicitLod, 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", SpvOpImageSparseSampleDrefExplicitLod, 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", SpvOpImageSparseSampleProjImplicitLod, 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", SpvOpImageSparseSampleProjExplicitLod, 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", SpvOpImageSparseSampleProjDrefImplicitLod, 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", SpvOpImageSparseSampleProjDrefExplicitLod, 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", SpvOpImageSparseFetch, 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", SpvOpImageSparseGather, 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", SpvOpImageSparseDrefGather, 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", SpvOpImageSparseTexelsResident, 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", SpvOpNoLine, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicFlagTestAndSet", SpvOpAtomicFlagTestAndSet, 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", SpvOpAtomicFlagClear, 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", SpvOpImageSparseRead, 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", SpvOpSizeOf, 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", SpvOpTypePipeStorage, 1, pygen_variable_caps_PipeStorage, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ConstantPipeStorage", SpvOpConstantPipeStorage, 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}, + {"CreatePipeFromPipeStorage", SpvOpCreatePipeFromPipeStorage, 1, pygen_variable_caps_PipeStorage, 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}, + {"GetKernelLocalSizeForSubgroupCount", SpvOpGetKernelLocalSizeForSubgroupCount, 1, pygen_variable_caps_SubgroupDispatch, 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,1), 0xffffffffu}, + {"GetKernelMaxNumSubgroups", SpvOpGetKernelMaxNumSubgroups, 1, pygen_variable_caps_SubgroupDispatch, 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,1), 0xffffffffu}, + {"TypeNamedBarrier", SpvOpTypeNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"NamedBarrierInitialize", SpvOpNamedBarrierInitialize, 1, pygen_variable_caps_NamedBarrier, 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}, + {"MemoryNamedBarrier", SpvOpMemoryNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 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,1), 0xffffffffu}, + {"ModuleProcessed", SpvOpModuleProcessed, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ExecutionModeId", SpvOpExecutionModeId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"DecorateId", SpvOpDecorateId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"GroupNonUniformElect", SpvOpGroupNonUniformElect, 1, pygen_variable_caps_GroupNonUniform, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformAll", SpvOpGroupNonUniformAll, 1, pygen_variable_caps_GroupNonUniformVote, 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,3), 0xffffffffu}, + {"GroupNonUniformAny", SpvOpGroupNonUniformAny, 1, pygen_variable_caps_GroupNonUniformVote, 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,3), 0xffffffffu}, + {"GroupNonUniformAllEqual", SpvOpGroupNonUniformAllEqual, 1, pygen_variable_caps_GroupNonUniformVote, 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,3), 0xffffffffu}, + {"GroupNonUniformBroadcast", SpvOpGroupNonUniformBroadcast, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformBroadcastFirst", SpvOpGroupNonUniformBroadcastFirst, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformBallot", SpvOpGroupNonUniformBallot, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformInverseBallot", SpvOpGroupNonUniformInverseBallot, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformBallotBitExtract", SpvOpGroupNonUniformBallotBitExtract, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformBallotBitCount", SpvOpGroupNonUniformBallotBitCount, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformBallotFindLSB", SpvOpGroupNonUniformBallotFindLSB, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformBallotFindMSB", SpvOpGroupNonUniformBallotFindMSB, 1, pygen_variable_caps_GroupNonUniformBallot, 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,3), 0xffffffffu}, + {"GroupNonUniformShuffle", SpvOpGroupNonUniformShuffle, 1, pygen_variable_caps_GroupNonUniformShuffle, 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,3), 0xffffffffu}, + {"GroupNonUniformShuffleXor", SpvOpGroupNonUniformShuffleXor, 1, pygen_variable_caps_GroupNonUniformShuffle, 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,3), 0xffffffffu}, + {"GroupNonUniformShuffleUp", SpvOpGroupNonUniformShuffleUp, 1, pygen_variable_caps_GroupNonUniformShuffleRelative, 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,3), 0xffffffffu}, + {"GroupNonUniformShuffleDown", SpvOpGroupNonUniformShuffleDown, 1, pygen_variable_caps_GroupNonUniformShuffleRelative, 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,3), 0xffffffffu}, + {"GroupNonUniformIAdd", SpvOpGroupNonUniformIAdd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFAdd", SpvOpGroupNonUniformFAdd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformIMul", SpvOpGroupNonUniformIMul, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFMul", SpvOpGroupNonUniformFMul, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformSMin", SpvOpGroupNonUniformSMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformUMin", SpvOpGroupNonUniformUMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFMin", SpvOpGroupNonUniformFMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformSMax", SpvOpGroupNonUniformSMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformUMax", SpvOpGroupNonUniformUMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFMax", SpvOpGroupNonUniformFMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBitwiseAnd", SpvOpGroupNonUniformBitwiseAnd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBitwiseOr", SpvOpGroupNonUniformBitwiseOr, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBitwiseXor", SpvOpGroupNonUniformBitwiseXor, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformLogicalAnd", SpvOpGroupNonUniformLogicalAnd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformLogicalOr", SpvOpGroupNonUniformLogicalOr, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformLogicalXor", SpvOpGroupNonUniformLogicalXor, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformQuadBroadcast", SpvOpGroupNonUniformQuadBroadcast, 1, pygen_variable_caps_GroupNonUniformQuad, 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,3), 0xffffffffu}, + {"GroupNonUniformQuadSwap", SpvOpGroupNonUniformQuadSwap, 1, pygen_variable_caps_GroupNonUniformQuad, 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,3), 0xffffffffu}, + {"CopyLogical", SpvOpCopyLogical, 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,4), 0xffffffffu}, + {"PtrEqual", SpvOpPtrEqual, 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,4), 0xffffffffu}, + {"PtrNotEqual", SpvOpPtrNotEqual, 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,4), 0xffffffffu}, + {"PtrDiff", SpvOpPtrDiff, 3, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer, 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,4), 0xffffffffu}, + {"TerminateInvocation", SpvOpTerminateInvocation, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_terminate_invocation, 0xffffffffu, 0xffffffffu}, + {"SubgroupBallotKHR", SpvOpSubgroupBallotKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"SubgroupFirstInvocationKHR", SpvOpSubgroupFirstInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"SubgroupAllKHR", SpvOpSubgroupAllKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"SubgroupAnyKHR", SpvOpSubgroupAnyKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"SubgroupAllEqualKHR", SpvOpSubgroupAllEqualKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"SubgroupReadInvocationKHR", SpvOpSubgroupReadInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 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_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"TypeRayQueryProvisionalKHR", SpvOpTypeRayQueryProvisionalKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryInitializeKHR", SpvOpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 8, {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, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryTerminateKHR", SpvOpRayQueryTerminateKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGenerateIntersectionKHR", SpvOpRayQueryGenerateIntersectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryConfirmIntersectionKHR", SpvOpRayQueryConfirmIntersectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryProceedKHR", SpvOpRayQueryProceedKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionTypeKHR", SpvOpRayQueryGetIntersectionTypeKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"GroupIAddNonUniformAMD", SpvOpGroupIAddNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupFAddNonUniformAMD", SpvOpGroupFAddNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupFMinNonUniformAMD", SpvOpGroupFMinNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupUMinNonUniformAMD", SpvOpGroupUMinNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupSMinNonUniformAMD", SpvOpGroupSMinNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupFMaxNonUniformAMD", SpvOpGroupFMaxNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupUMaxNonUniformAMD", SpvOpGroupUMaxNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupSMaxNonUniformAMD", SpvOpGroupSMaxNonUniformAMD, 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, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"FragmentMaskFetchAMD", SpvOpFragmentMaskFetchAMD, 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", SpvOpFragmentFetchAMD, 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", SpvOpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_clock, 0xffffffffu, 0xffffffffu}, + {"ImageSampleFootprintNV", SpvOpImageSampleFootprintNV, 1, pygen_variable_caps_ImageFootprintNV, 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_OPTIONAL_IMAGE}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformPartitionNV", SpvOpGroupNonUniformPartitionNV, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, 0xffffffffu, 0xffffffffu}, + {"WritePackedPrimitiveIndices4x8NV", SpvOpWritePackedPrimitiveIndices4x8NV, 1, pygen_variable_caps_MeshShadingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_mesh_shader, 0xffffffffu, 0xffffffffu}, + {"ReportIntersectionKHR", SpvOpReportIntersectionKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ReportIntersectionNV", SpvOpReportIntersectionNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"IgnoreIntersectionKHR", SpvOpIgnoreIntersectionKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"IgnoreIntersectionNV", SpvOpIgnoreIntersectionNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TerminateRayKHR", SpvOpTerminateRayKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TerminateRayNV", SpvOpTerminateRayNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TraceNV", SpvOpTraceNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 11, {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, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TraceRayKHR", SpvOpTraceRayKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 11, {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, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TypeAccelerationStructureKHR", SpvOpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHRRayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"TypeAccelerationStructureNV", SpvOpTypeAccelerationStructureNV, 3, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHRRayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"ExecuteCallableKHR", SpvOpExecuteCallableKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ExecuteCallableNV", SpvOpExecuteCallableNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TypeCooperativeMatrixNV", SpvOpTypeCooperativeMatrixNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLoadNV", SpvOpCooperativeMatrixLoadNV, 1, pygen_variable_caps_CooperativeMatrixNV, 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_MEMORY_ACCESS}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixStoreNV", SpvOpCooperativeMatrixStoreNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixMulAddNV", SpvOpCooperativeMatrixMulAddNV, 1, pygen_variable_caps_CooperativeMatrixNV, 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_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLengthNV", SpvOpCooperativeMatrixLengthNV, 1, pygen_variable_caps_CooperativeMatrixNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"BeginInvocationInterlockEXT", SpvOpBeginInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu}, + {"EndInvocationInterlockEXT", SpvOpEndInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu}, + {"DemoteToHelperInvocationEXT", SpvOpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, 0xffffffffu, 0xffffffffu}, + {"IsHelperInvocationEXT", SpvOpIsHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleINTEL", SpvOpSubgroupShuffleINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleDownINTEL", SpvOpSubgroupShuffleDownINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleUpINTEL", SpvOpSubgroupShuffleUpINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleXorINTEL", SpvOpSubgroupShuffleXorINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupBlockReadINTEL", SpvOpSubgroupBlockReadINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupBlockWriteINTEL", SpvOpSubgroupBlockWriteINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockReadINTEL", SpvOpSubgroupImageBlockReadINTEL, 1, pygen_variable_caps_SubgroupImageBlockIOINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockWriteINTEL", SpvOpSubgroupImageBlockWriteINTEL, 1, pygen_variable_caps_SubgroupImageBlockIOINTEL, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageMediaBlockReadINTEL", SpvOpSubgroupImageMediaBlockReadINTEL, 1, pygen_variable_caps_SubgroupImageMediaBlockIOINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageMediaBlockWriteINTEL", SpvOpSubgroupImageMediaBlockWriteINTEL, 1, pygen_variable_caps_SubgroupImageMediaBlockIOINTEL, 5, {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}, + {"UCountLeadingZerosINTEL", SpvOpUCountLeadingZerosINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UCountTrailingZerosINTEL", SpvOpUCountTrailingZerosINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AbsISubINTEL", SpvOpAbsISubINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AbsUSubINTEL", SpvOpAbsUSubINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IAddSatINTEL", SpvOpIAddSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UAddSatINTEL", SpvOpUAddSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IAverageINTEL", SpvOpIAverageINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UAverageINTEL", SpvOpUAverageINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IAverageRoundedINTEL", SpvOpIAverageRoundedINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UAverageRoundedINTEL", SpvOpUAverageRoundedINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ISubSatINTEL", SpvOpISubSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"USubSatINTEL", SpvOpUSubSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IMul32x16INTEL", SpvOpIMul32x16INTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UMul32x16INTEL", SpvOpUMul32x16INTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FunctionPointerINTEL", SpvOpFunctionPointerINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu}, + {"FunctionPointerCallINTEL", SpvOpFunctionPointerCallINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu}, + {"DecorateString", SpvOpDecorateString, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"DecorateStringGOOGLE", SpvOpDecorateStringGOOGLE, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"MemberDecorateString", SpvOpMemberDecorateString, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"MemberDecorateStringGOOGLE", SpvOpMemberDecorateStringGOOGLE, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"VmeImageINTEL", SpvOpVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeVmeImageINTEL", SpvOpTypeVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImePayloadINTEL", SpvOpTypeAvcImePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcRefPayloadINTEL", SpvOpTypeAvcRefPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcSicPayloadINTEL", SpvOpTypeAvcSicPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcMcePayloadINTEL", SpvOpTypeAvcMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcMceResultINTEL", SpvOpTypeAvcMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultINTEL", SpvOpTypeAvcImeResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultSingleReferenceStreamoutINTEL", SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultDualReferenceStreamoutINTEL", SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeSingleReferenceStreaminINTEL", SpvOpTypeAvcImeSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeDualReferenceStreaminINTEL", SpvOpTypeAvcImeDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcRefResultINTEL", SpvOpTypeAvcRefResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcSicResultINTEL", SpvOpTypeAvcSicResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterShapePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetInterShapePenaltyINTEL", SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetInterDirectionPenaltyINTEL", SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetMotionVectorCostFunctionINTEL", SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetAcOnlyHaarINTEL", SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToImePayloadINTEL", SpvOpSubgroupAvcMceConvertToImePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToImeResultINTEL", SpvOpSubgroupAvcMceConvertToImeResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToRefPayloadINTEL", SpvOpSubgroupAvcMceConvertToRefPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToRefResultINTEL", SpvOpSubgroupAvcMceConvertToRefResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToSicPayloadINTEL", SpvOpSubgroupAvcMceConvertToSicPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToSicResultINTEL", SpvOpSubgroupAvcMceConvertToSicResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetMotionVectorsINTEL", SpvOpSubgroupAvcMceGetMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterDistortionsINTEL", SpvOpSubgroupAvcMceGetInterDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetBestInterDistortionsINTEL", SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterMajorShapeINTEL", SpvOpSubgroupAvcMceGetInterMajorShapeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterMinorShapeINTEL", SpvOpSubgroupAvcMceGetInterMinorShapeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterDirectionsINTEL", SpvOpSubgroupAvcMceGetInterDirectionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterMotionVectorCountINTEL", SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterReferenceIdsINTEL", SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeInitializeINTEL", SpvOpSubgroupAvcImeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetSingleReferenceINTEL", SpvOpSubgroupAvcImeSetSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetDualReferenceINTEL", SpvOpSubgroupAvcImeSetDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeRefWindowSizeINTEL", SpvOpSubgroupAvcImeRefWindowSizeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeAdjustRefOffsetINTEL", SpvOpSubgroupAvcImeAdjustRefOffsetINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeConvertToMcePayloadINTEL", SpvOpSubgroupAvcImeConvertToMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetMaxMotionVectorCountINTEL", SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetUnidirectionalMixDisableINTEL", SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetWeightedSadINTEL", SpvOpSubgroupAvcImeSetWeightedSadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeConvertToMceResultINTEL", SpvOpSubgroupAvcImeConvertToMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetSingleReferenceStreaminINTEL", SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetDualReferenceStreaminINTEL", SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeStripSingleReferenceStreamoutINTEL", SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeStripDualReferenceStreamoutINTEL", SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetBorderReachedINTEL", SpvOpSubgroupAvcImeGetBorderReachedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetTruncatedSearchIndicationINTEL", SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcFmeInitializeINTEL", SpvOpSubgroupAvcFmeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 9, {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}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcBmeInitializeINTEL", SpvOpSubgroupAvcBmeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 10, {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}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefConvertToMcePayloadINTEL", SpvOpSubgroupAvcRefConvertToMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefSetBidirectionalMixDisableINTEL", SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefSetBilinearFilterEnableINTEL", SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithSingleReferenceINTEL", SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithDualReferenceINTEL", SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithMultiReferenceINTEL", SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefConvertToMceResultINTEL", SpvOpSubgroupAvcRefConvertToMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicInitializeINTEL", SpvOpSubgroupAvcSicInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConfigureSkcINTEL", SpvOpSubgroupAvcSicConfigureSkcINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConfigureIpeLumaINTEL", SpvOpSubgroupAvcSicConfigureIpeLumaINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 10, {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}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConfigureIpeLumaChromaINTEL", SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 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_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetMotionVectorMaskINTEL", SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConvertToMcePayloadINTEL", SpvOpSubgroupAvcSicConvertToMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetIntraLumaShapePenaltyINTEL", SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetBilinearFilterEnableINTEL", SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetSkcForwardTransformEnableINTEL", SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetBlockBasedRawSkipSadINTEL", SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateIpeINTEL", SpvOpSubgroupAvcSicEvaluateIpeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithSingleReferenceINTEL", SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithDualReferenceINTEL", SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithMultiReferenceINTEL", SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConvertToMceResultINTEL", SpvOpSubgroupAvcSicConvertToMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetIpeLumaShapeINTEL", SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetBestIpeLumaDistortionINTEL", SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetBestIpeChromaDistortionINTEL", SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetPackedIpeLumaModesINTEL", SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetIpeChromaModeINTEL", SpvOpSubgroupAvcSicGetIpeChromaModeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetInterRawSadsINTEL", SpvOpSubgroupAvcSicGetInterRawSadsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"LoopControlINTEL", SpvOpLoopControlINTEL, 1, pygen_variable_caps_UnstructuredLoopControlsINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, 0xffffffffu, 0xffffffffu}, + {"ReadPipeBlockingINTEL", SpvOpReadPipeBlockingINTEL, 1, pygen_variable_caps_BlockingPipesINTEL, 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_INTEL_blocking_pipes, 0xffffffffu, 0xffffffffu}, + {"WritePipeBlockingINTEL", SpvOpWritePipeBlockingINTEL, 1, pygen_variable_caps_BlockingPipesINTEL, 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_INTEL_blocking_pipes, 0xffffffffu, 0xffffffffu}, + {"FPGARegINTEL", SpvOpFPGARegINTEL, 1, pygen_variable_caps_FPGARegINTEL, 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_INTEL_fpga_reg, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetRayTMinKHR", SpvOpRayQueryGetRayTMinKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetRayFlagsKHR", SpvOpRayQueryGetRayFlagsKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionTKHR", SpvOpRayQueryGetIntersectionTKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionInstanceCustomIndexKHR", SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionInstanceIdKHR", SpvOpRayQueryGetIntersectionInstanceIdKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionGeometryIndexKHR", SpvOpRayQueryGetIntersectionGeometryIndexKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionPrimitiveIndexKHR", SpvOpRayQueryGetIntersectionPrimitiveIndexKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionBarycentricsKHR", SpvOpRayQueryGetIntersectionBarycentricsKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionFrontFaceKHR", SpvOpRayQueryGetIntersectionFrontFaceKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionCandidateAABBOpaqueKHR", SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionObjectRayDirectionKHR", SpvOpRayQueryGetIntersectionObjectRayDirectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionObjectRayOriginKHR", SpvOpRayQueryGetIntersectionObjectRayOriginKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetWorldRayDirectionKHR", SpvOpRayQueryGetWorldRayDirectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetWorldRayOriginKHR", SpvOpRayQueryGetWorldRayOriginKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionObjectToWorldKHR", SpvOpRayQueryGetIntersectionObjectToWorldKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionWorldToObjectKHR", SpvOpRayQueryGetIntersectionWorldToObjectKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"AtomicFAddEXT", SpvOpAtomicFAddEXT, 2, pygen_variable_caps_AtomicFloat32AddEXTAtomicFloat64AddEXT, 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, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, 0xffffffffu, 0xffffffffu} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/debuginfo.insts.inc b/spirv-tools-sys/generated/debuginfo.insts.inc new file mode 100644 index 0000000000..4fc30e3b04 --- /dev/null +++ b/spirv-tools-sys/generated/debuginfo.insts.inc @@ -0,0 +1,38 @@ + + +static const spv_ext_inst_desc_t debuginfo_entries[] = { + {"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_DEBUG_OPERATION, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/enum_string_mapping.inc b/spirv-tools-sys/generated/enum_string_mapping.inc new file mode 100644 index 0000000000..3e672245ec --- /dev/null +++ b/spirv-tools-sys/generated/enum_string_mapping.inc @@ -0,0 +1,477 @@ +const char* ExtensionToString(Extension extension) { + switch (extension) { + case Extension::kSPV_AMD_gcn_shader: + return "SPV_AMD_gcn_shader"; + case Extension::kSPV_AMD_gpu_shader_half_float: + return "SPV_AMD_gpu_shader_half_float"; + case Extension::kSPV_AMD_gpu_shader_half_float_fetch: + return "SPV_AMD_gpu_shader_half_float_fetch"; + case Extension::kSPV_AMD_gpu_shader_int16: + return "SPV_AMD_gpu_shader_int16"; + case Extension::kSPV_AMD_shader_ballot: + return "SPV_AMD_shader_ballot"; + case Extension::kSPV_AMD_shader_explicit_vertex_parameter: + return "SPV_AMD_shader_explicit_vertex_parameter"; + case Extension::kSPV_AMD_shader_fragment_mask: + return "SPV_AMD_shader_fragment_mask"; + case Extension::kSPV_AMD_shader_image_load_store_lod: + return "SPV_AMD_shader_image_load_store_lod"; + case Extension::kSPV_AMD_shader_trinary_minmax: + return "SPV_AMD_shader_trinary_minmax"; + case Extension::kSPV_AMD_texture_gather_bias_lod: + return "SPV_AMD_texture_gather_bias_lod"; + case Extension::kSPV_EXT_demote_to_helper_invocation: + return "SPV_EXT_demote_to_helper_invocation"; + case Extension::kSPV_EXT_descriptor_indexing: + return "SPV_EXT_descriptor_indexing"; + case Extension::kSPV_EXT_fragment_fully_covered: + return "SPV_EXT_fragment_fully_covered"; + case Extension::kSPV_EXT_fragment_invocation_density: + return "SPV_EXT_fragment_invocation_density"; + case Extension::kSPV_EXT_fragment_shader_interlock: + return "SPV_EXT_fragment_shader_interlock"; + case Extension::kSPV_EXT_physical_storage_buffer: + return "SPV_EXT_physical_storage_buffer"; + case Extension::kSPV_EXT_shader_atomic_float_add: + return "SPV_EXT_shader_atomic_float_add"; + case Extension::kSPV_EXT_shader_stencil_export: + return "SPV_EXT_shader_stencil_export"; + case Extension::kSPV_EXT_shader_viewport_index_layer: + return "SPV_EXT_shader_viewport_index_layer"; + case Extension::kSPV_GOOGLE_decorate_string: + return "SPV_GOOGLE_decorate_string"; + case Extension::kSPV_GOOGLE_hlsl_functionality1: + return "SPV_GOOGLE_hlsl_functionality1"; + case Extension::kSPV_GOOGLE_user_type: + return "SPV_GOOGLE_user_type"; + case Extension::kSPV_INTEL_blocking_pipes: + return "SPV_INTEL_blocking_pipes"; + case Extension::kSPV_INTEL_device_side_avc_motion_estimation: + return "SPV_INTEL_device_side_avc_motion_estimation"; + case Extension::kSPV_INTEL_fpga_loop_controls: + return "SPV_INTEL_fpga_loop_controls"; + case Extension::kSPV_INTEL_fpga_memory_attributes: + return "SPV_INTEL_fpga_memory_attributes"; + case Extension::kSPV_INTEL_fpga_reg: + return "SPV_INTEL_fpga_reg"; + case Extension::kSPV_INTEL_function_pointers: + return "SPV_INTEL_function_pointers"; + case Extension::kSPV_INTEL_kernel_attributes: + return "SPV_INTEL_kernel_attributes"; + case Extension::kSPV_INTEL_media_block_io: + return "SPV_INTEL_media_block_io"; + case Extension::kSPV_INTEL_shader_integer_functions2: + return "SPV_INTEL_shader_integer_functions2"; + case Extension::kSPV_INTEL_subgroups: + return "SPV_INTEL_subgroups"; + case Extension::kSPV_INTEL_unstructured_loop_controls: + return "SPV_INTEL_unstructured_loop_controls"; + case Extension::kSPV_KHR_16bit_storage: + return "SPV_KHR_16bit_storage"; + case Extension::kSPV_KHR_8bit_storage: + return "SPV_KHR_8bit_storage"; + case Extension::kSPV_KHR_device_group: + return "SPV_KHR_device_group"; + case Extension::kSPV_KHR_float_controls: + return "SPV_KHR_float_controls"; + case Extension::kSPV_KHR_multiview: + return "SPV_KHR_multiview"; + case Extension::kSPV_KHR_no_integer_wrap_decoration: + return "SPV_KHR_no_integer_wrap_decoration"; + case Extension::kSPV_KHR_non_semantic_info: + return "SPV_KHR_non_semantic_info"; + case Extension::kSPV_KHR_physical_storage_buffer: + return "SPV_KHR_physical_storage_buffer"; + case Extension::kSPV_KHR_post_depth_coverage: + return "SPV_KHR_post_depth_coverage"; + case Extension::kSPV_KHR_ray_query: + return "SPV_KHR_ray_query"; + case Extension::kSPV_KHR_ray_tracing: + return "SPV_KHR_ray_tracing"; + case Extension::kSPV_KHR_shader_atomic_counter_ops: + return "SPV_KHR_shader_atomic_counter_ops"; + case Extension::kSPV_KHR_shader_ballot: + return "SPV_KHR_shader_ballot"; + case Extension::kSPV_KHR_shader_clock: + return "SPV_KHR_shader_clock"; + case Extension::kSPV_KHR_shader_draw_parameters: + return "SPV_KHR_shader_draw_parameters"; + case Extension::kSPV_KHR_storage_buffer_storage_class: + return "SPV_KHR_storage_buffer_storage_class"; + case Extension::kSPV_KHR_subgroup_vote: + return "SPV_KHR_subgroup_vote"; + case Extension::kSPV_KHR_terminate_invocation: + return "SPV_KHR_terminate_invocation"; + case Extension::kSPV_KHR_variable_pointers: + return "SPV_KHR_variable_pointers"; + case Extension::kSPV_KHR_vulkan_memory_model: + return "SPV_KHR_vulkan_memory_model"; + case Extension::kSPV_NVX_multiview_per_view_attributes: + return "SPV_NVX_multiview_per_view_attributes"; + case Extension::kSPV_NV_compute_shader_derivatives: + return "SPV_NV_compute_shader_derivatives"; + case Extension::kSPV_NV_cooperative_matrix: + return "SPV_NV_cooperative_matrix"; + case Extension::kSPV_NV_fragment_shader_barycentric: + return "SPV_NV_fragment_shader_barycentric"; + case Extension::kSPV_NV_geometry_shader_passthrough: + return "SPV_NV_geometry_shader_passthrough"; + case Extension::kSPV_NV_mesh_shader: + return "SPV_NV_mesh_shader"; + case Extension::kSPV_NV_ray_tracing: + return "SPV_NV_ray_tracing"; + case Extension::kSPV_NV_sample_mask_override_coverage: + return "SPV_NV_sample_mask_override_coverage"; + case Extension::kSPV_NV_shader_image_footprint: + return "SPV_NV_shader_image_footprint"; + case Extension::kSPV_NV_shader_sm_builtins: + return "SPV_NV_shader_sm_builtins"; + case Extension::kSPV_NV_shader_subgroup_partitioned: + return "SPV_NV_shader_subgroup_partitioned"; + case Extension::kSPV_NV_shading_rate: + return "SPV_NV_shading_rate"; + case Extension::kSPV_NV_stereo_view_rendering: + return "SPV_NV_stereo_view_rendering"; + case Extension::kSPV_NV_viewport_array2: + return "SPV_NV_viewport_array2"; + case Extension::kSPV_VALIDATOR_ignore_type_decl_unique: + return "SPV_VALIDATOR_ignore_type_decl_unique"; + }; + + return ""; +} + + + bool GetExtensionFromString(const char* str, Extension* extension) { + static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_kernel_attributes", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" }; + static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique }; + const auto b = std::begin(known_ext_strs); + const auto e = std::end(known_ext_strs); + const auto found = std::equal_range( + b, e, str, [](const char* str1, const char* str2) { + return std::strcmp(str1, str2) < 0; + }); + if (found.first == e || found.first == found.second) return false; + + *extension = known_ext_ids[found.first - b]; + return true; + } + + +const char* CapabilityToString(SpvCapability capability) { + switch (capability) { + case SpvCapabilityMatrix: + return "Matrix"; + case SpvCapabilityShader: + return "Shader"; + case SpvCapabilityGeometry: + return "Geometry"; + case SpvCapabilityTessellation: + return "Tessellation"; + case SpvCapabilityAddresses: + return "Addresses"; + case SpvCapabilityLinkage: + return "Linkage"; + case SpvCapabilityKernel: + return "Kernel"; + case SpvCapabilityVector16: + return "Vector16"; + case SpvCapabilityFloat16Buffer: + return "Float16Buffer"; + case SpvCapabilityFloat16: + return "Float16"; + case SpvCapabilityFloat64: + return "Float64"; + case SpvCapabilityInt64: + return "Int64"; + case SpvCapabilityInt64Atomics: + return "Int64Atomics"; + case SpvCapabilityImageBasic: + return "ImageBasic"; + case SpvCapabilityImageReadWrite: + return "ImageReadWrite"; + case SpvCapabilityImageMipmap: + return "ImageMipmap"; + case SpvCapabilityPipes: + return "Pipes"; + case SpvCapabilityGroups: + return "Groups"; + case SpvCapabilityDeviceEnqueue: + return "DeviceEnqueue"; + case SpvCapabilityLiteralSampler: + return "LiteralSampler"; + case SpvCapabilityAtomicStorage: + return "AtomicStorage"; + case SpvCapabilityInt16: + return "Int16"; + case SpvCapabilityTessellationPointSize: + return "TessellationPointSize"; + case SpvCapabilityGeometryPointSize: + return "GeometryPointSize"; + case SpvCapabilityImageGatherExtended: + return "ImageGatherExtended"; + case SpvCapabilityStorageImageMultisample: + return "StorageImageMultisample"; + case SpvCapabilityUniformBufferArrayDynamicIndexing: + return "UniformBufferArrayDynamicIndexing"; + case SpvCapabilitySampledImageArrayDynamicIndexing: + return "SampledImageArrayDynamicIndexing"; + case SpvCapabilityStorageBufferArrayDynamicIndexing: + return "StorageBufferArrayDynamicIndexing"; + case SpvCapabilityStorageImageArrayDynamicIndexing: + return "StorageImageArrayDynamicIndexing"; + case SpvCapabilityClipDistance: + return "ClipDistance"; + case SpvCapabilityCullDistance: + return "CullDistance"; + case SpvCapabilityImageCubeArray: + return "ImageCubeArray"; + case SpvCapabilitySampleRateShading: + return "SampleRateShading"; + case SpvCapabilityImageRect: + return "ImageRect"; + case SpvCapabilitySampledRect: + return "SampledRect"; + case SpvCapabilityGenericPointer: + return "GenericPointer"; + case SpvCapabilityInt8: + return "Int8"; + case SpvCapabilityInputAttachment: + return "InputAttachment"; + case SpvCapabilitySparseResidency: + return "SparseResidency"; + case SpvCapabilityMinLod: + return "MinLod"; + case SpvCapabilitySampled1D: + return "Sampled1D"; + case SpvCapabilityImage1D: + return "Image1D"; + case SpvCapabilitySampledCubeArray: + return "SampledCubeArray"; + case SpvCapabilitySampledBuffer: + return "SampledBuffer"; + case SpvCapabilityImageBuffer: + return "ImageBuffer"; + case SpvCapabilityImageMSArray: + return "ImageMSArray"; + case SpvCapabilityStorageImageExtendedFormats: + return "StorageImageExtendedFormats"; + case SpvCapabilityImageQuery: + return "ImageQuery"; + case SpvCapabilityDerivativeControl: + return "DerivativeControl"; + case SpvCapabilityInterpolationFunction: + return "InterpolationFunction"; + case SpvCapabilityTransformFeedback: + return "TransformFeedback"; + case SpvCapabilityGeometryStreams: + return "GeometryStreams"; + case SpvCapabilityStorageImageReadWithoutFormat: + return "StorageImageReadWithoutFormat"; + case SpvCapabilityStorageImageWriteWithoutFormat: + return "StorageImageWriteWithoutFormat"; + case SpvCapabilityMultiViewport: + return "MultiViewport"; + case SpvCapabilitySubgroupDispatch: + return "SubgroupDispatch"; + case SpvCapabilityNamedBarrier: + return "NamedBarrier"; + case SpvCapabilityPipeStorage: + return "PipeStorage"; + case SpvCapabilityGroupNonUniform: + return "GroupNonUniform"; + case SpvCapabilityGroupNonUniformVote: + return "GroupNonUniformVote"; + case SpvCapabilityGroupNonUniformArithmetic: + return "GroupNonUniformArithmetic"; + case SpvCapabilityGroupNonUniformBallot: + return "GroupNonUniformBallot"; + case SpvCapabilityGroupNonUniformShuffle: + return "GroupNonUniformShuffle"; + case SpvCapabilityGroupNonUniformShuffleRelative: + return "GroupNonUniformShuffleRelative"; + case SpvCapabilityGroupNonUniformClustered: + return "GroupNonUniformClustered"; + case SpvCapabilityGroupNonUniformQuad: + return "GroupNonUniformQuad"; + case SpvCapabilityShaderLayer: + return "ShaderLayer"; + case SpvCapabilityShaderViewportIndex: + return "ShaderViewportIndex"; + case SpvCapabilitySubgroupBallotKHR: + return "SubgroupBallotKHR"; + case SpvCapabilityDrawParameters: + return "DrawParameters"; + case SpvCapabilitySubgroupVoteKHR: + return "SubgroupVoteKHR"; + case SpvCapabilityStorageBuffer16BitAccess: + return "StorageBuffer16BitAccess"; + case SpvCapabilityUniformAndStorageBuffer16BitAccess: + return "UniformAndStorageBuffer16BitAccess"; + case SpvCapabilityStoragePushConstant16: + return "StoragePushConstant16"; + case SpvCapabilityStorageInputOutput16: + return "StorageInputOutput16"; + case SpvCapabilityDeviceGroup: + return "DeviceGroup"; + case SpvCapabilityMultiView: + return "MultiView"; + case SpvCapabilityVariablePointersStorageBuffer: + return "VariablePointersStorageBuffer"; + case SpvCapabilityVariablePointers: + return "VariablePointers"; + case SpvCapabilityAtomicStorageOps: + return "AtomicStorageOps"; + case SpvCapabilitySampleMaskPostDepthCoverage: + return "SampleMaskPostDepthCoverage"; + case SpvCapabilityStorageBuffer8BitAccess: + return "StorageBuffer8BitAccess"; + case SpvCapabilityUniformAndStorageBuffer8BitAccess: + return "UniformAndStorageBuffer8BitAccess"; + case SpvCapabilityStoragePushConstant8: + return "StoragePushConstant8"; + case SpvCapabilityDenormPreserve: + return "DenormPreserve"; + case SpvCapabilityDenormFlushToZero: + return "DenormFlushToZero"; + case SpvCapabilitySignedZeroInfNanPreserve: + return "SignedZeroInfNanPreserve"; + case SpvCapabilityRoundingModeRTE: + return "RoundingModeRTE"; + case SpvCapabilityRoundingModeRTZ: + return "RoundingModeRTZ"; + case SpvCapabilityRayQueryProvisionalKHR: + return "RayQueryProvisionalKHR"; + case SpvCapabilityRayTraversalPrimitiveCullingProvisionalKHR: + return "RayTraversalPrimitiveCullingProvisionalKHR"; + case SpvCapabilityFloat16ImageAMD: + return "Float16ImageAMD"; + case SpvCapabilityImageGatherBiasLodAMD: + return "ImageGatherBiasLodAMD"; + case SpvCapabilityFragmentMaskAMD: + return "FragmentMaskAMD"; + case SpvCapabilityStencilExportEXT: + return "StencilExportEXT"; + case SpvCapabilityImageReadWriteLodAMD: + return "ImageReadWriteLodAMD"; + case SpvCapabilityShaderClockKHR: + return "ShaderClockKHR"; + case SpvCapabilitySampleMaskOverrideCoverageNV: + return "SampleMaskOverrideCoverageNV"; + case SpvCapabilityGeometryShaderPassthroughNV: + return "GeometryShaderPassthroughNV"; + case SpvCapabilityShaderViewportIndexLayerEXT: + return "ShaderViewportIndexLayerEXT"; + case SpvCapabilityShaderViewportMaskNV: + return "ShaderViewportMaskNV"; + case SpvCapabilityShaderStereoViewNV: + return "ShaderStereoViewNV"; + case SpvCapabilityPerViewAttributesNV: + return "PerViewAttributesNV"; + case SpvCapabilityFragmentFullyCoveredEXT: + return "FragmentFullyCoveredEXT"; + case SpvCapabilityMeshShadingNV: + return "MeshShadingNV"; + case SpvCapabilityImageFootprintNV: + return "ImageFootprintNV"; + case SpvCapabilityFragmentBarycentricNV: + return "FragmentBarycentricNV"; + case SpvCapabilityComputeDerivativeGroupQuadsNV: + return "ComputeDerivativeGroupQuadsNV"; + case SpvCapabilityFragmentDensityEXT: + return "FragmentDensityEXT"; + case SpvCapabilityGroupNonUniformPartitionedNV: + return "GroupNonUniformPartitionedNV"; + case SpvCapabilityShaderNonUniform: + return "ShaderNonUniform"; + case SpvCapabilityRuntimeDescriptorArray: + return "RuntimeDescriptorArray"; + case SpvCapabilityInputAttachmentArrayDynamicIndexing: + return "InputAttachmentArrayDynamicIndexing"; + case SpvCapabilityUniformTexelBufferArrayDynamicIndexing: + return "UniformTexelBufferArrayDynamicIndexing"; + case SpvCapabilityStorageTexelBufferArrayDynamicIndexing: + return "StorageTexelBufferArrayDynamicIndexing"; + case SpvCapabilityUniformBufferArrayNonUniformIndexing: + return "UniformBufferArrayNonUniformIndexing"; + case SpvCapabilitySampledImageArrayNonUniformIndexing: + return "SampledImageArrayNonUniformIndexing"; + case SpvCapabilityStorageBufferArrayNonUniformIndexing: + return "StorageBufferArrayNonUniformIndexing"; + case SpvCapabilityStorageImageArrayNonUniformIndexing: + return "StorageImageArrayNonUniformIndexing"; + case SpvCapabilityInputAttachmentArrayNonUniformIndexing: + return "InputAttachmentArrayNonUniformIndexing"; + case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing: + return "UniformTexelBufferArrayNonUniformIndexing"; + case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing: + return "StorageTexelBufferArrayNonUniformIndexing"; + case SpvCapabilityRayTracingNV: + return "RayTracingNV"; + case SpvCapabilityVulkanMemoryModel: + return "VulkanMemoryModel"; + case SpvCapabilityVulkanMemoryModelDeviceScope: + return "VulkanMemoryModelDeviceScope"; + case SpvCapabilityPhysicalStorageBufferAddresses: + return "PhysicalStorageBufferAddresses"; + case SpvCapabilityComputeDerivativeGroupLinearNV: + return "ComputeDerivativeGroupLinearNV"; + case SpvCapabilityRayTracingProvisionalKHR: + return "RayTracingProvisionalKHR"; + case SpvCapabilityCooperativeMatrixNV: + return "CooperativeMatrixNV"; + case SpvCapabilityFragmentShaderSampleInterlockEXT: + return "FragmentShaderSampleInterlockEXT"; + case SpvCapabilityFragmentShaderShadingRateInterlockEXT: + return "FragmentShaderShadingRateInterlockEXT"; + case SpvCapabilityShaderSMBuiltinsNV: + return "ShaderSMBuiltinsNV"; + case SpvCapabilityFragmentShaderPixelInterlockEXT: + return "FragmentShaderPixelInterlockEXT"; + case SpvCapabilityDemoteToHelperInvocationEXT: + return "DemoteToHelperInvocationEXT"; + case SpvCapabilitySubgroupShuffleINTEL: + return "SubgroupShuffleINTEL"; + case SpvCapabilitySubgroupBufferBlockIOINTEL: + return "SubgroupBufferBlockIOINTEL"; + case SpvCapabilitySubgroupImageBlockIOINTEL: + return "SubgroupImageBlockIOINTEL"; + case SpvCapabilitySubgroupImageMediaBlockIOINTEL: + return "SubgroupImageMediaBlockIOINTEL"; + case SpvCapabilityIntegerFunctions2INTEL: + return "IntegerFunctions2INTEL"; + case SpvCapabilityFunctionPointersINTEL: + return "FunctionPointersINTEL"; + case SpvCapabilityIndirectReferencesINTEL: + return "IndirectReferencesINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationINTEL: + return "SubgroupAvcMotionEstimationINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL: + return "SubgroupAvcMotionEstimationIntraINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL: + return "SubgroupAvcMotionEstimationChromaINTEL"; + case SpvCapabilityFPGAMemoryAttributesINTEL: + return "FPGAMemoryAttributesINTEL"; + case SpvCapabilityUnstructuredLoopControlsINTEL: + return "UnstructuredLoopControlsINTEL"; + case SpvCapabilityFPGALoopControlsINTEL: + return "FPGALoopControlsINTEL"; + case SpvCapabilityKernelAttributesINTEL: + return "KernelAttributesINTEL"; + case SpvCapabilityFPGAKernelAttributesINTEL: + return "FPGAKernelAttributesINTEL"; + case SpvCapabilityBlockingPipesINTEL: + return "BlockingPipesINTEL"; + case SpvCapabilityFPGARegINTEL: + return "FPGARegINTEL"; + case SpvCapabilityAtomicFloat32AddEXT: + return "AtomicFloat32AddEXT"; + case SpvCapabilityAtomicFloat64AddEXT: + return "AtomicFloat64AddEXT"; + case SpvCapabilityMax: + assert(0 && "Attempting to convert SpvCapabilityMax to string"); + return ""; + }; + + return ""; +} \ No newline at end of file diff --git a/spirv-tools-sys/generated/extension_enum.inc b/spirv-tools-sys/generated/extension_enum.inc new file mode 100644 index 0000000000..a5c14eedb0 --- /dev/null +++ b/spirv-tools-sys/generated/extension_enum.inc @@ -0,0 +1,68 @@ +kSPV_AMD_gcn_shader, +kSPV_AMD_gpu_shader_half_float, +kSPV_AMD_gpu_shader_half_float_fetch, +kSPV_AMD_gpu_shader_int16, +kSPV_AMD_shader_ballot, +kSPV_AMD_shader_explicit_vertex_parameter, +kSPV_AMD_shader_fragment_mask, +kSPV_AMD_shader_image_load_store_lod, +kSPV_AMD_shader_trinary_minmax, +kSPV_AMD_texture_gather_bias_lod, +kSPV_EXT_demote_to_helper_invocation, +kSPV_EXT_descriptor_indexing, +kSPV_EXT_fragment_fully_covered, +kSPV_EXT_fragment_invocation_density, +kSPV_EXT_fragment_shader_interlock, +kSPV_EXT_physical_storage_buffer, +kSPV_EXT_shader_atomic_float_add, +kSPV_EXT_shader_stencil_export, +kSPV_EXT_shader_viewport_index_layer, +kSPV_GOOGLE_decorate_string, +kSPV_GOOGLE_hlsl_functionality1, +kSPV_GOOGLE_user_type, +kSPV_INTEL_blocking_pipes, +kSPV_INTEL_device_side_avc_motion_estimation, +kSPV_INTEL_fpga_loop_controls, +kSPV_INTEL_fpga_memory_attributes, +kSPV_INTEL_fpga_reg, +kSPV_INTEL_function_pointers, +kSPV_INTEL_kernel_attributes, +kSPV_INTEL_media_block_io, +kSPV_INTEL_shader_integer_functions2, +kSPV_INTEL_subgroups, +kSPV_INTEL_unstructured_loop_controls, +kSPV_KHR_16bit_storage, +kSPV_KHR_8bit_storage, +kSPV_KHR_device_group, +kSPV_KHR_float_controls, +kSPV_KHR_multiview, +kSPV_KHR_no_integer_wrap_decoration, +kSPV_KHR_non_semantic_info, +kSPV_KHR_physical_storage_buffer, +kSPV_KHR_post_depth_coverage, +kSPV_KHR_ray_query, +kSPV_KHR_ray_tracing, +kSPV_KHR_shader_atomic_counter_ops, +kSPV_KHR_shader_ballot, +kSPV_KHR_shader_clock, +kSPV_KHR_shader_draw_parameters, +kSPV_KHR_storage_buffer_storage_class, +kSPV_KHR_subgroup_vote, +kSPV_KHR_terminate_invocation, +kSPV_KHR_variable_pointers, +kSPV_KHR_vulkan_memory_model, +kSPV_NVX_multiview_per_view_attributes, +kSPV_NV_compute_shader_derivatives, +kSPV_NV_cooperative_matrix, +kSPV_NV_fragment_shader_barycentric, +kSPV_NV_geometry_shader_passthrough, +kSPV_NV_mesh_shader, +kSPV_NV_ray_tracing, +kSPV_NV_sample_mask_override_coverage, +kSPV_NV_shader_image_footprint, +kSPV_NV_shader_sm_builtins, +kSPV_NV_shader_subgroup_partitioned, +kSPV_NV_shading_rate, +kSPV_NV_stereo_view_rendering, +kSPV_NV_viewport_array2, +kSPV_VALIDATOR_ignore_type_decl_unique \ No newline at end of file diff --git a/spirv-tools-sys/generated/generators.inc b/spirv-tools-sys/generated/generators.inc new file mode 100644 index 0000000000..b0a58846be --- /dev/null +++ b/spirv-tools-sys/generated/generators.inc @@ -0,0 +1,25 @@ +{0, "Khronos", "", "Khronos"}, +{1, "LunarG", "", "LunarG"}, +{2, "Valve", "", "Valve"}, +{3, "Codeplay", "", "Codeplay"}, +{4, "NVIDIA", "", "NVIDIA"}, +{5, "ARM", "", "ARM"}, +{6, "Khronos", "LLVM/SPIR-V Translator", "Khronos LLVM/SPIR-V Translator"}, +{7, "Khronos", "SPIR-V Tools Assembler", "Khronos SPIR-V Tools Assembler"}, +{8, "Khronos", "Glslang Reference Front End", "Khronos Glslang Reference Front End"}, +{9, "Qualcomm", "", "Qualcomm"}, +{10, "AMD", "", "AMD"}, +{11, "Intel", "", "Intel"}, +{12, "Imagination", "", "Imagination"}, +{13, "Google", "Shaderc over Glslang", "Google Shaderc over Glslang"}, +{14, "Google", "spiregg", "Google spiregg"}, +{15, "Google", "rspirv", "Google rspirv"}, +{16, "X-LEGEND", "Mesa-IR/SPIR-V Translator", "X-LEGEND Mesa-IR/SPIR-V Translator"}, +{17, "Khronos", "SPIR-V Tools Linker", "Khronos SPIR-V Tools Linker"}, +{18, "Wine", "VKD3D Shader Compiler", "Wine VKD3D Shader Compiler"}, +{19, "Clay", "Clay Shader Compiler", "Clay Clay Shader Compiler"}, +{20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"}, +{21, "Google", "Clspv", "Google Clspv"}, +{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"}, +{23, "Google", "Tint Compiler", "Google Tint Compiler"}, +{24, "Google", "ANGLE Shader Compiler", "Google ANGLE Shader Compiler"}, \ No newline at end of file diff --git a/spirv-tools-sys/generated/glsl.std.450.insts.inc b/spirv-tools-sys/generated/glsl.std.450.insts.inc new file mode 100644 index 0000000000..7d3866d80d --- /dev/null +++ b/spirv-tools-sys/generated/glsl.std.450.insts.inc @@ -0,0 +1,86 @@ +static const SpvCapability pygen_variable_caps_Float64[] = {SpvCapabilityFloat64}; +static const SpvCapability pygen_variable_caps_InterpolationFunction[] = {SpvCapabilityInterpolationFunction}; + +static const spv_ext_inst_desc_t glsl_entries[] = { + {"Round", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"RoundEven", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Trunc", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FAbs", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SAbs", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FSign", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SSign", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Floor", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Ceil", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Fract", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Radians", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Degrees", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Sin", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Cos", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Tan", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Asin", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Acos", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Atan", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Sinh", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Cosh", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Tanh", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Asinh", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Acosh", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Atanh", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Atan2", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Pow", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Exp", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Log", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Exp2", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Log2", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Sqrt", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InverseSqrt", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Determinant", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"MatrixInverse", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Modf", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ModfStruct", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMin", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMin", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMin", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMax", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMax", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMax", 42, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FClamp", 43, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UClamp", 44, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SClamp", 45, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMix", 46, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"IMix", 47, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Step", 48, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SmoothStep", 49, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Fma", 50, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Frexp", 51, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FrexpStruct", 52, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Ldexp", 53, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackSnorm4x8", 54, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackUnorm4x8", 55, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackSnorm2x16", 56, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackUnorm2x16", 57, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackHalf2x16", 58, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackDouble2x32", 59, 1, pygen_variable_caps_Float64, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackSnorm2x16", 60, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackUnorm2x16", 61, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackHalf2x16", 62, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackSnorm4x8", 63, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackUnorm4x8", 64, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackDouble2x32", 65, 1, pygen_variable_caps_Float64, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Length", 66, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Distance", 67, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Cross", 68, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Normalize", 69, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FaceForward", 70, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Reflect", 71, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Refract", 72, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FindILsb", 73, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FindSMsb", 74, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FindUMsb", 75, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InterpolateAtCentroid", 76, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InterpolateAtSample", 77, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InterpolateAtOffset", 78, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NMin", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NMax", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NClamp", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/nonsemantic.clspvreflection.insts.inc b/spirv-tools-sys/generated/nonsemantic.clspvreflection.insts.inc new file mode 100644 index 0000000000..4f559f6aeb --- /dev/null +++ b/spirv-tools-sys/generated/nonsemantic.clspvreflection.insts.inc @@ -0,0 +1,28 @@ + + +static const spv_ext_inst_desc_t nonsemantic_clspvreflection_entries[] = { + {"Kernel", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentInfo", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentStorageBuffer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentUniform", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPodStorageBuffer", 5, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPodUniform", 6, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPodPushConstant", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentSampledImage", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentStorageImage", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentSampler", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentWorkgroup", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantWorkgroupSize", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantGlobalOffset", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantWorkDim", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantGlobalOffset", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantEnqueuedLocalSize", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantGlobalSize", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantRegionOffset", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantNumWorkgroups", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantRegionGroupOffset", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ConstantDataStorageBuffer", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ConstantDataUniform", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"LiteralSampler", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PropertyRequiredWorkgroupSize", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/opencl.debuginfo.100.insts.inc b/spirv-tools-sys/generated/opencl.debuginfo.100.insts.inc new file mode 100644 index 0000000000..963bca37cc --- /dev/null +++ b/spirv-tools-sys/generated/opencl.debuginfo.100.insts.inc @@ -0,0 +1,40 @@ + + +static const spv_ext_inst_desc_t opencl_debuginfo_100_entries[] = { + {"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugImportedEntity", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugSource", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/opencl.std.insts.inc b/spirv-tools-sys/generated/opencl.std.insts.inc new file mode 100644 index 0000000000..cd0a9c37a5 --- /dev/null +++ b/spirv-tools-sys/generated/opencl.std.insts.inc @@ -0,0 +1,166 @@ + + +static const spv_ext_inst_desc_t opencl_entries[] = { + {"acos", 0, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"acosh", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"acospi", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"asin", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"asinh", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"asinpi", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atan", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atan2", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atanh", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atanpi", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atan2pi", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cbrt", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ceil", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"copysign", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cos", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cosh", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cospi", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"erfc", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"erf", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"exp", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"exp2", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"exp10", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"expm1", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fabs", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fdim", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"floor", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fma", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmax", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmin", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmod", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fract", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"frexp", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"hypot", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ilogb", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ldexp", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"lgamma", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"lgamma_r", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log2", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log10", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log1p", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"logb", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"mad", 42, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"maxmag", 43, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"minmag", 44, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"modf", 45, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"nan", 46, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"nextafter", 47, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"pow", 48, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"pown", 49, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"powr", 50, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"remainder", 51, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"remquo", 52, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rint", 53, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rootn", 54, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"round", 55, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rsqrt", 56, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sin", 57, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sincos", 58, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sinh", 59, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sinpi", 60, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sqrt", 61, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tan", 62, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tanh", 63, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tanpi", 64, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tgamma", 65, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"trunc", 66, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_cos", 67, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_divide", 68, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_exp", 69, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_exp2", 70, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_exp10", 71, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_log", 72, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_log2", 73, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_log10", 74, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_powr", 75, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_recip", 76, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_rsqrt", 77, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_sin", 78, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_sqrt", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_tan", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_cos", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_divide", 82, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_exp", 83, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_exp2", 84, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_exp10", 85, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_log", 86, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_log2", 87, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_log10", 88, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_powr", 89, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_recip", 90, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_rsqrt", 91, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_sin", 92, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_sqrt", 93, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_tan", 94, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fclamp", 95, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"degrees", 96, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmax_common", 97, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmin_common", 98, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"mix", 99, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"radians", 100, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"step", 101, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"smoothstep", 102, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sign", 103, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cross", 104, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"distance", 105, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"length", 106, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"normalize", 107, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fast_distance", 108, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fast_length", 109, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fast_normalize", 110, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_abs", 141, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_abs_diff", 142, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_add_sat", 143, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_add_sat", 144, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_hadd", 145, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_hadd", 146, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_rhadd", 147, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_rhadd", 148, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_clamp", 149, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_clamp", 150, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"clz", 151, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ctz", 152, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mad_hi", 153, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mad_sat", 154, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mad_sat", 155, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_max", 156, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_max", 157, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_min", 158, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_min", 159, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mul_hi", 160, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rotate", 161, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_sub_sat", 162, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_sub_sat", 163, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_upsample", 164, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_upsample", 165, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"popcount", 166, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mad24", 167, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mad24", 168, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mul24", 169, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mul24", 170, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vloadn", 171, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"vstoren", 172, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vload_half", 173, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vload_halfn", 174, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"vstore_half", 175, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vstore_half_r", 176, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}}, + {"vstore_halfn", 177, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vstore_halfn_r", 178, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}}, + {"vloada_halfn", 179, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"vstorea_halfn", 180, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vstorea_halfn_r", 181, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}}, + {"shuffle", 182, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"shuffle2", 183, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"printf", 184, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"prefetch", 185, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"bitselect", 186, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"select", 187, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_abs", 201, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_abs_diff", 202, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mul_hi", 203, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mad_hi", 204, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/operand.kinds-unified1.inc b/spirv-tools-sys/generated/operand.kinds-unified1.inc new file mode 100644 index 0000000000..f07003d8da --- /dev/null +++ b/spirv-tools-sys/generated/operand.kinds-unified1.inc @@ -0,0 +1,1152 @@ +static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddresses}; +static const SpvCapability pygen_variable_caps_AtomicStorage[] = {SpvCapabilityAtomicStorage}; +static const SpvCapability pygen_variable_caps_ClipDistance[] = {SpvCapabilityClipDistance}; +static const SpvCapability pygen_variable_caps_ComputeDerivativeGroupLinearNV[] = {SpvCapabilityComputeDerivativeGroupLinearNV}; +static const SpvCapability pygen_variable_caps_ComputeDerivativeGroupQuadsNV[] = {SpvCapabilityComputeDerivativeGroupQuadsNV}; +static const SpvCapability pygen_variable_caps_CullDistance[] = {SpvCapabilityCullDistance}; +static const SpvCapability pygen_variable_caps_DenormFlushToZero[] = {SpvCapabilityDenormFlushToZero}; +static const SpvCapability pygen_variable_caps_DenormPreserve[] = {SpvCapabilityDenormPreserve}; +static const SpvCapability pygen_variable_caps_DeviceEnqueue[] = {SpvCapabilityDeviceEnqueue}; +static const SpvCapability pygen_variable_caps_DeviceGroup[] = {SpvCapabilityDeviceGroup}; +static const SpvCapability pygen_variable_caps_DrawParameters[] = {SpvCapabilityDrawParameters}; +static const SpvCapability pygen_variable_caps_DrawParametersMeshShadingNV[] = {SpvCapabilityDrawParameters, SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_FPGAKernelAttributesINTEL[] = {SpvCapabilityFPGAKernelAttributesINTEL}; +static const SpvCapability pygen_variable_caps_FPGALoopControlsINTEL[] = {SpvCapabilityFPGALoopControlsINTEL}; +static const SpvCapability pygen_variable_caps_FPGAMemoryAttributesINTEL[] = {SpvCapabilityFPGAMemoryAttributesINTEL}; +static const SpvCapability pygen_variable_caps_FragmentBarycentricNV[] = {SpvCapabilityFragmentBarycentricNV}; +static const SpvCapability pygen_variable_caps_FragmentDensityEXTShadingRateNV[] = {SpvCapabilityFragmentDensityEXT, SpvCapabilityShadingRateNV}; +static const SpvCapability pygen_variable_caps_FragmentFullyCoveredEXT[] = {SpvCapabilityFragmentFullyCoveredEXT}; +static const SpvCapability pygen_variable_caps_FragmentShaderPixelInterlockEXT[] = {SpvCapabilityFragmentShaderPixelInterlockEXT}; +static const SpvCapability pygen_variable_caps_FragmentShaderSampleInterlockEXT[] = {SpvCapabilityFragmentShaderSampleInterlockEXT}; +static const SpvCapability pygen_variable_caps_FragmentShaderShadingRateInterlockEXT[] = {SpvCapabilityFragmentShaderShadingRateInterlockEXT}; +static const SpvCapability pygen_variable_caps_FunctionPointersINTEL[] = {SpvCapabilityFunctionPointersINTEL}; +static const SpvCapability pygen_variable_caps_GenericPointer[] = {SpvCapabilityGenericPointer}; +static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry}; +static const SpvCapability pygen_variable_caps_GeometryMeshShadingNV[] = {SpvCapabilityGeometry, SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXT[] = {SpvCapabilityGeometry, SpvCapabilityShaderLayer, SpvCapabilityShaderViewportIndexLayerEXT}; +static const SpvCapability pygen_variable_caps_GeometryTessellation[] = {SpvCapabilityGeometry, SpvCapabilityTessellation}; +static const SpvCapability pygen_variable_caps_GeometryTessellationMeshShadingNV[] = {SpvCapabilityGeometry, SpvCapabilityTessellation, SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_GeometryTessellationRayTracingNVRayTracingProvisionalKHR[] = {SpvCapabilityGeometry, SpvCapabilityTessellation, SpvCapabilityRayTracingNV, SpvCapabilityRayTracingProvisionalKHR}; +static const SpvCapability pygen_variable_caps_GeometryShaderPassthroughNV[] = {SpvCapabilityGeometryShaderPassthroughNV}; +static const SpvCapability pygen_variable_caps_GeometryStreams[] = {SpvCapabilityGeometryStreams}; +static const SpvCapability pygen_variable_caps_GroupNonUniform[] = {SpvCapabilityGroupNonUniform}; +static const SpvCapability pygen_variable_caps_GroupNonUniformClustered[] = {SpvCapabilityGroupNonUniformClustered}; +static const SpvCapability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformPartitionedNV}; +static const SpvCapability pygen_variable_caps_ImageBasic[] = {SpvCapabilityImageBasic}; +static const SpvCapability pygen_variable_caps_ImageBuffer[] = {SpvCapabilityImageBuffer}; +static const SpvCapability pygen_variable_caps_ImageBufferShaderNonUniform[] = {SpvCapabilityImageBuffer, SpvCapabilityShaderNonUniform}; +static const SpvCapability pygen_variable_caps_ImageGatherExtended[] = {SpvCapabilityImageGatherExtended}; +static const SpvCapability pygen_variable_caps_IndirectReferencesINTEL[] = {SpvCapabilityIndirectReferencesINTEL}; +static const SpvCapability pygen_variable_caps_InputAttachment[] = {SpvCapabilityInputAttachment}; +static const SpvCapability pygen_variable_caps_InputAttachmentShaderNonUniform[] = {SpvCapabilityInputAttachment, SpvCapabilityShaderNonUniform}; +static const SpvCapability pygen_variable_caps_Int64[] = {SpvCapabilityInt64}; +static const SpvCapability pygen_variable_caps_Kernel[] = {SpvCapabilityKernel}; +static const SpvCapability pygen_variable_caps_KernelGroupNonUniform[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform}; +static const SpvCapability pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform, SpvCapabilitySubgroupBallotKHR}; +static const SpvCapability pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniformArithmetic, SpvCapabilityGroupNonUniformBallot}; +static const SpvCapability pygen_variable_caps_KernelAttributesINTEL[] = {SpvCapabilityKernelAttributesINTEL}; +static const SpvCapability pygen_variable_caps_Linkage[] = {SpvCapabilityLinkage}; +static const SpvCapability pygen_variable_caps_Matrix[] = {SpvCapabilityMatrix}; +static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_MinLod[] = {SpvCapabilityMinLod}; +static const SpvCapability pygen_variable_caps_MultiView[] = {SpvCapabilityMultiView}; +static const SpvCapability pygen_variable_caps_MultiViewport[] = {SpvCapabilityMultiViewport}; +static const SpvCapability pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXT[] = {SpvCapabilityMultiViewport, SpvCapabilityShaderViewportIndex, SpvCapabilityShaderViewportIndexLayerEXT}; +static const SpvCapability pygen_variable_caps_PerViewAttributesNVMeshShadingNV[] = {SpvCapabilityPerViewAttributesNV, SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {SpvCapabilityPhysicalStorageBufferAddresses}; +static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes}; +static const SpvCapability pygen_variable_caps_RayQueryProvisionalKHR[] = {SpvCapabilityRayQueryProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR[] = {SpvCapabilityRayQueryProvisionalKHR, SpvCapabilityRayTracingProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RayTracingProvisionalKHR[] = {SpvCapabilityRayTracingProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RayTraversalPrimitiveCullingProvisionalKHR[] = {SpvCapabilityRayTraversalPrimitiveCullingProvisionalKHR}; +static const SpvCapability pygen_variable_caps_RoundingModeRTE[] = {SpvCapabilityRoundingModeRTE}; +static const SpvCapability pygen_variable_caps_RoundingModeRTZ[] = {SpvCapabilityRoundingModeRTZ}; +static const SpvCapability pygen_variable_caps_SampleMaskOverrideCoverageNV[] = {SpvCapabilitySampleMaskOverrideCoverageNV}; +static const SpvCapability pygen_variable_caps_SampleMaskPostDepthCoverage[] = {SpvCapabilitySampleMaskPostDepthCoverage}; +static const SpvCapability pygen_variable_caps_SampleRateShading[] = {SpvCapabilitySampleRateShading}; +static const SpvCapability pygen_variable_caps_Sampled1D[] = {SpvCapabilitySampled1D}; +static const SpvCapability pygen_variable_caps_Sampled1DImage1D[] = {SpvCapabilitySampled1D, SpvCapabilityImage1D}; +static const SpvCapability pygen_variable_caps_SampledBuffer[] = {SpvCapabilitySampledBuffer}; +static const SpvCapability pygen_variable_caps_SampledBufferImageBuffer[] = {SpvCapabilitySampledBuffer, SpvCapabilityImageBuffer}; +static const SpvCapability pygen_variable_caps_SampledBufferShaderNonUniform[] = {SpvCapabilitySampledBuffer, SpvCapabilityShaderNonUniform}; +static const SpvCapability pygen_variable_caps_SampledCubeArray[] = {SpvCapabilitySampledCubeArray}; +static const SpvCapability pygen_variable_caps_SampledRect[] = {SpvCapabilitySampledRect}; +static const SpvCapability pygen_variable_caps_SampledRectImageRect[] = {SpvCapabilitySampledRect, SpvCapabilityImageRect}; +static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader}; +static const SpvCapability pygen_variable_caps_ShaderImageCubeArray[] = {SpvCapabilityShader, SpvCapabilityImageCubeArray}; +static const SpvCapability pygen_variable_caps_ShaderKernel[] = {SpvCapabilityShader, SpvCapabilityKernel}; +static const SpvCapability pygen_variable_caps_ShaderKernelImageMSArray[] = {SpvCapabilityShader, SpvCapabilityKernel, SpvCapabilityImageMSArray}; +static const SpvCapability pygen_variable_caps_ShaderNonUniform[] = {SpvCapabilityShaderNonUniform}; +static const SpvCapability pygen_variable_caps_ShaderSMBuiltinsNV[] = {SpvCapabilityShaderSMBuiltinsNV}; +static const SpvCapability pygen_variable_caps_ShaderStereoViewNV[] = {SpvCapabilityShaderStereoViewNV}; +static const SpvCapability pygen_variable_caps_ShaderViewportIndexLayerNV[] = {SpvCapabilityShaderViewportIndexLayerNV}; +static const SpvCapability pygen_variable_caps_ShaderViewportMaskNV[] = {SpvCapabilityShaderViewportMaskNV}; +static const SpvCapability pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV[] = {SpvCapabilityShaderViewportMaskNV, SpvCapabilityMeshShadingNV}; +static const SpvCapability pygen_variable_caps_ShadingRateNVFragmentDensityEXT[] = {SpvCapabilityShadingRateNV, SpvCapabilityFragmentDensityEXT}; +static const SpvCapability pygen_variable_caps_SignedZeroInfNanPreserve[] = {SpvCapabilitySignedZeroInfNanPreserve}; +static const SpvCapability pygen_variable_caps_StencilExportEXT[] = {SpvCapabilityStencilExportEXT}; +static const SpvCapability pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16[] = {SpvCapabilityStorageBuffer16BitAccess, SpvCapabilityStorageUniformBufferBlock16}; +static const SpvCapability pygen_variable_caps_StorageBuffer8BitAccess[] = {SpvCapabilityStorageBuffer8BitAccess}; +static const SpvCapability pygen_variable_caps_StorageImageExtendedFormats[] = {SpvCapabilityStorageImageExtendedFormats}; +static const SpvCapability pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot[] = {SpvCapabilitySubgroupBallotKHR, SpvCapabilityGroupNonUniformBallot}; +static const SpvCapability pygen_variable_caps_SubgroupDispatch[] = {SpvCapabilitySubgroupDispatch}; +static const SpvCapability pygen_variable_caps_Tessellation[] = {SpvCapabilityTessellation}; +static const SpvCapability pygen_variable_caps_TransformFeedback[] = {SpvCapabilityTransformFeedback}; +static const SpvCapability pygen_variable_caps_VariablePointersStorageBuffer[] = {SpvCapabilityVariablePointersStorageBuffer}; +static const SpvCapability pygen_variable_caps_VulkanMemoryModel[] = {SpvCapabilityVulkanMemoryModel}; + +static const spvtools::Extension pygen_variable_exts_SPV_AMD_gpu_shader_half_float_fetch[] = {spvtools::Extension::kSPV_AMD_gpu_shader_half_float_fetch}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter[] = {spvtools::Extension::kSPV_AMD_shader_explicit_vertex_parameter}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_image_load_store_lod[] = {spvtools::Extension::kSPV_AMD_shader_image_load_store_lod}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_texture_gather_bias_lod[] = {spvtools::Extension::kSPV_AMD_texture_gather_bias_lod}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_descriptor_indexing[] = {spvtools::Extension::kSPV_EXT_descriptor_indexing}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_fully_covered[] = {spvtools::Extension::kSPV_EXT_fragment_fully_covered}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate[] = {spvtools::Extension::kSPV_EXT_fragment_invocation_density, spvtools::Extension::kSPV_NV_shading_rate}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer, spvtools::Extension::kSPV_KHR_physical_storage_buffer}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_export[] = {spvtools::Extension::kSPV_EXT_shader_stencil_export}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_user_type[] = {spvtools::Extension::kSPV_GOOGLE_user_type}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_blocking_pipes[] = {spvtools::Extension::kSPV_INTEL_blocking_pipes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation[] = {spvtools::Extension::kSPV_INTEL_device_side_avc_motion_estimation}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_loop_controls[] = {spvtools::Extension::kSPV_INTEL_fpga_loop_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_memory_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_reg[] = {spvtools::Extension::kSPV_INTEL_fpga_reg}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_function_pointers[] = {spvtools::Extension::kSPV_INTEL_function_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_kernel_attributes[] = {spvtools::Extension::kSPV_INTEL_kernel_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_media_block_io[] = {spvtools::Extension::kSPV_INTEL_media_block_io}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_shader_integer_functions2[] = {spvtools::Extension::kSPV_INTEL_shader_integer_functions2}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroups[] = {spvtools::Extension::kSPV_INTEL_subgroups}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_16bit_storage[] = {spvtools::Extension::kSPV_KHR_16bit_storage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_8bit_storage[] = {spvtools::Extension::kSPV_KHR_8bit_storage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_device_group[] = {spvtools::Extension::kSPV_KHR_device_group}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_float_controls[] = {spvtools::Extension::kSPV_KHR_float_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_multiview[] = {spvtools::Extension::kSPV_KHR_multiview}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration[] = {spvtools::Extension::kSPV_KHR_no_integer_wrap_decoration}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_querySPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_query, spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_NV_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops[] = {spvtools::Extension::kSPV_KHR_shader_atomic_counter_ops}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parameters[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters, spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_storage_buffer_storage_class, spvtools::Extension::kSPV_KHR_variable_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_variable_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_vulkan_memory_model[] = {spvtools::Extension::kSPV_KHR_vulkan_memory_model}; +static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributes[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes, spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_compute_shader_derivatives[] = {spvtools::Extension::kSPV_NV_compute_shader_derivatives}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_fragment_shader_barycentric[] = {spvtools::Extension::kSPV_NV_fragment_shader_barycentric}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_geometry_shader_passthrough[] = {spvtools::Extension::kSPV_NV_geometry_shader_passthrough}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_mesh_shader, spvtools::Extension::kSPV_NV_viewport_array2}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_sample_mask_override_coverage[] = {spvtools::Extension::kSPV_NV_sample_mask_override_coverage}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_sm_builtins[] = {spvtools::Extension::kSPV_NV_shader_sm_builtins}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_stereo_view_rendering[] = {spvtools::Extension::kSPV_NV_stereo_view_rendering}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_viewport_array2}; + +static const spv_operand_desc_t pygen_variable_ImageOperandsEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Bias", 0x0001, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Lod", 0x0002, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Grad", 0x0004, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstOffset", 0x0008, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Offset", 0x0010, 1, pygen_variable_caps_ImageGatherExtended, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstOffsets", 0x0020, 1, pygen_variable_caps_ImageGatherExtended, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Sample", 0x0040, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MinLod", 0x0080, 1, pygen_variable_caps_MinLod, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MakeTexelAvailable", 0x0100, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeTexelAvailableKHR", 0x0100, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeTexelVisible", 0x0200, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeTexelVisibleKHR", 0x0200, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivateTexel", 0x0400, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivateTexelKHR", 0x0400, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VolatileTexel", 0x0800, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VolatileTexelKHR", 0x0800, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SignExtend", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"ZeroExtend", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FPFastMathModeEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NotNaN", 0x0001, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NotInf", 0x0002, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NSZ", 0x0004, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AllowRecip", 0x0008, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Fast", 0x0010, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SelectionControlEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Flatten", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DontFlatten", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_LoopControlEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unroll", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DontUnroll", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DependencyInfinite", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"DependencyLength", 0x0008, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"MinIterations", 0x0010, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"MaxIterations", 0x0020, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"IterationMultiple", 0x0040, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PeelCount", 0x0080, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PartialCount", 0x0100, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"InitiationIntervalINTEL", 0x10000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxConcurrencyINTEL", 0x20000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"DependencyArrayINTEL", 0x40000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PipelineEnableINTEL", 0x80000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"LoopCoalesceINTEL", 0x100000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxInterleavingINTEL", 0x200000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SpeculatedIterationsINTEL", 0x400000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FunctionControlEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Inline", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DontInline", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Pure", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Const", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_MemorySemanticsEntries[] = { + {"Relaxed", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Acquire", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Release", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AcquireRelease", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SequentiallyConsistent", 0x0010, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UniformMemory", 0x0040, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupMemory", 0x0080, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WorkgroupMemory", 0x0100, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CrossWorkgroupMemory", 0x0200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicCounterMemory", 0x0400, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageMemory", 0x0800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OutputMemory", 0x1000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"OutputMemoryKHR", 0x1000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeAvailable", 0x2000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeAvailableKHR", 0x2000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeVisible", 0x4000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeVisibleKHR", 0x4000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"Volatile", 0x8000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_MemoryAccessEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Volatile", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Aligned", 0x0002, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Nontemporal", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MakePointerAvailable", 0x0008, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakePointerAvailableKHR", 0x0008, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakePointerVisible", 0x0010, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakePointerVisibleKHR", 0x0010, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivatePointer", 0x0020, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivatePointerKHR", 0x0020, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_KernelProfilingInfoEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CmdExecTime", 0x0001, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayFlagsEntries[] = { + {"NoneKHR", 0x0000, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"OpaqueKHR", 0x0001, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"NoOpaqueKHR", 0x0002, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"TerminateOnFirstHitKHR", 0x0004, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SkipClosestHitShaderKHR", 0x0008, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullBackFacingTrianglesKHR", 0x0010, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullFrontFacingTrianglesKHR", 0x0020, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullOpaqueKHR", 0x0040, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullNoOpaqueKHR", 0x0080, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SkipTrianglesKHR", 0x0100, 1, pygen_variable_caps_RayTraversalPrimitiveCullingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SkipAABBsKHR", 0x0200, 1, pygen_variable_caps_RayTraversalPrimitiveCullingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = { + {"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ESSL", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GLSL", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OpenCL_C", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OpenCL_CPP", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"HLSL", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = { + {"Vertex", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TessellationControl", 1, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TessellationEvaluation", 2, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Geometry", 3, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Fragment", 4, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GLCompute", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Kernel", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TaskNV", 5267, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MeshNV", 5268, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayGenerationNV", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayGenerationKHR", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"IntersectionNV", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"IntersectionKHR", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AnyHitNV", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AnyHitKHR", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ClosestHitNV", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ClosestHitKHR", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MissNV", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MissKHR", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CallableNV", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CallableKHR", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_AddressingModelEntries[] = { + {"Logical", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Physical32", 1, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Physical64", 2, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PhysicalStorageBuffer64", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_MemoryModelEntries[] = { + {"Simple", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GLSL450", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OpenCL", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Vulkan", 3, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanKHR", 3, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = { + {"Invocations", 0, 1, pygen_variable_caps_Geometry, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpacingEqual", 1, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpacingFractionalEven", 2, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpacingFractionalOdd", 3, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VertexOrderCw", 4, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VertexOrderCcw", 5, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PixelCenterInteger", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OriginUpperLeft", 7, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OriginLowerLeft", 8, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EarlyFragmentTests", 9, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PointMode", 10, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Xfb", 11, 1, pygen_variable_caps_TransformFeedback, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DepthReplacing", 12, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DepthGreater", 14, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DepthLess", 15, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DepthUnchanged", 16, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LocalSize", 17, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LocalSizeHint", 18, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InputPoints", 19, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InputLines", 20, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InputLinesAdjacency", 21, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Triangles", 22, 2, pygen_variable_caps_GeometryTessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InputTrianglesAdjacency", 23, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Quads", 24, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Isolines", 25, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OutputVertices", 26, 3, pygen_variable_caps_GeometryTessellationMeshShadingNV, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OutputPoints", 27, 2, pygen_variable_caps_GeometryMeshShadingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OutputLineStrip", 28, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OutputTriangleStrip", 29, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VecTypeHint", 30, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ContractionOff", 31, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Initializer", 33, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"Finalizer", 34, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"SubgroupSize", 35, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"SubgroupsPerWorkgroup", 36, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"SubgroupsPerWorkgroupId", 37, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"LocalSizeId", 38, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"LocalSizeHintId", 39, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"PostDepthCoverage", 4446, 1, pygen_variable_caps_SampleMaskPostDepthCoverage, 1, pygen_variable_exts_SPV_KHR_post_depth_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"DenormPreserve", 4459, 1, pygen_variable_caps_DenormPreserve, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"DenormFlushToZero", 4460, 1, pygen_variable_caps_DenormFlushToZero, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"SignedZeroInfNanPreserve", 4461, 1, pygen_variable_caps_SignedZeroInfNanPreserve, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTE", 4462, 1, pygen_variable_caps_RoundingModeRTE, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTZ", 4463, 1, pygen_variable_caps_RoundingModeRTZ, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"StencilRefReplacingEXT", 5027, 1, pygen_variable_caps_StencilExportEXT, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"OutputLinesNV", 5269, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"OutputPrimitivesNV", 5270, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"DerivativeGroupQuadsNV", 5289, 1, pygen_variable_caps_ComputeDerivativeGroupQuadsNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"DerivativeGroupLinearNV", 5290, 1, pygen_variable_caps_ComputeDerivativeGroupLinearNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"OutputTrianglesNV", 5298, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PixelInterlockOrderedEXT", 5366, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"PixelInterlockUnorderedEXT", 5367, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"SampleInterlockOrderedEXT", 5368, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"SampleInterlockUnorderedEXT", 5369, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"ShadingRateInterlockOrderedEXT", 5370, 1, pygen_variable_caps_FragmentShaderShadingRateInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"ShadingRateInterlockUnorderedEXT", 5371, 1, pygen_variable_caps_FragmentShaderShadingRateInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"MaxWorkgroupSizeINTEL", 5893, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxWorkDimINTEL", 5894, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"NoGlobalOffsetINTEL", 5895, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"NumSIMDWorkitemsINTEL", 5896, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { + {"UniformConstant", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Input", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Uniform", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Output", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Workgroup", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CrossWorkgroup", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Private", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Function", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Generic", 8, 1, pygen_variable_caps_GenericPointer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PushConstant", 9, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicCounter", 10, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Image", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageBuffer", 12, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"CallableDataKHR", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingCallableDataKHR", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayPayloadNV", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayPayloadKHR", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitAttributeNV", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitAttributeKHR", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayPayloadNV", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayPayloadKHR", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderRecordBufferNV", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderRecordBufferKHR", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"CodeSectionINTEL", 5605, 1, pygen_variable_caps_FunctionPointersINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DimEntries[] = { + {"1D", 0, 2, pygen_variable_caps_Sampled1DImage1D, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"2D", 1, 3, pygen_variable_caps_ShaderKernelImageMSArray, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"3D", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Cube", 3, 2, pygen_variable_caps_ShaderImageCubeArray, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rect", 4, 2, pygen_variable_caps_SampledRectImageRect, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Buffer", 5, 2, pygen_variable_caps_SampledBufferImageBuffer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubpassData", 6, 1, pygen_variable_caps_InputAttachment, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SamplerAddressingModeEntries[] = { + {"None", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ClampToEdge", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Clamp", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Repeat", 3, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RepeatMirrored", 4, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SamplerFilterModeEntries[] = { + {"Nearest", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Linear", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ImageFormatEntries[] = { + {"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba32f", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba16f", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R32f", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba8", 4, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba8Snorm", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg32f", 6, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg16f", 7, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R11fG11fB10f", 8, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R16f", 9, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba16", 10, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgb10A2", 11, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg16", 12, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg8", 13, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R16", 14, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R8", 15, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba16Snorm", 16, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg16Snorm", 17, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg8Snorm", 18, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R16Snorm", 19, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R8Snorm", 20, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba32i", 21, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba16i", 22, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba8i", 23, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R32i", 24, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg32i", 25, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg16i", 26, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg8i", 27, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R16i", 28, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R8i", 29, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba32ui", 30, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba16ui", 31, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgba8ui", 32, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R32ui", 33, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rgb10a2ui", 34, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg32ui", 35, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg16ui", 36, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rg8ui", 37, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R16ui", 38, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R8ui", 39, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ImageChannelOrderEntries[] = { + {"R", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"A", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RG", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RA", 3, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RGB", 4, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RGBA", 5, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BGRA", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ARGB", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Intensity", 8, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Luminance", 9, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Rx", 10, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RGx", 11, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RGBx", 12, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Depth", 13, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DepthStencil", 14, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"sRGB", 15, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"sRGBx", 16, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"sRGBA", 17, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"sBGRA", 18, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ABGR", 19, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ImageChannelDataTypeEntries[] = { + {"SnormInt8", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SnormInt16", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormInt8", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormInt16", 3, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormShort565", 4, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormShort555", 5, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormInt101010", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedInt8", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedInt16", 8, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedInt32", 9, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedInt8", 10, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedInt16", 11, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedInt32", 12, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"HalfFloat", 13, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float", 14, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormInt24", 15, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnormInt101010_2", 16, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FPRoundingModeEntries[] = { + {"RTE", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RTZ", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RTP", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RTN", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_LinkageTypeEntries[] = { + {"Export", 0, 1, pygen_variable_caps_Linkage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Import", 1, 1, pygen_variable_caps_Linkage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_AccessQualifierEntries[] = { + {"ReadOnly", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WriteOnly", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReadWrite", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FunctionParameterAttributeEntries[] = { + {"Zext", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Sext", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ByVal", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Sret", 3, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoAlias", 4, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoCapture", 5, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoWrite", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoReadWrite", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { + {"RelaxedPrecision", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpecId", 1, 2, pygen_variable_caps_ShaderKernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Block", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BufferBlock", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), SPV_SPIRV_VERSION_WORD(1,3)}, + {"RowMajor", 4, 1, pygen_variable_caps_Matrix, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ColMajor", 5, 1, pygen_variable_caps_Matrix, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ArrayStride", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MatrixStride", 7, 1, pygen_variable_caps_Matrix, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GLSLShared", 8, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GLSLPacked", 9, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CPacked", 10, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BuiltIn", 11, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_BUILT_IN}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoPerspective", 13, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Flat", 14, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Patch", 15, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Centroid", 16, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Sample", 17, 1, pygen_variable_caps_SampleRateShading, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Invariant", 18, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Restrict", 19, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Aliased", 20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Volatile", 21, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Constant", 22, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Coherent", 23, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NonWritable", 24, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NonReadable", 25, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Uniform", 26, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UniformId", 27, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"SaturatedConversion", 28, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Stream", 29, 1, pygen_variable_caps_GeometryStreams, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Location", 30, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Component", 31, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Index", 32, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Binding", 33, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DescriptorSet", 34, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Offset", 35, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"XfbBuffer", 36, 1, pygen_variable_caps_TransformFeedback, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"XfbStride", 37, 1, pygen_variable_caps_TransformFeedback, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FuncParamAttr", 38, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FPRoundingMode", 39, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_FP_ROUNDING_MODE}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FPFastMathMode", 40, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_FP_FAST_MATH_MODE}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LinkageAttributes", 41, 1, pygen_variable_caps_Linkage, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LINKAGE_TYPE}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoContraction", 42, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InputAttachmentIndex", 43, 1, pygen_variable_caps_InputAttachment, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Alignment", 44, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MaxByteOffset", 45, 1, pygen_variable_caps_Addresses, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"AlignmentId", 46, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"MaxByteOffsetId", 47, 1, pygen_variable_caps_Addresses, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"NoSignedWrap", 4469, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"NoUnsignedWrap", 4470, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"ExplicitInterpAMD", 4999, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"OverrideCoverageNV", 5248, 1, pygen_variable_caps_SampleMaskOverrideCoverageNV, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"PassthroughNV", 5250, 1, pygen_variable_caps_GeometryShaderPassthroughNV, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, + {"ViewportRelativeNV", 5252, 1, pygen_variable_caps_ShaderViewportMaskNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SecondaryViewportRelativeNV", 5256, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PerPrimitiveNV", 5271, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerViewNV", 5272, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerTaskNV", 5273, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerVertexNV", 5285, 1, pygen_variable_caps_FragmentBarycentricNV, 1, pygen_variable_exts_SPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"NonUniform", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonUniformEXT", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RestrictPointer", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasedPointer", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ReferencedIndirectlyINTEL", 5602, 1, pygen_variable_caps_IndirectReferencesINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"CounterBuffer", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"HlslCounterBufferGOOGLE", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"UserSemantic", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"HlslSemanticGOOGLE", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"UserTypeGOOGLE", 5636, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_user_type, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"RegisterINTEL", 5825, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"MemoryINTEL", 5826, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"NumbanksINTEL", 5827, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"BankwidthINTEL", 5828, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxPrivateCopiesINTEL", 5829, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SinglepumpINTEL", 5830, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"DoublepumpINTEL", 5831, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"MaxReplicatesINTEL", 5832, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SimpleDualPortINTEL", 5833, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"MergeINTEL", 5834, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"BankBitsINTEL", 5835, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"ForcePow2DepthINTEL", 5836, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = { + {"Position", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PointSize", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ClipDistance", 3, 1, pygen_variable_caps_ClipDistance, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CullDistance", 4, 1, pygen_variable_caps_CullDistance, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VertexId", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InstanceId", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PrimitiveId", 7, 4, pygen_variable_caps_GeometryTessellationRayTracingNVRayTracingProvisionalKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InvocationId", 8, 2, pygen_variable_caps_GeometryTessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Layer", 9, 3, pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ViewportIndex", 10, 3, pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TessLevelOuter", 11, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TessLevelInner", 12, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TessCoord", 13, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PatchVertices", 14, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FragCoord", 15, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PointCoord", 16, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FrontFacing", 17, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampleId", 18, 1, pygen_variable_caps_SampleRateShading, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SamplePosition", 19, 1, pygen_variable_caps_SampleRateShading, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampleMask", 20, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FragDepth", 22, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"HelperInvocation", 23, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NumWorkgroups", 24, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WorkgroupSize", 25, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WorkgroupId", 26, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LocalInvocationId", 27, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GlobalInvocationId", 28, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LocalInvocationIndex", 29, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WorkDim", 30, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GlobalSize", 31, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EnqueuedWorkgroupSize", 32, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GlobalOffset", 33, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GlobalLinearId", 34, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupSize", 36, 3, pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupMaxSize", 37, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NumSubgroups", 38, 2, pygen_variable_caps_KernelGroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NumEnqueuedSubgroups", 39, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupId", 40, 2, pygen_variable_caps_KernelGroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupLocalInvocationId", 41, 3, pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VertexIndex", 42, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InstanceIndex", 43, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupEqMask", 4416, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupEqMaskKHR", 4416, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGeMask", 4417, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGeMaskKHR", 4417, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGtMask", 4418, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGtMaskKHR", 4418, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLeMask", 4419, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLeMaskKHR", 4419, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLtMask", 4420, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLtMaskKHR", 4420, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"BaseVertex", 4424, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"BaseInstance", 4425, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"DrawIndex", 4426, 2, pygen_variable_caps_DrawParametersMeshShadingNV, 2, pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"DeviceIndex", 4438, 1, pygen_variable_caps_DeviceGroup, 1, pygen_variable_exts_SPV_KHR_device_group, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"ViewIndex", 4440, 1, pygen_variable_caps_MultiView, 1, pygen_variable_exts_SPV_KHR_multiview, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"BaryCoordNoPerspAMD", 4992, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspCentroidAMD", 4993, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspSampleAMD", 4994, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordSmoothAMD", 4995, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordSmoothCentroidAMD", 4996, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordSmoothSampleAMD", 4997, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordPullModelAMD", 4998, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"FragStencilRefEXT", 5014, 1, pygen_variable_caps_StencilExportEXT, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"ViewportMaskNV", 5253, 2, pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV, 2, pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"SecondaryPositionNV", 5257, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu}, + {"SecondaryViewportMaskNV", 5258, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu}, + {"PositionPerViewNV", 5261, 2, pygen_variable_caps_PerViewAttributesNVMeshShadingNV, 2, pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"ViewportMaskPerViewNV", 5262, 2, pygen_variable_caps_PerViewAttributesNVMeshShadingNV, 2, pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"FullyCoveredEXT", 5264, 1, pygen_variable_caps_FragmentFullyCoveredEXT, 1, pygen_variable_exts_SPV_EXT_fragment_fully_covered, {}, 0xffffffffu, 0xffffffffu}, + {"TaskCountNV", 5274, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitiveCountNV", 5275, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitiveIndicesNV", 5276, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"ClipDistancePerViewNV", 5277, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"CullDistancePerViewNV", 5278, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"LayerPerViewNV", 5279, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"MeshViewCountNV", 5280, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"MeshViewIndicesNV", 5281, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNV", 5286, 1, pygen_variable_caps_FragmentBarycentricNV, 1, pygen_variable_exts_SPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspNV", 5287, 1, pygen_variable_caps_FragmentBarycentricNV, 1, pygen_variable_exts_SPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"FragSizeEXT", 5292, 2, pygen_variable_caps_FragmentDensityEXTShadingRateNV, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentSizeNV", 5292, 2, pygen_variable_caps_ShadingRateNVFragmentDensityEXT, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"FragInvocationCountEXT", 5293, 2, pygen_variable_caps_FragmentDensityEXTShadingRateNV, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"InvocationsPerPixelNV", 5293, 2, pygen_variable_caps_ShadingRateNVFragmentDensityEXT, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchIdNV", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchIdKHR", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchSizeNV", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchSizeKHR", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayOriginNV", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayOriginKHR", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayDirectionNV", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayDirectionKHR", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayOriginNV", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayOriginKHR", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayDirectionNV", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayDirectionKHR", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTminNV", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTminKHR", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTmaxNV", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTmaxKHR", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"InstanceCustomIndexNV", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"InstanceCustomIndexKHR", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectToWorldNV", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectToWorldKHR", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldToObjectNV", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldToObjectKHR", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitTNV", 5332, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitTKHR", 5332, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitKindNV", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitKindKHR", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayFlagsNV", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayFlagsKHR", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayGeometryIndexKHR", 5352, 1, pygen_variable_caps_RayTracingProvisionalKHR, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"WarpIDNV", 5376, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"SMIDNV", 5377, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ScopeEntries[] = { + {"CrossDevice", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Device", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Workgroup", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Subgroup", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Invocation", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"QueueFamily", 5, 1, pygen_variable_caps_VulkanMemoryModel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"QueueFamilyKHR", 5, 1, pygen_variable_caps_VulkanMemoryModel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ShaderCallKHR", 6, 1, pygen_variable_caps_RayTracingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_GroupOperationEntries[] = { + {"Reduce", 0, 3, pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InclusiveScan", 1, 3, pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ExclusiveScan", 2, 3, pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ClusteredReduce", 3, 1, pygen_variable_caps_GroupNonUniformClustered, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"PartitionedReduceNV", 6, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu}, + {"PartitionedInclusiveScanNV", 7, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu}, + {"PartitionedExclusiveScanNV", 8, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_KernelEnqueueFlagsEntries[] = { + {"NoWait", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WaitKernel", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WaitWorkGroup", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { + {"Matrix", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Shader", 1, 1, pygen_variable_caps_Matrix, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Geometry", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Tessellation", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Addresses", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Linkage", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Kernel", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Vector16", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float16Buffer", 8, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float16", 9, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float64", 10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Int64", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Int64Atomics", 12, 1, pygen_variable_caps_Int64, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageBasic", 13, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageReadWrite", 14, 1, pygen_variable_caps_ImageBasic, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageMipmap", 15, 1, pygen_variable_caps_ImageBasic, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Pipes", 17, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Groups", 18, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DeviceEnqueue", 19, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LiteralSampler", 20, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicStorage", 21, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Int16", 22, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TessellationPointSize", 23, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GeometryPointSize", 24, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageGatherExtended", 25, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageImageMultisample", 27, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UniformBufferArrayDynamicIndexing", 28, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampledImageArrayDynamicIndexing", 29, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageBufferArrayDynamicIndexing", 30, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageImageArrayDynamicIndexing", 31, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ClipDistance", 32, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CullDistance", 33, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageCubeArray", 34, 1, pygen_variable_caps_SampledCubeArray, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampleRateShading", 35, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageRect", 36, 1, pygen_variable_caps_SampledRect, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampledRect", 37, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GenericPointer", 38, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Int8", 39, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InputAttachment", 40, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SparseResidency", 41, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MinLod", 42, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Sampled1D", 43, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Image1D", 44, 1, pygen_variable_caps_Sampled1D, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampledCubeArray", 45, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampledBuffer", 46, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageBuffer", 47, 1, pygen_variable_caps_SampledBuffer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageMSArray", 48, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageImageExtendedFormats", 49, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQuery", 50, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DerivativeControl", 51, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InterpolationFunction", 52, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TransformFeedback", 53, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GeometryStreams", 54, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageImageReadWithoutFormat", 55, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StorageImageWriteWithoutFormat", 56, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MultiViewport", 57, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SubgroupDispatch", 58, 1, pygen_variable_caps_DeviceEnqueue, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"NamedBarrier", 59, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"PipeStorage", 60, 1, pygen_variable_caps_Pipes, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"GroupNonUniform", 61, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformVote", 62, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformArithmetic", 63, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallot", 64, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffle", 65, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffleRelative", 66, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformClustered", 67, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformQuad", 68, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"ShaderLayer", 69, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ShaderViewportIndex", 70, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu}, + {"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupVoteKHR", 4431, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, {}, 0xffffffffu, 0xffffffffu}, + {"StorageBuffer16BitAccess", 4433, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StorageUniformBufferBlock16", 4433, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"UniformAndStorageBuffer16BitAccess", 4434, 2, pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StorageUniform16", 4434, 2, pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StoragePushConstant16", 4435, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StorageInputOutput16", 4436, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"DeviceGroup", 4437, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_device_group, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"MultiView", 4439, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_multiview, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"VariablePointersStorageBuffer", 4441, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"VariablePointers", 4442, 1, pygen_variable_caps_VariablePointersStorageBuffer, 1, pygen_variable_exts_SPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"AtomicStorageOps", 4445, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops, {}, 0xffffffffu, 0xffffffffu}, + {"SampleMaskPostDepthCoverage", 4447, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_post_depth_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"StorageBuffer8BitAccess", 4448, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformAndStorageBuffer8BitAccess", 4449, 1, pygen_variable_caps_StorageBuffer8BitAccess, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StoragePushConstant8", 4450, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"DenormPreserve", 4464, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"DenormFlushToZero", 4465, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"SignedZeroInfNanPreserve", 4466, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTE", 4467, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTZ", 4468, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RayQueryProvisionalKHR", 4471, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_query, {}, 0xffffffffu, 0xffffffffu}, + {"RayTraversalPrimitiveCullingProvisionalKHR", 4478, 2, pygen_variable_caps_RayQueryProvisionalKHRRayTracingProvisionalKHR, 2, pygen_variable_exts_SPV_KHR_ray_querySPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"Float16ImageAMD", 5008, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_gpu_shader_half_float_fetch, {}, 0xffffffffu, 0xffffffffu}, + {"ImageGatherBiasLodAMD", 5009, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_texture_gather_bias_lod, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu}, + {"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderClockKHR", 5055, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_clock, {}, 0xffffffffu, 0xffffffffu}, + {"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderViewportIndexLayerEXT", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderViewportIndexLayerNV", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderViewportMaskNV", 5255, 1, pygen_variable_caps_ShaderViewportIndexLayerNV, 1, pygen_variable_exts_SPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderStereoViewNV", 5259, 1, pygen_variable_caps_ShaderViewportMaskNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu}, + {"PerViewAttributesNV", 5260, 1, pygen_variable_caps_MultiView, 1, pygen_variable_exts_SPV_NVX_multiview_per_view_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentFullyCoveredEXT", 5265, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_fully_covered, {}, 0xffffffffu, 0xffffffffu}, + {"MeshShadingNV", 5266, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"ImageFootprintNV", 5282, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentBarycentricNV", 5284, 0, nullptr, 1, pygen_variable_exts_SPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"ComputeDerivativeGroupQuadsNV", 5288, 0, nullptr, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentDensityEXT", 5291, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"ShadingRateNV", 5291, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformPartitionedNV", 5297, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderNonUniform", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ShaderNonUniformEXT", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RuntimeDescriptorArray", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RuntimeDescriptorArrayEXT", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayDynamicIndexing", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayDynamicIndexingEXT", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayDynamicIndexing", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayDynamicIndexingEXT", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayDynamicIndexing", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayDynamicIndexingEXT", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformBufferArrayNonUniformIndexing", 5306, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformBufferArrayNonUniformIndexingEXT", 5306, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SampledImageArrayNonUniformIndexing", 5307, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SampledImageArrayNonUniformIndexingEXT", 5307, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageBufferArrayNonUniformIndexing", 5308, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageBufferArrayNonUniformIndexingEXT", 5308, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageImageArrayNonUniformIndexing", 5309, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageImageArrayNonUniformIndexingEXT", 5309, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayNonUniformIndexing", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayNonUniformIndexingEXT", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayNonUniformIndexing", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayNonUniformIndexingEXT", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayNonUniformIndexing", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayNonUniformIndexingEXT", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RayTracingNV", 5340, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"VulkanMemoryModel", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanMemoryModelKHR", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanMemoryModelDeviceScope", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanMemoryModelDeviceScopeKHR", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferAddresses", 5347, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferAddressesEXT", 5347, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ComputeDerivativeGroupLinearNV", 5350, 0, nullptr, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingProvisionalKHR", 5353, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixNV", 5357, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShaderSampleInterlockEXT", 5363, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShaderShadingRateInterlockEXT", 5372, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderSMBuiltinsNV", 5373, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShaderPixelInterlockEXT", 5378, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"DemoteToHelperInvocationEXT", 5379, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleINTEL", 5568, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupBufferBlockIOINTEL", 5569, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockIOINTEL", 5570, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageMediaBlockIOINTEL", 5579, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_media_block_io, {}, 0xffffffffu, 0xffffffffu}, + {"IntegerFunctions2INTEL", 5584, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_INTEL_shader_integer_functions2, {}, 0xffffffffu, 0xffffffffu}, + {"FunctionPointersINTEL", 5603, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"IndirectReferencesINTEL", 5604, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMotionEstimationINTEL", 5696, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMotionEstimationIntraINTEL", 5697, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMotionEstimationChromaINTEL", 5698, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAMemoryAttributesINTEL", 5824, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"UnstructuredLoopControlsINTEL", 5886, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, {}, 0xffffffffu, 0xffffffffu}, + {"FPGALoopControlsINTEL", 5888, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {}, 0xffffffffu, 0xffffffffu}, + {"KernelAttributesINTEL", 5892, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAKernelAttributesINTEL", 5897, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"BlockingPipesINTEL", 5945, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGARegINTEL", 5948, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_reg, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat32AddEXT", 6033, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat64AddEXT", 6034, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = { + {"RayQueryCandidateIntersectionKHR", 0, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCommittedIntersectionKHR", 1, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayQueryCommittedIntersectionTypeEntries[] = { + {"RayQueryCommittedIntersectionNoneKHR", 0, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCommittedIntersectionTriangleKHR", 1, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCommittedIntersectionGeneratedKHR", 2, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayQueryCandidateIntersectionTypeEntries[] = { + {"RayQueryCandidateIntersectionTriangleKHR", 0, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCandidateIntersectionAABBKHR", 1, 1, pygen_variable_caps_RayQueryProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugInfoFlagsEntries[] = { + {"FlagIsProtected", 0x01, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPrivate", 0x02, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPublic", 0x03, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsLocal", 0x04, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsDefinition", 0x08, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagFwdDecl", 0x10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagArtificial", 0x20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagExplicit", 0x40, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagPrototyped", 0x80, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagObjectPointer", 0x100, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagStaticMember", 0x200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIndirectVariable", 0x400, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagLValueReference", 0x800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagRValueReference", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsOptimized", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugBaseTypeAttributeEncodingEntries[] = { + {"Unspecified", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Address", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Boolean", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Signed", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedChar", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unsigned", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedChar", 8, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugCompositeTypeEntries[] = { + {"Class", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Structure", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Union", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugTypeQualifierEntries[] = { + {"ConstType", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VolatileType", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RestrictType", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugOperationEntries[] = { + {"Deref", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Plus", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Minus", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PlusUconst", 3, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitPiece", 4, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Swap", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Xderef", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StackValue", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Constu", 8, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugInfoFlagsEntries[] = { + {"FlagIsProtected", 0x01, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPrivate", 0x02, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPublic", 0x03, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsLocal", 0x04, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsDefinition", 0x08, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagFwdDecl", 0x10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagArtificial", 0x20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagExplicit", 0x40, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagPrototyped", 0x80, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagObjectPointer", 0x100, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagStaticMember", 0x200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIndirectVariable", 0x400, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagLValueReference", 0x800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagRValueReference", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsOptimized", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsEnumClass", 0x4000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagTypePassByValue", 0x8000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagTypePassByReference", 0x10000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugBaseTypeAttributeEncodingEntries[] = { + {"Unspecified", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Address", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Boolean", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Signed", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedChar", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unsigned", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedChar", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugCompositeTypeEntries[] = { + {"Class", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Structure", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Union", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugTypeQualifierEntries[] = { + {"ConstType", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VolatileType", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RestrictType", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicType", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugOperationEntries[] = { + {"Deref", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Plus", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Minus", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PlusUconst", 3, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitPiece", 4, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Swap", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Xderef", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StackValue", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Constu", 8, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Fragment", 9, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugImportedEntityEntries[] = { + {"ImportedModule", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImportedDeclaration", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { + {SPV_OPERAND_TYPE_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries}, + {SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, ARRAY_SIZE(pygen_variable_FPFastMathModeEntries), pygen_variable_FPFastMathModeEntries}, + {SPV_OPERAND_TYPE_SELECTION_CONTROL, ARRAY_SIZE(pygen_variable_SelectionControlEntries), pygen_variable_SelectionControlEntries}, + {SPV_OPERAND_TYPE_LOOP_CONTROL, ARRAY_SIZE(pygen_variable_LoopControlEntries), pygen_variable_LoopControlEntries}, + {SPV_OPERAND_TYPE_FUNCTION_CONTROL, ARRAY_SIZE(pygen_variable_FunctionControlEntries), pygen_variable_FunctionControlEntries}, + {SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, ARRAY_SIZE(pygen_variable_MemorySemanticsEntries), pygen_variable_MemorySemanticsEntries}, + {SPV_OPERAND_TYPE_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, + {SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, ARRAY_SIZE(pygen_variable_KernelProfilingInfoEntries), pygen_variable_KernelProfilingInfoEntries}, + {SPV_OPERAND_TYPE_RAY_FLAGS, ARRAY_SIZE(pygen_variable_RayFlagsEntries), pygen_variable_RayFlagsEntries}, + {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, ARRAY_SIZE(pygen_variable_SourceLanguageEntries), pygen_variable_SourceLanguageEntries}, + {SPV_OPERAND_TYPE_EXECUTION_MODEL, ARRAY_SIZE(pygen_variable_ExecutionModelEntries), pygen_variable_ExecutionModelEntries}, + {SPV_OPERAND_TYPE_ADDRESSING_MODEL, ARRAY_SIZE(pygen_variable_AddressingModelEntries), pygen_variable_AddressingModelEntries}, + {SPV_OPERAND_TYPE_MEMORY_MODEL, ARRAY_SIZE(pygen_variable_MemoryModelEntries), pygen_variable_MemoryModelEntries}, + {SPV_OPERAND_TYPE_EXECUTION_MODE, ARRAY_SIZE(pygen_variable_ExecutionModeEntries), pygen_variable_ExecutionModeEntries}, + {SPV_OPERAND_TYPE_STORAGE_CLASS, ARRAY_SIZE(pygen_variable_StorageClassEntries), pygen_variable_StorageClassEntries}, + {SPV_OPERAND_TYPE_DIMENSIONALITY, ARRAY_SIZE(pygen_variable_DimEntries), pygen_variable_DimEntries}, + {SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, ARRAY_SIZE(pygen_variable_SamplerAddressingModeEntries), pygen_variable_SamplerAddressingModeEntries}, + {SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, ARRAY_SIZE(pygen_variable_SamplerFilterModeEntries), pygen_variable_SamplerFilterModeEntries}, + {SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, ARRAY_SIZE(pygen_variable_ImageFormatEntries), pygen_variable_ImageFormatEntries}, + {SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, ARRAY_SIZE(pygen_variable_ImageChannelOrderEntries), pygen_variable_ImageChannelOrderEntries}, + {SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, ARRAY_SIZE(pygen_variable_ImageChannelDataTypeEntries), pygen_variable_ImageChannelDataTypeEntries}, + {SPV_OPERAND_TYPE_FP_ROUNDING_MODE, ARRAY_SIZE(pygen_variable_FPRoundingModeEntries), pygen_variable_FPRoundingModeEntries}, + {SPV_OPERAND_TYPE_LINKAGE_TYPE, ARRAY_SIZE(pygen_variable_LinkageTypeEntries), pygen_variable_LinkageTypeEntries}, + {SPV_OPERAND_TYPE_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries}, + {SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, ARRAY_SIZE(pygen_variable_FunctionParameterAttributeEntries), pygen_variable_FunctionParameterAttributeEntries}, + {SPV_OPERAND_TYPE_DECORATION, ARRAY_SIZE(pygen_variable_DecorationEntries), pygen_variable_DecorationEntries}, + {SPV_OPERAND_TYPE_BUILT_IN, ARRAY_SIZE(pygen_variable_BuiltInEntries), pygen_variable_BuiltInEntries}, + {SPV_OPERAND_TYPE_SCOPE_ID, ARRAY_SIZE(pygen_variable_ScopeEntries), pygen_variable_ScopeEntries}, + {SPV_OPERAND_TYPE_GROUP_OPERATION, ARRAY_SIZE(pygen_variable_GroupOperationEntries), pygen_variable_GroupOperationEntries}, + {SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS, ARRAY_SIZE(pygen_variable_KernelEnqueueFlagsEntries), pygen_variable_KernelEnqueueFlagsEntries}, + {SPV_OPERAND_TYPE_CAPABILITY, ARRAY_SIZE(pygen_variable_CapabilityEntries), pygen_variable_CapabilityEntries}, + {SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION, ARRAY_SIZE(pygen_variable_RayQueryIntersectionEntries), pygen_variable_RayQueryIntersectionEntries}, + {SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE, ARRAY_SIZE(pygen_variable_RayQueryCommittedIntersectionTypeEntries), pygen_variable_RayQueryCommittedIntersectionTypeEntries}, + {SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE, ARRAY_SIZE(pygen_variable_RayQueryCandidateIntersectionTypeEntries), pygen_variable_RayQueryCandidateIntersectionTypeEntries}, + {SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, ARRAY_SIZE(pygen_variable_DebugInfoFlagsEntries), pygen_variable_DebugInfoFlagsEntries}, + {SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, ARRAY_SIZE(pygen_variable_DebugBaseTypeAttributeEncodingEntries), pygen_variable_DebugBaseTypeAttributeEncodingEntries}, + {SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, ARRAY_SIZE(pygen_variable_DebugCompositeTypeEntries), pygen_variable_DebugCompositeTypeEntries}, + {SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, ARRAY_SIZE(pygen_variable_DebugTypeQualifierEntries), pygen_variable_DebugTypeQualifierEntries}, + {SPV_OPERAND_TYPE_DEBUG_OPERATION, ARRAY_SIZE(pygen_variable_DebugOperationEntries), pygen_variable_DebugOperationEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugInfoFlagsEntries), pygen_variable_CLDEBUG100_DebugInfoFlagsEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugBaseTypeAttributeEncodingEntries), pygen_variable_CLDEBUG100_DebugBaseTypeAttributeEncodingEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugCompositeTypeEntries), pygen_variable_CLDEBUG100_DebugCompositeTypeEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugTypeQualifierEntries), pygen_variable_CLDEBUG100_DebugTypeQualifierEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugOperationEntries), pygen_variable_CLDEBUG100_DebugOperationEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugImportedEntityEntries), pygen_variable_CLDEBUG100_DebugImportedEntityEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/spv-amd-gcn-shader.insts.inc b/spirv-tools-sys/generated/spv-amd-gcn-shader.insts.inc new file mode 100644 index 0000000000..1682aff5f6 --- /dev/null +++ b/spirv-tools-sys/generated/spv-amd-gcn-shader.insts.inc @@ -0,0 +1,7 @@ + + +static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = { + {"CubeFaceIndexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"CubeFaceCoordAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"TimeAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/spv-amd-shader-ballot.insts.inc b/spirv-tools-sys/generated/spv-amd-shader-ballot.insts.inc new file mode 100644 index 0000000000..c3b4aa09b8 --- /dev/null +++ b/spirv-tools-sys/generated/spv-amd-shader-ballot.insts.inc @@ -0,0 +1,8 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = { + {"SwizzleInvocationsAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc b/spirv-tools-sys/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc new file mode 100644 index 0000000000..1ed559596d --- /dev/null +++ b/spirv-tools-sys/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc @@ -0,0 +1,5 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = { + {"InterpolateAtVertexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/spirv-tools-sys/generated/spv-amd-shader-trinary-minmax.insts.inc b/spirv-tools-sys/generated/spv-amd-shader-trinary-minmax.insts.inc new file mode 100644 index 0000000000..af7ce826ad --- /dev/null +++ b/spirv-tools-sys/generated/spv-amd-shader-trinary-minmax.insts.inc @@ -0,0 +1,13 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = { + {"FMin3AMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMin3AMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMin3AMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMax3AMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMax3AMD", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMax3AMD", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMid3AMD", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMid3AMD", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMid3AMD", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file From 32fe2a1a8f11dd00c63b1914d2cbf350faa84f28 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:03:44 +0200 Subject: [PATCH 03/41] Add first pass on spirv-tools-sys --- Cargo.toml | 1 + spirv-tools-sys/Cargo.toml | 12 + spirv-tools-sys/build.rs | 241 ++++++++++++ spirv-tools-sys/src/c/opt.cpp | 224 +++++++++++ spirv-tools-sys/src/lib.rs | 4 + spirv-tools-sys/src/opt.rs | 712 ++++++++++++++++++++++++++++++++++ spirv-tools-sys/src/shared.rs | 66 ++++ 7 files changed, 1260 insertions(+) create mode 100644 spirv-tools-sys/Cargo.toml create mode 100644 spirv-tools-sys/build.rs create mode 100644 spirv-tools-sys/src/c/opt.cpp create mode 100644 spirv-tools-sys/src/lib.rs create mode 100644 spirv-tools-sys/src/opt.rs create mode 100644 spirv-tools-sys/src/shared.rs diff --git a/Cargo.toml b/Cargo.toml index e620a1d1ab..dbbcca750f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ members = [ "rustc_codegen_spirv", "spirv-builder", "spirv-std", + "spirv-tools-sys", ] diff --git a/spirv-tools-sys/Cargo.toml b/spirv-tools-sys/Cargo.toml new file mode 100644 index 0000000000..28f1f427a3 --- /dev/null +++ b/spirv-tools-sys/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "spirv-tools-sys" +version = "0.1.0" +authors = ["Jake Shadle "] +edition = "2018" +build = "build.rs" + +[features] +opt = [] + +[build-dependencies] +cc = { version = "1.0", features = ["parallel"] } diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs new file mode 100644 index 0000000000..4e233b75cc --- /dev/null +++ b/spirv-tools-sys/build.rs @@ -0,0 +1,241 @@ +use cc::Build; +use std::path::Path; + +fn add_includes(builder: &mut Build, root: &str, includes: &[&str]) { + let root = Path::new(root); + + for inc in includes { + builder.include(root.join(inc)); + } +} + +fn add_sources(builder: &mut Build, root: &str, files: &[&str]) { + let root = Path::new(root); + builder.files(files.iter().map(|src| { + let mut p = root.join(src); + p.set_extension("cpp"); + p + })); +} + +fn shared(build: &mut Build) { + add_sources( + build, + "spirv-tools/source", + &[ + "util/bit_vector", + "util/parse_number", + "util/string_utils", + "assembly_grammar", + "binary", + "diagnostic", + "disassemble", + "enum_string_mapping", + "ext_inst", + "extensions", + "libspirv", + "name_mapper", + "opcode", + "operand", + "parsed_operand", + "print", + "software_version", + "spirv_endian", + "spirv_fuzzer_options", + "spirv_optimizer_options", + "spirv_reducer_options", + "spirv_target_env", + "spirv_validator_options", + "table", + "text", + "text_handler", + ], + ); +} + +fn opt(build: &mut Build) { + build.file("src/c/opt.cpp"); + + add_sources( + build, + "spirv-tools/source/opt", + &[ + "aggressive_dead_code_elim_pass", + "amd_ext_to_khr", + "basic_block", + "block_merge_pass", + "block_merge_util", + "build_module", + "ccp_pass", + "cfg", + "cfg_cleanup_pass", + "code_sink", + "combine_access_chains", + "compact_ids_pass", + "composite", + "const_folding_rules", + "constants", + "convert_to_half_pass", + "copy_prop_arrays", + "dead_branch_elim_pass", + "dead_insert_elim_pass", + "dead_variable_elimination", + "debug_info_manager", + "decompose_initialized_variables_pass", + "decoration_manager", + "def_use_manager", + "desc_sroa", + "dominator_analysis", + "dominator_tree", + "eliminate_dead_constant_pass", + "eliminate_dead_functions_pass", + "eliminate_dead_functions_util", + "eliminate_dead_members_pass", + "feature_manager", + "fix_storage_class", + "flatten_decoration_pass", + "fold", + "fold_spec_constant_op_and_composite_pass", + "folding_rules", + "freeze_spec_constant_value_pass", + "function", + "generate_webgpu_initializers_pass", + "graphics_robust_access_pass", + "if_conversion", + "inline_exhaustive_pass", + "inline_opaque_pass", + "inline_pass", + "inst_bindless_check_pass", + "inst_buff_addr_check_pass", + "inst_debug_printf_pass", + "instruction", + "instruction_list", + "instrument_pass", + "ir_context", + "ir_loader", + "legalize_vector_shuffle_pass", + "licm_pass", + "local_access_chain_convert_pass", + "local_redundancy_elimination", + "local_single_block_elim_pass", + "local_single_store_elim_pass", + "loop_dependence", + "loop_dependence_helpers", + "loop_descriptor", + "loop_fission", + "loop_fusion", + "loop_fusion_pass", + "loop_peeling", + "loop_unroller", + "loop_unswitch_pass", + "loop_utils", + "mem_pass", + "merge_return_pass", + "module", + "optimizer", + "pass", + "pass_manager", + "pch_source_opt", + "private_to_local_pass", + "process_lines_pass", + "propagator", + "reduce_load_size", + "redundancy_elimination", + "register_pressure", + "relax_float_ops_pass", + "remove_duplicates_pass", + "replace_invalid_opc", + "scalar_analysis", + "scalar_analysis_simplification", + "scalar_replacement_pass", + "set_spec_constant_default_value_pass", + "simplification_pass", + "split_invalid_unreachable_pass", + "ssa_rewrite_pass", + "strength_reduction_pass", + "strip_atomic_counter_memory_pass", + "strip_debug_info_pass", + "strip_reflect_info_pass", + "struct_cfg_analysis", + "type_manager", + "types", + "unify_const_pass", + "upgrade_memory_model", + "value_number_table", + "vector_dce", + "workaround1209", + "wrap_opkill", + ], + ); +} + +fn val(build: &mut Build) { + add_sources( + build, + "spirv-tools/source/val", + &[ + "validate", + "validate_adjacency", + "validate_annotation", + "validate_arithmetics", + "validate_atomics", + "validate_barriers", + "validate_bitwise", + "validate_builtins", + "validate_capability", + "validate_cfg", + "validate_composites", + "validate_constants", + "validate_conversion", + "validate_debug", + "validate_decorations", + "validate_derivatives", + "validate_extensions", + "validate_execution_limitations", + "validate_function", + "validate_id", + "validate_image", + "validate_interfaces", + "validate_instruction", + "validate_layout", + "validate_literals", + "validate_logicals", + "validate_memory", + "validate_memory_semantics", + "validate_misc", + "validate_mode_setting", + "validate_non_uniform", + "validate_primitives", + "validate_scopes", + "validate_small_type_uses", + "validate_type", + "basic_block", + "construct", + "function", + "instruction", + "validation_state", + ], + ); +} + +fn main() { + let mut build = Build::new(); + + add_includes(&mut build, "spirv-tools", &["", "include"]); + add_includes(&mut build, "generated", &[""]); + add_includes( + &mut build, + "spirv-headers", + &["include", "include/spirv/unified1"], + ); + + shared(&mut build); + val(&mut build); + + if cfg!(feature = "opt") { + opt(&mut build); + } + + build.cpp(true); + build.compile("spirv-tools"); +} diff --git a/spirv-tools-sys/src/c/opt.cpp b/spirv-tools-sys/src/c/opt.cpp new file mode 100644 index 0000000000..0bf3ce5113 --- /dev/null +++ b/spirv-tools-sys/src/c/opt.cpp @@ -0,0 +1,224 @@ +#include "spirv-tools/optimizer.hpp" + +struct Optimus; + +enum Passes { + Null, + StripAtomicCounterMemory, + StripDebugInfo, + StripReflectInfo, + EliminateDeadFunctions, + EliminateDeadMembers, + FlattenDecoration, + FreezeSpecConstantValue, + FoldSpecConstantOpAndComposite, + UnifyConstant, + EliminateDeadConstant, + StrengthReduction, + BlockMerge, + InlineExhaustive, + InlineOpaque, + LocalSingleBlockLoadStoreElim, + DeadBranchElim, + LocalMultiStoreElim, + LocalAccessChainConvert, + LocalSingleStoreElim, + InsertExtractElim, + DeadInsertElim, + AggressiveDCE, + PropagateLineInfo, + RedundantLineInfoElim, + CompactIds, + RemoveDuplicates, + CFGCleanup, + DeadVariableElimination, + MergeReturn, + LocalRedundancyElimination, + LoopInvariantCodeMotion, + LoopPeeling, + LoopUnswitch, + RedundancyElimination, + PrivateToLocal, + CCP, + Workaround1209, + IfConversion, + ReplaceInvalidOpcode, + Simplification, + SSARewrite, + ConvertRelaxedToHalf, + RelaxFloatOps, + CopyPropagateArrays, + VectorDCE, + ReduceLoadSize, + CombineAccessChains, + UpgradeMemoryModel, + CodeSinking, + GenerateWebGPUInitializers, + FixStorageClass, + LegalizeVectorShuffle, + DecomposeInitializedVariables, + SplitInvalidUnreachable, + GraphicsRobustAccess, + DescriptorScalarReplacement, + WrapOpKill, + AmdExtToKhr, +}; + +enum RunResult { + InvalidInputBuffer, + InvalidInputSize, + InvalidOutputBuffer, + InvalidOutputSize, + InvalidCallback, + OptimizerFailed, + OptimizerSucceeded, +}; + +typedef void (*optimized_callback)(const uint32_t* data, size_t len, void* ctx); + +extern "C" { + SPIRV_TOOLS_EXPORT Optimus* create_optimizer(spv_target_env target_env) { + spvtools::Optimizer* optimizer = new spvtools::Optimizer(target_env); + + // auto print_msg_to_stderr = [](spv_message_level_t, const char*, + // const spv_position_t&, const char* m) { + // fprintf(stderr, "error: %s\n", m); + // }; + + //optimizer->SetMessageConsumer(print_msg_to_stderr); + + return (Optimus*)optimizer; + } + + SPIRV_TOOLS_EXPORT void destroy_optimizer(Optimus* optimizer) { + delete (spvtools::Optimizer*)optimizer; + } + + SPIRV_TOOLS_EXPORT RunResult run_optimizer( + const Optimus* optimizer, + const uint32_t* input_ptr, + size_t input_size, + optimized_callback callback, + void* ctx, + const spv_optimizer_options options + ) { + if (input_ptr == nullptr) { + return RunResult::InvalidInputBuffer; + } + + if (callback == nullptr) { + return RunResult::InvalidCallback; + } + + auto output_buff = std::vector(); + + auto op = (spvtools::Optimizer*)optimizer; + bool success = false; + if (options == nullptr) { + success = op->Run(input_ptr, input_size, &output_buff); + } else { + success = op->Run(input_ptr, input_size, &output_buff, options); + } + + if (!success) { + return RunResult::OptimizerFailed; + } + + callback(output_buff.data(), output_buff.size(), ctx); + + return RunResult::OptimizerSucceeded; + } + + SPIRV_TOOLS_EXPORT void register_pass(Optimus* optimizer, Passes pass) { + #define PASTEB(a, b) a ## b + #define PASTEA(a, b) PASTEB(a, b) + #define PASS(name) \ + case name: \ + op->RegisterPass(spvtools::PASTEA(PASTEA(Create, name), Pass)()); \ + break; + + spvtools::Optimizer* op = (spvtools::Optimizer*)optimizer; + + switch (pass) { + PASS(Null) + PASS(StripAtomicCounterMemory) + PASS(StripDebugInfo) + PASS(StripReflectInfo) + PASS(EliminateDeadFunctions) + PASS(EliminateDeadMembers) + PASS(FlattenDecoration) + PASS(FreezeSpecConstantValue) + PASS(FoldSpecConstantOpAndComposite) + PASS(UnifyConstant) + PASS(EliminateDeadConstant) + PASS(StrengthReduction) + PASS(BlockMerge) + PASS(InlineExhaustive) + PASS(InlineOpaque) + PASS(LocalSingleBlockLoadStoreElim) + PASS(DeadBranchElim) + PASS(LocalMultiStoreElim) + PASS(LocalAccessChainConvert) + PASS(LocalSingleStoreElim) + PASS(InsertExtractElim) + PASS(DeadInsertElim) + PASS(AggressiveDCE) + PASS(PropagateLineInfo) + PASS(RedundantLineInfoElim) + PASS(CompactIds) + PASS(RemoveDuplicates) + PASS(CFGCleanup) + PASS(DeadVariableElimination) + PASS(MergeReturn) + PASS(LocalRedundancyElimination) + PASS(LoopInvariantCodeMotion) + PASS(LoopPeeling) + PASS(LoopUnswitch) + PASS(RedundancyElimination) + PASS(PrivateToLocal) + PASS(CCP) + PASS(Workaround1209) + PASS(IfConversion) + PASS(ReplaceInvalidOpcode) + PASS(Simplification) + PASS(SSARewrite) + PASS(ConvertRelaxedToHalf) + PASS(RelaxFloatOps) + PASS(CopyPropagateArrays) + PASS(VectorDCE) + PASS(ReduceLoadSize) + PASS(CombineAccessChains) + PASS(UpgradeMemoryModel) + PASS(CodeSinking) + PASS(GenerateWebGPUInitializers) + PASS(FixStorageClass) + PASS(LegalizeVectorShuffle) + PASS(DecomposeInitializedVariables) + PASS(SplitInvalidUnreachable) + PASS(GraphicsRobustAccess) + PASS(DescriptorScalarReplacement) + PASS(WrapOpKill) + PASS(AmdExtToKhr) + } + } + + SPIRV_TOOLS_EXPORT void register_performance_passes(Optimus* optimizer) { + ((spvtools::Optimizer*)optimizer)->RegisterPerformancePasses(); + } + + SPIRV_TOOLS_EXPORT void register_size_passes(Optimus* optimizer) { + ((spvtools::Optimizer*)optimizer)->RegisterSizePasses(); + } + + SPIRV_TOOLS_EXPORT void register_vulkan_to_webgpu_passes(Optimus* optimizer) { + ((spvtools::Optimizer*)optimizer)->RegisterVulkanToWebGPUPasses(); + } + + SPIRV_TOOLS_EXPORT void register_webgpu_to_vulkan_passes(Optimus* optimizer) { + ((spvtools::Optimizer*)optimizer)->RegisterWebGPUToVulkanPasses(); + } + + SPIRV_TOOLS_EXPORT void register_legalization_passes(Optimus* optimizer) { + ((spvtools::Optimizer*)optimizer)->RegisterLegalizationPasses(); + } +} diff --git a/spirv-tools-sys/src/lib.rs b/spirv-tools-sys/src/lib.rs new file mode 100644 index 0000000000..6117315177 --- /dev/null +++ b/spirv-tools-sys/src/lib.rs @@ -0,0 +1,4 @@ +pub mod shared; + +#[cfg(feature = "opt")] +pub mod opt; diff --git a/spirv-tools-sys/src/opt.rs b/spirv-tools-sys/src/opt.rs new file mode 100644 index 0000000000..d1f7ce6847 --- /dev/null +++ b/spirv-tools-sys/src/opt.rs @@ -0,0 +1,712 @@ +#[repr(C)] +pub struct Optimizer { + _unused: [u8; 0], +} + +#[repr(C)] +pub struct OptimizerOptions { + _unused: [u8; 0], +} + +#[repr(C)] +pub struct ValidatorOptions { + _unused: [u8; 0], +} + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub enum Passes { + // Creates a null pass. + // A null pass does nothing to the SPIR-V module to be optimized. + Null, + // Creates a strip-atomic-counter-memory pass. + // A strip-atomic-counter-memory pass removes all usages of the + // AtomicCounterMemory bit in Memory Semantics bitmasks. This bit is a no-op in + // Vulkan, so isn't needed in that env. And the related capability is not + // allowed in WebGPU, so it is not allowed in that env. + StripAtomicCounterMemory, + // Creates a strip-debug-info pass. + // A strip-debug-info pass removes all debug instructions (as documented in + // Section 3.32.2 of the SPIR-V spec) of the SPIR-V module to be optimized. + StripDebugInfo, + // Creates a strip-reflect-info pass. + // A strip-reflect-info pass removes all reflections instructions. + // For now, this is limited to removing decorations defined in + // SPV_GOOGLE_hlsl_functionality1. The coverage may expand in + // the future. + StripReflectInfo, + // Creates an eliminate-dead-functions pass. + // An eliminate-dead-functions pass will remove all functions that are not in + // the call trees rooted at entry points and exported functions. These + // functions are not needed because they will never be called. + EliminateDeadFunctions, + // Creates an eliminate-dead-members pass. + // An eliminate-dead-members pass will remove all unused members of structures. + // This will not affect the data layout of the remaining members. + EliminateDeadMembers, + // Creates a flatten-decoration pass. + // A flatten-decoration pass replaces grouped decorations with equivalent + // ungrouped decorations. That is, it replaces each OpDecorationGroup + // instruction and associated OpGroupDecorate and OpGroupMemberDecorate + // instructions with equivalent OpDecorate and OpMemberDecorate instructions. + // The pass does not attempt to preserve debug information for instructions + // it removes. + FlattenDecoration, + // Creates a freeze-spec-constant-value pass. + // A freeze-spec-constant pass specializes the value of spec constants to + // their default values. This pass only processes the spec constants that have + // SpecId decorations (defined by OpSpecConstant, OpSpecConstantTrue, or + // OpSpecConstantFalse instructions) and replaces them with their normal + // counterparts (OpConstant, OpConstantTrue, or OpConstantFalse). The + // corresponding SpecId annotation instructions will also be removed. This + // pass does not fold the newly added normal constants and does not process + // other spec constants defined by OpSpecConstantComposite or + // OpSpecConstantOp. + FreezeSpecConstantValue, + // Creates a fold-spec-constant-op-and-composite pass. + // A fold-spec-constant-op-and-composite pass folds spec constants defined by + // OpSpecConstantOp or OpSpecConstantComposite instruction, to normal Constants + // defined by OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull, or + // OpConstantComposite instructions. Note that spec constants defined with + // OpSpecConstant, OpSpecConstantTrue, or OpSpecConstantFalse instructions are + // not handled, as these instructions indicate their value are not determined + // and can be changed in future. A spec constant is foldable if all of its + // value(s) can be determined from the module. E.g., an integer spec constant + // defined with OpSpecConstantOp instruction can be folded if its value won't + // change later. This pass will replace the original OpSpecContantOp instruction + // with an OpConstant instruction. When folding composite spec constants, + // new instructions may be inserted to define the components of the composite + // constant first, then the original spec constants will be replaced by + // OpConstantComposite instructions. + // + // There are some operations not supported yet: + // OpSConvert, OpFConvert, OpQuantizeToF16 and + // all the operations under Kernel capability. + // TODO(qining): Add support for the operations listed above. + FoldSpecConstantOpAndComposite, + // Creates a unify-constant pass. + // A unify-constant pass de-duplicates the constants. Constants with the exact + // same value and identical form will be unified and only one constant will + // be kept for each unique pair of type and value. + // There are several cases not handled by this pass: + // 1) Constants defined by OpConstantNull instructions (null constants) and + // constants defined by OpConstantFalse, OpConstant or OpConstantComposite + // with value 0 (zero-valued normal constants) are not considered equivalent. + // So null constants won't be used to replace zero-valued normal constants, + // vice versa. + // 2) Whenever there are decorations to the constant's result id id, the + // constant won't be handled, which means, it won't be used to replace any + // other constants, neither can other constants replace it. + // 3) NaN in float point format with different bit patterns are not unified. + UnifyConstant, + // Creates a eliminate-dead-constant pass. + // A eliminate-dead-constant pass removes dead constants, including normal + // contants defined by OpConstant, OpConstantComposite, OpConstantTrue, or + // OpConstantFalse and spec constants defined by OpSpecConstant, + // OpSpecConstantComposite, OpSpecConstantTrue, OpSpecConstantFalse or + // OpSpecConstantOp. + EliminateDeadConstant, + // Creates a strength-reduction pass. + // A strength-reduction pass will look for opportunities to replace an + // instruction with an equivalent and less expensive one. For example, + // multiplying by a power of 2 can be replaced by a bit shift. + StrengthReduction, + // Creates a block merge pass. + // This pass searches for blocks with a single Branch to a block with no + // other predecessors and merges the blocks into a single block. Continue + // blocks and Merge blocks are not candidates for the second block. + // + // The pass is most useful after Dead Branch Elimination, which can leave + // such sequences of blocks. Merging them makes subsequent passes more + // effective, such as single block local store-load elimination. + // + // While this pass reduces the number of occurrences of this sequence, at + // this time it does not guarantee all such sequences are eliminated. + // + // Presence of phi instructions can inhibit this optimization. Handling + // these is left for future improvements. + BlockMerge, + // Creates an exhaustive inline pass. + // An exhaustive inline pass attempts to exhaustively inline all function + // calls in all functions in an entry point call tree. The intent is to enable, + // albeit through brute force, analysis and optimization across function + // calls by subsequent optimization passes. As the inlining is exhaustive, + // there is no attempt to optimize for size or runtime performance. Functions + // that are not in the call tree of an entry point are not changed. + InlineExhaustive, + // Creates an opaque inline pass. + // An opaque inline pass inlines all function calls in all functions in all + // entry point call trees where the called function contains an opaque type + // in either its parameter types or return type. An opaque type is currently + // defined as Image, Sampler or SampledImage. The intent is to enable, albeit + // through brute force, analysis and optimization across these function calls + // by subsequent passes in order to remove the storing of opaque types which is + // not legal in Vulkan. Functions that are not in the call tree of an entry + // point are not changed. + InlineOpaque, + // Creates a single-block local variable load/store elimination pass. + // For every entry point function, do single block memory optimization of + // function variables referenced only with non-access-chain loads and stores. + // For each targeted variable load, if previous store to that variable in the + // block, replace the load's result id with the value id of the store. + // If previous load within the block, replace the current load's result id + // with the previous load's result id. In either case, delete the current + // load. Finally, check if any remaining stores are useless, and delete store + // and variable if possible. + // + // The presence of access chain references and function calls can inhibit + // the above optimization. + // + // Only modules with relaxed logical addressing (see opt/instruction.h) are + // currently processed. + // + // This pass is most effective if preceeded by Inlining and + // LocalAccessChainConvert. This pass will reduce the work needed to be done + // by LocalSingleStoreElim and LocalMultiStoreElim. + // + // Only functions in the call tree of an entry point are processed. + LocalSingleBlockLoadStoreElim, + // Create dead branch elimination pass. + // For each entry point function, this pass will look for SelectionMerge + // BranchConditionals with constant condition and convert to a Branch to + // the indicated label. It will delete resulting dead blocks. + // + // For all phi functions in merge block, replace all uses with the id + // corresponding to the living predecessor. + // + // Note that some branches and blocks may be left to avoid creating invalid + // control flow. Improving this is left to future work. + // + // This pass is most effective when preceeded by passes which eliminate + // local loads and stores, effectively propagating constant values where + // possible. + DeadBranchElim, + // Creates an SSA local variable load/store elimination pass. + // For every entry point function, eliminate all loads and stores of function + // scope variables only referenced with non-access-chain loads and stores. + // Eliminate the variables as well. + // + // The presence of access chain references and function calls can inhibit + // the above optimization. + // + // Only shader modules with relaxed logical addressing (see opt/instruction.h) + // are currently processed. Currently modules with any extensions enabled are + // not processed. This is left for future work. + // + // This pass is most effective if preceeded by Inlining and + // LocalAccessChainConvert. LocalSingleStoreElim and LocalSingleBlockElim + // will reduce the work that this pass has to do. + LocalMultiStoreElim, + // Creates a local access chain conversion pass. + // A local access chain conversion pass identifies all function scope + // variables which are accessed only with loads, stores and access chains + // with constant indices. It then converts all loads and stores of such + // variables into equivalent sequences of loads, stores, extracts and inserts. + // + // This pass only processes entry point functions. It currently only converts + // non-nested, non-ptr access chains. It does not process modules with + // non-32-bit integer types present. Optional memory access options on loads + // and stores are ignored as we are only processing function scope variables. + // + // This pass unifies access to these variables to a single mode and simplifies + // subsequent analysis and elimination of these variables along with their + // loads and stores allowing values to propagate to their points of use where + // possible. + LocalAccessChainConvert, + // Creates a local single store elimination pass. + // For each entry point function, this pass eliminates loads and stores for + // function scope variable that are stored to only once, where possible. Only + // whole variable loads and stores are eliminated; access-chain references are + // not optimized. Replace all loads of such variables with the value that is + // stored and eliminate any resulting dead code. + // + // Currently, the presence of access chains and function calls can inhibit this + // pass, however the Inlining and LocalAccessChainConvert passes can make it + // more effective. In additional, many non-load/store memory operations are + // not supported and will prohibit optimization of a function. Support of + // these operations are future work. + // + // Only shader modules with relaxed logical addressing (see opt/instruction.h) + // are currently processed. + // + // This pass will reduce the work needed to be done by LocalSingleBlockElim + // and LocalMultiStoreElim and can improve the effectiveness of other passes + // such as DeadBranchElimination which depend on values for their analysis. + LocalSingleStoreElim, + // Creates an insert/extract elimination pass. + // This pass processes each entry point function in the module, searching for + // extracts on a sequence of inserts. It further searches the sequence for an + // insert with indices identical to the extract. If such an insert can be + // found before hitting a conflicting insert, the extract's result id is + // replaced with the id of the values from the insert. + // + // Besides removing extracts this pass enables subsequent dead code elimination + // passes to delete the inserts. This pass performs best after access chains are + // converted to inserts and extracts and local loads and stores are eliminated. + InsertExtractElim, + // Creates a dead insert elimination pass. + // This pass processes each entry point function in the module, searching for + // unreferenced inserts into composite types. These are most often unused + // stores to vector components. They are unused because they are never + // referenced, or because there is another insert to the same component between + // the insert and the reference. After removing the inserts, dead code + // elimination is attempted on the inserted values. + // + // This pass performs best after access chains are converted to inserts and + // extracts and local loads and stores are eliminated. While executing this + // pass can be advantageous on its own, it is also advantageous to execute + // this pass after CreateInsertExtractPass() as it will remove any unused + // inserts created by that pass. + DeadInsertElim, + // Create aggressive dead code elimination pass + // This pass eliminates unused code from the module. In addition, + // it detects and eliminates code which may have spurious uses but which do + // not contribute to the output of the function. The most common cause of + // such code sequences is summations in loops whose result is no longer used + // due to dead code elimination. This optimization has additional compile + // time cost over standard dead code elimination. + // + // This pass only processes entry point functions. It also only processes + // shaders with relaxed logical addressing (see opt/instruction.h). It + // currently will not process functions with function calls. Unreachable + // functions are deleted. + // + // This pass will be made more effective by first running passes that remove + // dead control flow and inlines function calls. + // + // This pass can be especially useful after running Local Access Chain + // Conversion, which tends to cause cycles of dead code to be left after + // Store/Load elimination passes are completed. These cycles cannot be + // eliminated with standard dead code elimination. + AggressiveDCE, + // Create line propagation pass + // This pass propagates line information based on the rules for OpLine and + // OpNoline and clones an appropriate line instruction into every instruction + // which does not already have debug line instructions. + // + // This pass is intended to maximize preservation of source line information + // through passes which delete, move and clone instructions. Ideally it should + // be run before any such pass. It is a bookend pass with EliminateDeadLines + // which can be used to remove redundant line instructions at the end of a + // run of such passes and reduce final output file size. + PropagateLineInfo, + // Create dead line elimination pass + // This pass eliminates redundant line instructions based on the rules for + // OpLine and OpNoline. Its main purpose is to reduce the size of the file + // need to store the SPIR-V without losing line information. + // + // This is a bookend pass with PropagateLines which attaches line instructions + // to every instruction to preserve line information during passes which + // delete, move and clone instructions. DeadLineElim should be run after + // PropagateLines and all such subsequent passes. Normally it would be one + // of the last passes to be run. + RedundantLineInfoElim, + // Creates a compact ids pass. + // The pass remaps result ids to a compact and gapless range starting from %1. + CompactIds, + // Creates a remove duplicate pass. + // This pass removes various duplicates: + // * duplicate capabilities; + // * duplicate extended instruction imports; + // * duplicate types; + // * duplicate decorations. + RemoveDuplicates, + // Creates a CFG cleanup pass. + // This pass removes cruft from the control flow graph of functions that are + // reachable from entry points and exported functions. It currently includes the + // following functionality: + // + // - Removal of unreachable basic blocks. + CFGCleanup, + // Create dead variable elimination pass. + // This pass will delete module scope variables, along with their decorations, + // that are not referenced. + DeadVariableElimination, + // create merge return pass. + // changes functions that have multiple return statements so they have a single + // return statement. + // + // for structured control flow it is assumed that the only unreachable blocks in + // the function are trivial merge and continue blocks. + // + // a trivial merge block contains the label and an opunreachable instructions, + // nothing else. a trivial continue block contain a label and an opbranch to + // the header, nothing else. + // + // these conditions are guaranteed to be met after running dead-branch + // elimination. + MergeReturn, + // Create value numbering pass. + // This pass will look for instructions in the same basic block that compute the + // same value, and remove the redundant ones. + LocalRedundancyElimination, + // Create LICM pass. + // This pass will look for invariant instructions inside loops and hoist them to + // the loops preheader. + LoopInvariantCodeMotion, + // Creates a loop peeling pass. + // This pass will look for conditions inside a loop that are true or false only + // for the N first or last iteration. For loop with such condition, those N + // iterations of the loop will be executed outside of the main loop. + // To limit code size explosion, the loop peeling can only happen if the code + // size growth for each loop is under |code_growth_threshold|. + LoopPeeling, + // Creates a loop unswitch pass. + // This pass will look for loop independent branch conditions and move the + // condition out of the loop and version the loop based on the taken branch. + // Works best after LICM and local multi store elimination pass. + LoopUnswitch, + // Create global value numbering pass. + // This pass will look for instructions where the same value is computed on all + // paths leading to the instruction. Those instructions are deleted. + RedundancyElimination, + // Create a private to local pass. + // This pass looks for variables delcared in the private storage class that are + // used in only one function. Those variables are moved to the function storage + // class in the function that they are used. + PrivateToLocal, + // Creates a conditional constant propagation (CCP) pass. + // This pass implements the SSA-CCP algorithm in + // + // Constant propagation with conditional branches, + // Wegman and Zadeck, ACM TOPLAS 13(2):181-210. + // + // Constant values in expressions and conditional jumps are folded and + // simplified. This may reduce code size by removing never executed jump targets + // and computations with constant operands. + ConditionalConstantPropagation, + // Creates a workaround driver bugs pass. This pass attempts to work around + // a known driver bug (issue #1209) by identifying the bad code sequences and + // rewriting them. + // + // Current workaround: Avoid OpUnreachable instructions in loops. + Workaround1209, + // Creates a pass that converts if-then-else like assignments into OpSelect. + IfConversion, + // Creates a pass that will replace instructions that are not valid for the + // current shader stage by constants. Has no effect on non-shader modules. + ReplaceInvalidOpcode, + // Creates a pass that simplifies instructions using the instruction folder. + Simplification, + // Create the SSA rewrite pass. + // This pass converts load/store operations on function local variables into + // operations on SSA IDs. This allows SSA optimizers to act on these variables. + // Only variables that are local to the function and of supported types are + // processed (see IsSSATargetVar for details). + SSARewrite, + // Create pass to convert relaxed precision instructions to half precision. + // This pass converts as many relaxed float32 arithmetic operations to half as + // possible. It converts any float32 operands to half if needed. It converts + // any resulting half precision values back to float32 as needed. No variables + // are changed. No image operations are changed. + // + // Best if run after function scope store/load and composite operation + // eliminations are run. Also best if followed by instruction simplification, + // redundancy elimination and DCE. + ConvertRelaxedToHalf, + // Create relax float ops pass. + // This pass decorates all float32 result instructions with RelaxedPrecision + // if not already so decorated. + RelaxFloatOps, + // Create copy propagate arrays pass. + // This pass looks to copy propagate memory references for arrays. It looks + // for specific code patterns to recognize array copies. + CopyPropagateArrays, + // Create a vector dce pass. + // This pass looks for components of vectors that are unused, and removes them + // from the vector. Note this would still leave around lots of dead code that + // a pass of ADCE will be able to remove. + VectorDCE, + // Create a pass to reduce the size of loads. + // This pass looks for loads of structures where only a few of its members are + // used. It replaces the loads feeding an OpExtract with an OpAccessChain and + // a load of the specific elements. + ReduceLoadSize, + // Create a pass to combine chained access chains. + // This pass looks for access chains fed by other access chains and combines + // them into a single instruction where possible. + CombineAccessChains, + // Create a pass to upgrade to the VulkanKHR memory model. + // This pass upgrades the Logical GLSL450 memory model to Logical VulkanKHR. + // Additionally, it modifies memory, image, atomic and barrier operations to + // conform to that model's requirements. + UpgradeMemoryModel, + // Create a pass to do code sinking. Code sinking is a transformation + // where an instruction is moved into a more deeply nested construct. + CodeSinking, + // Create a pass to adds initializers for OpVariable calls that require them + // in WebGPU. Currently this pass naively initializes variables that are + // missing an initializer with a null value. In the future it may initialize + // variables to the first value stored in them, if that is a constant. + GenerateWebGPUInitializers, + // Create a pass to fix incorrect storage classes. In order to make code + // generation simpler, DXC may generate code where the storage classes do not + // match up correctly. This pass will fix the errors that it can. + FixStorageClass, + // Create a pass to legalize OpVectorShuffle operands going into WebGPU. WebGPU + // forbids using 0xFFFFFFFF, which indicates an undefined result, so this pass + // converts those literals to 0. + LegalizeVectorShuffle, + // Create a pass to decompose initialized variables into a seperate variable + // declaration and an initial store. + DecomposeInitializedVariables, + // Create a pass to attempt to split up invalid unreachable merge-blocks and + // continue-targets to legalize for WebGPU. + SplitInvalidUnreachable, + // Creates a graphics robust access pass. + // + // This pass injects code to clamp indexed accesses to buffers and internal + // arrays, providing guarantees satisfying Vulkan's robustBufferAccess rules. + // + // TODO(dneto): Clamps coordinates and sample index for pointer calculations + // into storage images (OpImageTexelPointer). For an cube array image, it + // assumes the maximum layer count times 6 is at most 0xffffffff. + // + // NOTE: This pass will fail with a message if: + // - The module is not a Shader module. + // - The module declares VariablePointers, VariablePointersStorageBuffer, or + // RuntimeDescriptorArrayEXT capabilities. + // - The module uses an addressing model other than Logical + // - Access chain indices are wider than 64 bits. + // - Access chain index for a struct is not an OpConstant integer or is out + // of range. (The module is already invalid if that is the case.) + // - TODO(dneto): The OpImageTexelPointer coordinate component is not 32-bits + // wide. + // + // NOTE: Access chain indices are always treated as signed integers. So + // if an array has a fixed size of more than 2^31 elements, then elements + // from 2^31 and above are never accessible with a 32-bit index, + // signed or unsigned. For this case, this pass will clamp the index + // between 0 and at 2^31-1, inclusive. + // Similarly, if an array has more then 2^15 element and is accessed with + // a 16-bit index, then elements from 2^15 and above are not accessible. + // In this case, the pass will clamp the index between 0 and 2^15-1 + // inclusive. + GraphicsRobustAccess, + // Create descriptor scalar replacement pass. + // This pass replaces every array variable |desc| that has a DescriptorSet and + // Binding decorations with a new variable for each element of the array. + // Suppose |desc| was bound at binding |b|. Then the variable corresponding to + // |desc[i]| will have binding |b+i|. The descriptor set will be the same. It + // is assumed that no other variable already has a binding that will used by one + // of the new variables. If not, the pass will generate invalid Spir-V. All + // accesses to |desc| must be OpAccessChain instructions with a literal index + // for the first index. + DescriptorScalarReplacement, + // Create a pass to replace each OpKill instruction with a function call to a + // function that has a single OpKill. Also replace each OpTerminateInvocation + // instruction with a function call to a function that has a single + // OpTerminateInvocation. This allows more code to be inlined. + WrapOpKill, + // Replaces the extensions VK_AMD_shader_ballot,VK_AMD_gcn_shader, and + // VK_AMD_shader_trinary_minmax with equivalent code using core instructions and + // capabilities. + AmdExtToKhr, +} + +#[derive(Copy, Clone, Debug, PartialEq)] +#[repr(C)] +pub enum RunResult { + InvalidInputBuffer, + InvalidInputSize, + InvalidOutputBuffer, + InvalidOutputSize, + InvalidCallback, + OptimizerFailed, + OptimizerSucceeded, +} + +extern "C" { + pub fn create_optimizer(env: crate::shared::TargetEnv) -> *mut Optimizer; + pub fn destroy_optimizer(opt: *mut Optimizer); + + pub fn run_optimizer( + opt: *const Optimizer, + input_ptr: *const u32, + input_size: usize, + callback: extern "C" fn(*const u32, usize, *mut std::ffi::c_void), + ctx: *mut std::ffi::c_void, + options: *const OptimizerOptions, + ) -> RunResult; + + /// Creates an optimizer options object with default options. Returns a valid + /// options object. The object remains valid until it is passed into + /// |spvOptimizerOptionsDestroy|. + #[link_name = "spvOptimizerOptionsCreate"] + pub fn create_optimizer_options() -> *mut OptimizerOptions; + + /// Destroys the given optimizer options object. + #[link_name = "spvOptimizerOptionsDestroy"] + pub fn destroy_optimizer_options(options: *mut OptimizerOptions); + + /// Records whether or not the optimizer should run the validator before + /// optimizing. If |val| is true, the validator will be run. + #[link_name = "spvOptimizerOptionsSetRunValidator"] + pub fn optimizer_options_run_validator(options: *mut OptimizerOptions, run: bool); + + /// Records the validator options that should be passed to the validator if it is + /// run. + #[link_name = "spvOptimizerOptionsSetValidatorOptions"] + pub fn optimizer_options_set_validator_options( + options: *mut OptimizerOptions, + validator_opts: *mut ValidatorOptions, + ); + + /// Records the maximum possible value for the id bound. + #[link_name = "spvOptimizerOptionsSetMaxIdBound"] + pub fn optimizer_options_set_max_id_bound(options: *mut OptimizerOptions, max: u32); + + /// Records whether all bindings within the module should be preserved. + #[link_name = "spvOptimizerOptionsSetPreserveBindings"] + pub fn optimizer_options_preserve_bindings(options: *mut OptimizerOptions, preserve: bool); + + /// Records whether all specialization constants within the module + /// should be preserved. + #[link_name = "spvOptimizerOptionsSetPreserveSpecConstants"] + pub fn optimizer_options_preserve_spec_constants( + options: *mut OptimizerOptions, + preserve: bool, + ); + + pub fn register_pass(opt: *mut Optimizer, which: Passes); + + /// Registers passes that attempt to improve performance of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + pub fn register_performance_passes(opt: *mut Optimizer); + + /// Registers passes that attempt to improve the size of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + pub fn register_size_passes(opt: *mut Optimizer); + + /// Registers passes that have been prescribed for converting from Vulkan to + /// WebGPU. This sequence of passes is subject to constant review and will + /// change from time to time. + pub fn register_vulkan_to_webgpu_passes(opt: *mut Optimizer); + + /// Registers passes that have been prescribed for converting from WebGPU to + /// Vulkan. This sequence of passes is subject to constant review and will + /// change from time to time. + pub fn register_webgpu_to_vulkan_passes(opt: *mut Optimizer); + + /// Registers passes that attempt to legalize the generated code. + /// + /// Note: this recipe is specially designed for legalizing SPIR-V. It should be + /// used by compilers after translating HLSL source code literally. It should + /// *not* be used by general workloads for performance or size improvement. + /// + /// This sequence of passes is subject to constant review and will change + /// from time to time. + pub fn register_legalization_passes(opt: *mut Optimizer); + +// Some passes take arguments, so we create those separately on a +// case-by-case basis + +// #[repr(C)] +// pub struct SpecConstantDefault { +// pub id: u32, +// pub value_ptr: *const c_char, +// pub value_len: usize, +// } + +// Creates a set-spec-constant-default-value pass from a mapping from spec-ids +// to the default values in the form of string. +// A set-spec-constant-default-value pass sets the default values for the +// spec constants that have SpecId decorations (i.e., those defined by +// OpSpecConstant{|True|False} instructions). +// SetSpecConstantDefaultValuePass( +// const std::unordered_map& id_value_map); + +// Create a pass to instrument OpDebugPrintf instructions. +// This pass replaces all OpDebugPrintf instructions with instructions to write +// a record containing the string id and the all specified values into a special +// printf output buffer (if space allows). This pass is designed to support +// the printf validation in the Vulkan validation layers. +// +// The instrumentation will write buffers in debug descriptor set |desc_set|. +// It will write |shader_id| in each output record to identify the shader +// module which generated the record. +// InstDebugPrintfPass(uint32_t desc_set, +// uint32_t shader_id); + +// Create a pass to instrument bindless descriptor checking +// This pass instruments all bindless references to check that descriptor +// array indices are inbounds, and if the descriptor indexing extension is +// enabled, that the descriptor has been initialized. If the reference is +// invalid, a record is written to the debug output buffer (if space allows) +// and a null value is returned. This pass is designed to support bindless +// validation in the Vulkan validation layers. +// +// TODO(greg-lunarg): Add support for buffer references. Currently only does +// checking for image references. +// +// Dead code elimination should be run after this pass as the original, +// potentially invalid code is not removed and could cause undefined behavior, +// including crashes. It may also be beneficial to run Simplification +// (ie Constant Propagation), DeadBranchElim and BlockMerge after this pass to +// optimize instrument code involving the testing of compile-time constants. +// It is also generally recommended that this pass (and all +// instrumentation passes) be run after any legalization and optimization +// passes. This will give better analysis for the instrumentation and avoid +// potentially de-optimizing the instrument code, for example, inlining +// the debug record output function throughout the module. +// +// The instrumentation will read and write buffers in debug +// descriptor set |desc_set|. It will write |shader_id| in each output record +// to identify the shader module which generated the record. +// |input_length_enable| controls instrumentation of runtime descriptor array +// references, and |input_init_enable| controls instrumentation of descriptor +// initialization checking, both of which require input buffer support. +// InstBindlessCheckPass( +// uint32_t desc_set, uint32_t shader_id, bool input_length_enable = false, +// bool input_init_enable = false, bool input_buff_oob_enable = false); + +// // Create a pass to instrument physical buffer address checking +// // This pass instruments all physical buffer address references to check that +// // all referenced bytes fall in a valid buffer. If the reference is +// // invalid, a record is written to the debug output buffer (if space allows) +// // and a null value is returned. This pass is designed to support buffer +// // address validation in the Vulkan validation layers. +// // +// // Dead code elimination should be run after this pass as the original, +// // potentially invalid code is not removed and could cause undefined behavior, +// // including crashes. Instruction simplification would likely also be +// // beneficial. It is also generally recommended that this pass (and all +// // instrumentation passes) be run after any legalization and optimization +// // passes. This will give better analysis for the instrumentation and avoid +// // potentially de-optimizing the instrument code, for example, inlining +// // the debug record output function throughout the module. +// // +// // The instrumentation will read and write buffers in debug +// // descriptor set |desc_set|. It will write |shader_id| in each output record +// // to identify the shader module which generated the record. +// InstBuffAddrCheckPass(uint32_t desc_set, +// uint32_t shader_id); + +// Create loop unroller pass. +// Creates a pass to unroll loops which have the "Unroll" loop control +// mask set. The loops must meet a specific criteria in order to be unrolled +// safely this criteria is checked before doing the unroll by the +// LoopUtils::CanPerformUnroll method. Any loop that does not meet the criteria +// won't be unrolled. See CanPerformUnroll LoopUtils.h for more information. +//LoopUnrollPass(bool fully_unroll, int factor = 0); + +// Create scalar replacement pass. +// This pass replaces composite function scope variables with variables for each +// element if those elements are accessed individually. The parameter is a +// limit on the number of members in the composite variable that the pass will +// consider replacing. +//ScalarReplacementPass(uint32_t size_limit = 100); + +// Creates a loop fission pass. +// This pass will split all top level loops whose register pressure exceedes the +// given |threshold|. +//LoopFissionPass(size_t threshold); + +// Creates a loop fusion pass. +// This pass will look for adjacent loops that are compatible and legal to be +// fused. The fuse all such loops as long as the register usage for the fused +// loop stays under the threshold defined by |max_registers_per_loop|. +//LoopFusionPass(size_t max_registers_per_loop); +} diff --git a/spirv-tools-sys/src/shared.rs b/spirv-tools-sys/src/shared.rs new file mode 100644 index 0000000000..c9099d8d91 --- /dev/null +++ b/spirv-tools-sys/src/shared.rs @@ -0,0 +1,66 @@ +/// Certain target environments impose additional restrictions on SPIR-V, so it's +/// often necessary to specify which one applies. `Universal_*` implies an +/// environment-agnostic SPIR-V. +/// +/// When an API method needs to derive a SPIR-V version from a target environment +/// the method will choose the highest version of SPIR-V supported by the target +/// environment. Examples: +/// SPV_ENV_VULKAN_1_0 -> SPIR-V 1.0 +/// SPV_ENV_VULKAN_1_1 -> SPIR-V 1.3 +/// SPV_ENV_VULKAN_1_1_SPIRV_1_4 -> SPIR-V 1.4 +/// SPV_ENV_VULKAN_1_2 -> SPIR-V 1.5 +/// +/// Consult the description of API entry points for specific rules. +#[derive(Copy, Clone, Debug)] +#[repr(C)] +#[allow(non_camel_case_types)] +pub enum TargetEnv { + /// SPIR-V 1.0 latest revision, no other restrictions. + Universal_1_0, + /// Vulkan 1.0 latest revision. + Vulkan_1_0, + /// SPIR-V 1.1 latest revision, no other restrictions. + Universal_1_1, + /// OpenCL Full Profile 2.1 latest revision. + OpenCL_2_1, + /// OpenCL Full Profile 2.2 latest revision. + OpenCL_2_2, + /// OpenGL 4.0 plus GL_ARB_gl_spirv, latest revisions. + OpenGL_4_0, + /// OpenGL 4.1 plus GL_ARB_gl_spirv, latest revisions. + OpenGL_4_1, + /// OpenGL 4.2 plus GL_ARB_gl_spirv, latest revisions. + OpenGL_4_2, + /// OpenGL 4.3 plus GL_ARB_gl_spirv, latest revisions. + OpenGL_4_3, + /// OpenGL 4.5 plus GL_ARB_gl_spirv, latest revisions. + OpenGL_4_5, + /// SPIR-V 1.2, latest revision, no other restrictions. + Universal_1_2, + /// OpenCL Full Profile 1.2 plus cl_khr_il_program, latest revision. + OpenCL_1_2, + /// OpenCL Embedded Profile 1.2 plus cl_khr_il_program, latest revision. + OpenCLEmbedded_1_2, + /// OpenCL Full Profile 2.0 plus cl_khr_il_program, latest revision. + OpenCL_2_0, + /// OpenCL Embedded Profile 2.0 plus cl_khr_il_program, latest revision. + OpenCLEmbedded_2_0, + /// OpenCL Embedded Profile 2.1 latest revision. + OpenCLEmbedded_2_1, + /// OpenCL Embedded Profile 2.2 latest revision. + OpenCLEmbedded_2_2, + /// SPIR-V 1.3 latest revision, no other restrictions. + Universal_1_3, + /// Vulkan 1.1 latest revision. + Vulkan_1_1, + /// Work in progress WebGPU 1.0. + WebGPU_0, + /// SPIR-V 1.4 latest revision, no other restrictions. + Universal_1_4, + /// Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary. + Vulkan_1_1_Spirv_1_4, + /// SPIR-V 1.5 latest revision, no other restrictions. + Universal_1_5, + /// Vulkan 1.2 latest revision. + Vulkan_1_2, +} From 095ec40289569468975fbca7d44b490f3985ee0e Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:04:11 +0200 Subject: [PATCH 04/41] Add first pass on spirv-tools --- Cargo.toml | 1 + spirv-tools/Cargo.toml | 11 +++ spirv-tools/src/lib.rs | 4 + spirv-tools/src/opt.rs | 161 +++++++++++++++++++++++++++++++++ spirv-tools/src/opt/options.rs | 41 +++++++++ 5 files changed, 218 insertions(+) create mode 100644 spirv-tools/Cargo.toml create mode 100644 spirv-tools/src/lib.rs create mode 100644 spirv-tools/src/opt.rs create mode 100644 spirv-tools/src/opt/options.rs diff --git a/Cargo.toml b/Cargo.toml index dbbcca750f..cd6dd32345 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,6 @@ members = [ "rustc_codegen_spirv", "spirv-builder", "spirv-std", + "spirv-tools", "spirv-tools-sys", ] diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml new file mode 100644 index 0000000000..d820d107f5 --- /dev/null +++ b/spirv-tools/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "spirv-tools" +version = "0.1.0" +authors = ["Embark "] +edition = "2018" + +[features] +opt = ["spirv-tools-sys/opt"] + +[dependencies] +spirv-tools-sys = { path = "../spirv-tools-sys" } diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs new file mode 100644 index 0000000000..9da7979f7e --- /dev/null +++ b/spirv-tools/src/lib.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "opt")] +pub mod opt; + +pub use spirv_tools_sys::shared; diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs new file mode 100644 index 0000000000..d1209a6d45 --- /dev/null +++ b/spirv-tools/src/opt.rs @@ -0,0 +1,161 @@ +mod options; + +use spirv_tools_sys::opt; + +pub use opt::{Passes, RunResult}; +pub use options::Options; + +pub trait OptimizeCallback { + fn optimized(&mut self, data: &[u32]); +} + +impl OptimizeCallback for F +where + F: FnMut(&[u32]), +{ + fn optimized(&mut self, data: &[u32]) { + self(data) + } +} + +pub struct Optimizer { + inner: *mut opt::Optimizer, +} + +impl Optimizer { + #[inline] + pub fn new(target: spirv_tools_sys::shared::TargetEnv) -> Self { + Self { + inner: unsafe { opt::create_optimizer(target) }, + } + } + + #[inline] + pub fn optimize( + &self, + input: &[u32], + oc: &mut F, + options: Option<&Options>, + ) -> Result<(), RunResult> { + unsafe { + struct Ctx<'a> { + cb: &'a mut dyn OptimizeCallback, + } + + let mut ctx = Ctx { cb: oc }; + + let cb_ctx: *mut std::ffi::c_void = std::mem::transmute(&mut ctx); + + extern "C" fn callback(data: *const u32, len: usize, ctx: *mut std::ffi::c_void) { + unsafe { + let optimized_binary = std::slice::from_raw_parts(data, len); + let ctx: &mut Ctx<'_> = std::mem::transmute(ctx); + + ctx.cb.optimized(optimized_binary); + } + } + + let options = match options { + Some(opts) => opts.inner, + None => std::ptr::null(), + }; + + let result = opt::run_optimizer( + self.inner, + input.as_ptr(), + input.len(), + callback, + cb_ctx, + options, + ); + + if result != opt::RunResult::OptimizerSucceeded { + return Err(result); + } + } + + Ok(()) + } + + #[inline] + pub fn optimize_to_buffer( + &self, + input: &[u32], + options: Option<&Options>, + ) -> Result, RunResult> { + let mut buffer = None; + self.optimize( + input, + &mut |data: &[u32]| { + buffer = Some(data.to_vec()); + }, + options, + )?; + + buffer.ok_or_else(|| RunResult::OptimizerFailed) + } + + /// Register a single pass with the the optimizer. + #[inline] + pub fn register_pass(&mut self, pass: Passes) -> &mut Self { + unsafe { opt::register_pass(self.inner, pass) } + self + } + + /// Registers passes that attempt to improve performance of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + pub fn register_performance_passes(&mut self) -> &mut Self { + unsafe { opt::register_performance_passes(self.inner) } + self + } + + /// Registers passes that attempt to improve the size of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + pub fn register_size_passes(&mut self) -> &mut Self { + unsafe { opt::register_size_passes(self.inner) } + self + } + + /// Registers passes that have been prescribed for converting from Vulkan to + /// WebGPU. This sequence of passes is subject to constant review and will + /// change from time to time. + #[inline] + pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self { + unsafe { opt::register_vulkan_to_webgpu_passes(self.inner) } + self + } + + /// Registers passes that have been prescribed for converting from WebGPU to + /// Vulkan. This sequence of passes is subject to constant review and will + /// change from time to time. + #[inline] + pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self { + unsafe { opt::register_webgpu_to_vulkan_passes(self.inner) } + self + } + + /// Registers passes that attempt to legalize the generated code. + /// + /// Note: this recipe is specially designed for legalizing SPIR-V. It should be + /// used by compilers after translating HLSL source code literally. It should + /// *not* be used by general workloads for performance or size improvement. + /// + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + pub fn register_legalization_passes(&mut self) -> &mut Self { + unsafe { opt::register_legalization_passes(self.inner) } + self + } +} + +impl Drop for Optimizer { + #[inline] + fn drop(&mut self) { + unsafe { opt::destroy_optimizer(self.inner) } + } +} diff --git a/spirv-tools/src/opt/options.rs b/spirv-tools/src/opt/options.rs new file mode 100644 index 0000000000..ed964d049e --- /dev/null +++ b/spirv-tools/src/opt/options.rs @@ -0,0 +1,41 @@ +use spirv_tools_sys::opt; + +pub struct Options { + pub(crate) inner: *mut opt::OptimizerOptions, +} + +impl Options { + #[inline] + pub fn new() -> Self { + Self { + inner: unsafe { opt::create_optimizer_options() }, + } + } + + #[inline] + pub fn run_validator(&mut self, toggle: bool) { + unsafe { opt::optimizer_options_run_validator(self.inner, toggle) } + } + + #[inline] + pub fn set_max_id_bounds(&mut self, max: u32) { + unsafe { opt::optimizer_options_set_max_id_bound(self.inner, max) } + } + + #[inline] + pub fn preserve_bindings(&mut self, toggle: bool) { + unsafe { opt::optimizer_options_preserve_bindings(self.inner, toggle) } + } + + #[inline] + pub fn preserve_spec_constants(&mut self, toggle: bool) { + unsafe { opt::optimizer_options_preserve_spec_constants(self.inner, toggle) } + } +} + +impl Drop for Options { + #[inline] + fn drop(&mut self) { + unsafe { opt::destroy_optimizer_options(self.inner) } + } +} From cac9704b3c6145a67c560563d45382225d28f6b4 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:09:28 +0200 Subject: [PATCH 05/41] Replace invocation of spirv-opt with spirv-tools crate --- Cargo.lock | 15 ++++++++ rustc_codegen_spirv/Cargo.toml | 5 +++ rustc_codegen_spirv/src/link.rs | 62 ++++++++++++++++++++++----------- spirv-tools-sys/spirv-headers | 2 +- spirv-tools-sys/spirv-tools | 2 +- 5 files changed, 63 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b91608536..36ccad42db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1983,6 +1983,7 @@ dependencies = [ "bimap", "pretty_assertions", "rspirv", + "spirv-tools", "tar", "tempfile", "thiserror", @@ -2199,6 +2200,20 @@ dependencies = [ name = "spirv-std" version = "0.1.0" +[[package]] +name = "spirv-tools" +version = "0.1.0" +dependencies = [ + "spirv-tools-sys", +] + +[[package]] +name = "spirv-tools-sys" +version = "0.1.0" +dependencies = [ + "cc", +] + [[package]] name = "spirv_cross" version = "0.22.0" diff --git a/rustc_codegen_spirv/Cargo.toml b/rustc_codegen_spirv/Cargo.toml index 9e6500a4d4..2d2ea755ec 100644 --- a/rustc_codegen_spirv/Cargo.toml +++ b/rustc_codegen_spirv/Cargo.toml @@ -22,3 +22,8 @@ topological-sort = "0.1" [dev-dependencies] pretty_assertions = "0.6" tempfile = "3.1" + +[dependencies.spirv-tools] +version = "0.1.0" +path = "../spirv-tools" +features = ["opt"] diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 8259ea1c63..04c1ef97fb 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -124,37 +124,54 @@ fn link_exe( codegen_results, ); - do_link(sess, &objects, &rlibs, out_filename, legalize); + let spv_binary = do_link(sess, &objects, &rlibs, out_filename, legalize); if env::var("SPIRV_OPT").is_ok() { let _timer = sess.timer("link_spirv_opt"); - do_spirv_opt(sess, out_filename); + do_spirv_opt(sess, &spv_binary, out_filename); } + if env::var("NO_SPIRV_VAL").is_err() { do_spirv_val(sess, out_filename); } } -fn do_spirv_opt(sess: &Session, filename: &Path) { - let tmp = filename.with_extension("opt.spv"); - let output = output_spirv_tool( - sess, - "spirv-opt", - |cmd| { - cmd.args(&["-Os", "--eliminate-dead-const", "--strip-debug"]) - .arg(&filename) - .arg("-o") - .arg(&tmp) - }, - |_| { - let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); - err.note(&format!("module {:?}", filename)); - err +fn do_spirv_opt(sess: &Session, spv_binary: &[u32], filename: &Path) { + use spirv_tools::{opt, shared}; + + // This is the same default target environment that spirv-opt uses + let mut optimizer = opt::Optimizer::new(shared::TargetEnv::Universal_1_5); + + optimizer + .register_size_passes() + .register_pass(opt::Passes::EliminateDeadConstant) + .register_pass(opt::Passes::StripDebugInfo); + + let mut write_result = None; + let mut opts = opt::Options::new(); + opts.run_validator(false); + + let result = optimizer.optimize( + spv_binary, + &mut |data: &[u32]| { + write_result = Some(std::fs::write(filename, crate::slice_u32_to_u8(&data))); }, + Some(&opts), ); - if output.is_some() { - std::fs::rename(tmp, filename).unwrap(); + match result { + Err(opt::RunResult::OptimizerFailed) => { + let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); + err.note(&format!("module {:?}", filename)); + } + Ok(_) => { + write_result.unwrap().unwrap(); + } + _ => { + let mut err = + sess.struct_warn("invalid arguments supplied to spirv-opt, leaving as unoptimized"); + err.note(&format!("module {:?}", filename)); + } } } @@ -374,7 +391,7 @@ fn do_link( rlibs: &[PathBuf], out_filename: &Path, legalize: bool, -) { +) -> Vec { let load_modules_timer = sess.timer("link_load_modules"); let mut modules = Vec::new(); // `objects` are the plain obj files we need to link - usually produced by the final crate. @@ -446,9 +463,10 @@ fn do_link( // And finally write out the linked binary. use rspirv::binary::Assemble; + let spv_binary = assembled.assemble(); File::create(out_filename) .unwrap() - .write_all(crate::slice_u32_to_u8(&assembled.assemble())) + .write_all(crate::slice_u32_to_u8(&spv_binary)) .unwrap(); drop(save_modules_timer); @@ -457,6 +475,8 @@ fn do_link( rspirv::binary::parse_bytes(&bytes, &mut loader).unwrap(); loader.module() } + + spv_binary } /// As of right now, this is essentially a no-op, just plumbing through all the files. diff --git a/spirv-tools-sys/spirv-headers b/spirv-tools-sys/spirv-headers index 05836bdba6..7845730cab 160000 --- a/spirv-tools-sys/spirv-headers +++ b/spirv-tools-sys/spirv-headers @@ -1 +1 @@ -Subproject commit 05836bdba63e7debce9fa9feaed42f20cd43af9d +Subproject commit 7845730cab6ebbdeb621e7349b7dc1a59c3377be diff --git a/spirv-tools-sys/spirv-tools b/spirv-tools-sys/spirv-tools index 99ad4f1e29..36494dd966 160000 --- a/spirv-tools-sys/spirv-tools +++ b/spirv-tools-sys/spirv-tools @@ -1 +1 @@ -Subproject commit 99ad4f1e29a382f2a2ec01c6a555edf6e8136c83 +Subproject commit 36494dd966ecaa4a399f3f7755bbdcf561229503 From 6739ca974b1125e86ef51af3e730c754dd705e36 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:35:56 +0200 Subject: [PATCH 06/41] Use C++11 --- spirv-tools-sys/build.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 4e233b75cc..a51a1e97b1 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -236,6 +236,12 @@ fn main() { opt(&mut build); } + if build.get_compiler().is_like_msvc() { + build.flag("/std:c++11"); + } else { + build.flag("-std=c++11"); + } + build.cpp(true); build.compile("spirv-tools"); } From 95911d20d446784c010c058e56a87178110f148b Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 16:48:48 +0200 Subject: [PATCH 07/41] Placate clippy --- rustc_codegen_spirv/src/link.rs | 4 ++-- spirv-tools/src/opt.rs | 4 ++-- spirv-tools/src/opt/options.rs | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 04c1ef97fb..615693c7c6 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -154,7 +154,7 @@ fn do_spirv_opt(sess: &Session, spv_binary: &[u32], filename: &Path) { let result = optimizer.optimize( spv_binary, &mut |data: &[u32]| { - write_result = Some(std::fs::write(filename, crate::slice_u32_to_u8(&data))); + write_result = Some(std::fs::write(filename, crate::slice_u32_to_u8(data))); }, Some(&opts), ); @@ -167,7 +167,7 @@ fn do_spirv_opt(sess: &Session, spv_binary: &[u32], filename: &Path) { Ok(_) => { write_result.unwrap().unwrap(); } - _ => { + Err(_) => { let mut err = sess.struct_warn("invalid arguments supplied to spirv-opt, leaving as unoptimized"); err.note(&format!("module {:?}", filename)); diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index d1209a6d45..bafc404746 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -49,7 +49,7 @@ impl Optimizer { extern "C" fn callback(data: *const u32, len: usize, ctx: *mut std::ffi::c_void) { unsafe { let optimized_binary = std::slice::from_raw_parts(data, len); - let ctx: &mut Ctx<'_> = std::mem::transmute(ctx); + let ctx: &mut Ctx<'_> = &mut *(ctx as *mut Ctx); ctx.cb.optimized(optimized_binary); } @@ -92,7 +92,7 @@ impl Optimizer { options, )?; - buffer.ok_or_else(|| RunResult::OptimizerFailed) + buffer.ok_or(RunResult::OptimizerFailed) } /// Register a single pass with the the optimizer. diff --git a/spirv-tools/src/opt/options.rs b/spirv-tools/src/opt/options.rs index ed964d049e..1abfafe63b 100644 --- a/spirv-tools/src/opt/options.rs +++ b/spirv-tools/src/opt/options.rs @@ -33,6 +33,12 @@ impl Options { } } +impl Default for Options { + fn default() -> Self { + Self::new() + } +} + impl Drop for Options { #[inline] fn drop(&mut self) { From 2997eaa71a06eb9154517b2164a6fdb77b06c178 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 21:39:33 +0200 Subject: [PATCH 08/41] Add validation, replacing spirv-val with the spirv-tools crate --- rustc_codegen_spirv/Cargo.toml | 2 +- rustc_codegen_spirv/src/link.rs | 186 +++++++++++++------------------- spirv-tools-sys/Cargo.toml | 4 +- spirv-tools-sys/build.rs | 13 ++- spirv-tools-sys/src/c/opt.cpp | 27 ++--- spirv-tools-sys/src/c/val.cpp | 26 +++++ spirv-tools-sys/src/lib.rs | 3 + spirv-tools-sys/src/opt.rs | 29 +++-- spirv-tools-sys/src/shared.rs | 12 +++ spirv-tools-sys/src/val.rs | 124 +++++++++++++++++++++ spirv-tools/Cargo.toml | 1 + spirv-tools/src/lib.rs | 2 + spirv-tools/src/opt.rs | 18 ++-- spirv-tools/src/opt/options.rs | 5 +- spirv-tools/src/val.rs | 164 ++++++++++++++++++++++++++++ 15 files changed, 455 insertions(+), 161 deletions(-) create mode 100644 spirv-tools-sys/src/c/val.cpp create mode 100644 spirv-tools-sys/src/val.rs create mode 100644 spirv-tools/src/val.rs diff --git a/rustc_codegen_spirv/Cargo.toml b/rustc_codegen_spirv/Cargo.toml index 2d2ea755ec..d6304f5ae7 100644 --- a/rustc_codegen_spirv/Cargo.toml +++ b/rustc_codegen_spirv/Cargo.toml @@ -26,4 +26,4 @@ tempfile = "3.1" [dependencies.spirv-tools] version = "0.1.0" path = "../spirv-tools" -features = ["opt"] +features = ["opt", "val"] diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 615693c7c6..9972feb7a3 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -1,27 +1,31 @@ use crate::{linker, SpirvCodegenBackend, SpirvModuleBuffer, SpirvThinBuffer}; -use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; -use rustc_codegen_ssa::back::write::CodegenContext; -use rustc_codegen_ssa::CodegenResults; -use rustc_data_structures::owning_ref::OwningRef; -use rustc_data_structures::rustc_erase_owner; -use rustc_data_structures::sync::MetadataRef; -use rustc_errors::{DiagnosticBuilder, FatalError}; -use rustc_middle::bug; -use rustc_middle::dep_graph::WorkProduct; -use rustc_middle::middle::cstore::NativeLib; -use rustc_middle::middle::dependency_format::Linkage; -use rustc_session::config::{CrateType, Lto, OutputFilenames, OutputType}; -use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; -use rustc_session::utils::NativeLibKind; -use rustc_session::Session; -use std::collections::HashSet; -use std::env; -use std::ffi::{CString, OsStr}; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::{Path, PathBuf}; -use std::process::Command; -use std::sync::Arc; +use rustc_codegen_ssa::{ + back::{ + lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}, + write::CodegenContext, + }, + CodegenResults, +}; +use rustc_data_structures::{owning_ref::OwningRef, rustc_erase_owner, sync::MetadataRef}; +use rustc_errors::FatalError; +use rustc_middle::{ + bug, dep_graph::WorkProduct, middle::cstore::NativeLib, middle::dependency_format::Linkage, +}; +use rustc_session::{ + config::{CrateType, Lto, OutputFilenames, OutputType}, + output::{check_file_is_writeable, invalid_output_for_target, out_filename}, + utils::NativeLibKind, + Session, +}; +use std::{ + collections::HashSet, + env, + ffi::{CString, OsStr}, + fs::File, + io::{Read, Write}, + path::{Path, PathBuf}, + sync::Arc, +}; use tar::{Archive, Builder, Header}; pub fn link<'a>( @@ -124,19 +128,33 @@ fn link_exe( codegen_results, ); - let spv_binary = do_link(sess, &objects, &rlibs, out_filename, legalize); + let spv_binary = do_link(sess, &objects, &rlibs, legalize); - if env::var("SPIRV_OPT").is_ok() { + let spv_binary = if env::var("SPIRV_OPT").is_ok() { let _timer = sess.timer("link_spirv_opt"); - do_spirv_opt(sess, &spv_binary, out_filename); - } + do_spirv_opt(sess, spv_binary, out_filename) + } else { + spv_binary + }; if env::var("NO_SPIRV_VAL").is_err() { - do_spirv_val(sess, out_filename); + do_spirv_val(sess, &spv_binary, out_filename); + } + + { + let save_modules_timer = sess.timer("link_save_modules"); + if let Err(e) = std::fs::write(out_filename, crate::slice_u32_to_u8(&spv_binary)) { + let mut err = sess.struct_err("failed to serialize spirv-binary to disk"); + err.note(&format!("module {:?}", out_filename)); + err.note(&format!("I/O error: {:#}", e)); + err.emit(); + } + + drop(save_modules_timer); } } -fn do_spirv_opt(sess: &Session, spv_binary: &[u32], filename: &Path) { +fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec { use spirv_tools::{opt, shared}; // This is the same default target environment that spirv-opt uses @@ -147,14 +165,17 @@ fn do_spirv_opt(sess: &Session, spv_binary: &[u32], filename: &Path) { .register_pass(opt::Passes::EliminateDeadConstant) .register_pass(opt::Passes::StripDebugInfo); - let mut write_result = None; let mut opts = opt::Options::new(); + + // We run the validator separately opts.run_validator(false); + let mut optimized_binary = None; + let result = optimizer.optimize( - spv_binary, + &spv_binary, &mut |data: &[u32]| { - write_result = Some(std::fs::write(filename, crate::slice_u32_to_u8(data))); + optimized_binary = Some(data.to_vec()); }, Some(&opts), ); @@ -163,75 +184,29 @@ fn do_spirv_opt(sess: &Session, spv_binary: &[u32], filename: &Path) { Err(opt::RunResult::OptimizerFailed) => { let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); err.note(&format!("module {:?}", filename)); + spv_binary } - Ok(_) => { - write_result.unwrap().unwrap(); - } + Ok(_) => optimized_binary.unwrap(), Err(_) => { let mut err = sess.struct_warn("invalid arguments supplied to spirv-opt, leaving as unoptimized"); err.note(&format!("module {:?}", filename)); + spv_binary } } } -fn do_spirv_val(sess: &Session, filename: &Path) { - output_spirv_tool( - sess, - "spirv-val", - |cmd| cmd.arg(&filename), - |status| { - let mut err = sess.struct_err(&format!("spirv-val failed with {}", status)); - err.note(&format!("module {:?}", filename)); - err - }, - ); -} - -/// Runs a given SPIR-V `tool`, configured with `builder`, erroring if not found -/// or returns a non-zero exit code. All errors will be emitted using the -/// diagnostics builder provided by `diagnostics.` -fn output_spirv_tool<'a, F, D>( - sess: &Session, - tool: &str, - builder: F, - diagnostics: D, -) -> Option -where - F: FnOnce(&mut Command) -> &mut Command, - D: FnOnce(std::process::ExitStatus) -> DiagnosticBuilder<'a>, -{ - let mut cmd = Command::new(tool); - (builder)(&mut cmd); - - let output = match cmd.output() { - Ok(output) => output, - Err(_) => { - let mut err = - sess.struct_err(&format!("Couldn't find `{}` SPIR-V tool in PATH.", tool)); - err.note( - "Please ensure that you have `spirv-tools` installed on \ - your system and available in your PATH.", - ); - err.emit(); - return None; - } - }; - - if output.status.success() { - Some(output) - } else { - let mut diagnostics = (diagnostics)(output.status); +fn do_spirv_val(sess: &Session, spv_binary: &[u32], filename: &Path) { + use spirv_tools::{shared, val}; - if !output.stdout.is_empty() { - diagnostics.note(&String::from_utf8(output.stdout).unwrap()); - } - if !output.stderr.is_empty() { - diagnostics.note(&String::from_utf8(output.stderr).unwrap()); - } + // This is the same default target environment that spirv-val uses + let validator = val::Validator::new(shared::TargetEnv::Universal_1_5); + let opts = val::ValidatorOptions::default(); - diagnostics.emit(); - None + if validator.validate(spv_binary, &opts).is_err() { + let mut err = sess.struct_err("error occurred during validation"); + err.note(&format!("module {:?}", filename)); + err.emit(); } } @@ -385,13 +360,13 @@ pub fn read_metadata(rlib: &Path) -> Result { /// This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's /// shenanigans to collect all the object files we need to link. -fn do_link( - sess: &Session, - objects: &[PathBuf], - rlibs: &[PathBuf], - out_filename: &Path, - legalize: bool, -) -> Vec { +fn do_link(sess: &Session, objects: &[PathBuf], rlibs: &[PathBuf], legalize: bool) -> Vec { + fn load(bytes: &[u8]) -> rspirv::dr::Module { + let mut loader = rspirv::dr::Loader::new(); + rspirv::binary::parse_bytes(&bytes, &mut loader).unwrap(); + loader.module() + } + let load_modules_timer = sess.timer("link_load_modules"); let mut modules = Vec::new(); // `objects` are the plain obj files we need to link - usually produced by the final crate. @@ -438,9 +413,9 @@ fn do_link( mem2reg: legalize, structurize: env::var("NO_STRUCTURIZE").is_err(), }; + let link_result = linker::link(Some(sess), &mut module_refs, &options); - let save_modules_timer = sess.timer("link_save_modules"); let assembled = match link_result { Ok(v) => v, Err(err) => { @@ -463,20 +438,7 @@ fn do_link( // And finally write out the linked binary. use rspirv::binary::Assemble; - let spv_binary = assembled.assemble(); - File::create(out_filename) - .unwrap() - .write_all(crate::slice_u32_to_u8(&spv_binary)) - .unwrap(); - drop(save_modules_timer); - - fn load(bytes: &[u8]) -> rspirv::dr::Module { - let mut loader = rspirv::dr::Loader::new(); - rspirv::binary::parse_bytes(&bytes, &mut loader).unwrap(); - loader.module() - } - - spv_binary + assembled.assemble() } /// As of right now, this is essentially a no-op, just plumbing through all the files. diff --git a/spirv-tools-sys/Cargo.toml b/spirv-tools-sys/Cargo.toml index 28f1f427a3..b4714f8fbf 100644 --- a/spirv-tools-sys/Cargo.toml +++ b/spirv-tools-sys/Cargo.toml @@ -6,7 +6,9 @@ edition = "2018" build = "build.rs" [features] -opt = [] +opt = ["val"] +val = ["tools"] +tools = [] [build-dependencies] cc = { version = "1.0", features = ["parallel"] } diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index a51a1e97b1..2736c50ed4 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -170,6 +170,8 @@ fn opt(build: &mut Build) { } fn val(build: &mut Build) { + build.file("src/c/val.cpp"); + add_sources( build, "spirv-tools/source/val", @@ -230,7 +232,11 @@ fn main() { ); shared(&mut build); - val(&mut build); + + // Some opt code requires val as well + if cfg!(any(feature = "opt", feature = "val")) { + val(&mut build); + } if cfg!(feature = "opt") { opt(&mut build); @@ -239,7 +245,10 @@ fn main() { if build.get_compiler().is_like_msvc() { build.flag("/std:c++11"); } else { - build.flag("-std=c++11"); + build + .flag("-std=c++11") + .flag("-fno-exceptions") + .flag("-fno-rtti"); } build.cpp(true); diff --git a/spirv-tools-sys/src/c/opt.cpp b/spirv-tools-sys/src/c/opt.cpp index 0bf3ce5113..fab1d32b23 100644 --- a/spirv-tools-sys/src/c/opt.cpp +++ b/spirv-tools-sys/src/c/opt.cpp @@ -77,24 +77,17 @@ enum RunResult { typedef void (*optimized_callback)(const uint32_t* data, size_t len, void* ctx); extern "C" { - SPIRV_TOOLS_EXPORT Optimus* create_optimizer(spv_target_env target_env) { - spvtools::Optimizer* optimizer = new spvtools::Optimizer(target_env); - - // auto print_msg_to_stderr = [](spv_message_level_t, const char*, - // const spv_position_t&, const char* m) { - // fprintf(stderr, "error: %s\n", m); - // }; - - //optimizer->SetMessageConsumer(print_msg_to_stderr); + SPIRV_TOOLS_EXPORT Optimus* optimizer_create(spv_target_env target_env) { + auto* optimizer = new spvtools::Optimizer(target_env); return (Optimus*)optimizer; } - SPIRV_TOOLS_EXPORT void destroy_optimizer(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_destroy(Optimus* optimizer) { delete (spvtools::Optimizer*)optimizer; } - SPIRV_TOOLS_EXPORT RunResult run_optimizer( + SPIRV_TOOLS_EXPORT RunResult optimizer_run( const Optimus* optimizer, const uint32_t* input_ptr, size_t input_size, @@ -129,7 +122,7 @@ extern "C" { return RunResult::OptimizerSucceeded; } - SPIRV_TOOLS_EXPORT void register_pass(Optimus* optimizer, Passes pass) { + SPIRV_TOOLS_EXPORT void optimizer_register_pass(Optimus* optimizer, Passes pass) { #define PASTEB(a, b) a ## b #define PASTEA(a, b) PASTEB(a, b) #define PASS(name) \ @@ -202,23 +195,23 @@ extern "C" { } } - SPIRV_TOOLS_EXPORT void register_performance_passes(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_register_performance_passes(Optimus* optimizer) { ((spvtools::Optimizer*)optimizer)->RegisterPerformancePasses(); } - SPIRV_TOOLS_EXPORT void register_size_passes(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_register_size_passes(Optimus* optimizer) { ((spvtools::Optimizer*)optimizer)->RegisterSizePasses(); } - SPIRV_TOOLS_EXPORT void register_vulkan_to_webgpu_passes(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_register_vulkan_to_webgpu_passes(Optimus* optimizer) { ((spvtools::Optimizer*)optimizer)->RegisterVulkanToWebGPUPasses(); } - SPIRV_TOOLS_EXPORT void register_webgpu_to_vulkan_passes(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_register_webgpu_to_vulkan_passes(Optimus* optimizer) { ((spvtools::Optimizer*)optimizer)->RegisterWebGPUToVulkanPasses(); } - SPIRV_TOOLS_EXPORT void register_legalization_passes(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_register_legalization_passes(Optimus* optimizer) { ((spvtools::Optimizer*)optimizer)->RegisterLegalizationPasses(); } } diff --git a/spirv-tools-sys/src/c/val.cpp b/spirv-tools-sys/src/c/val.cpp new file mode 100644 index 0000000000..6bbf82ae56 --- /dev/null +++ b/spirv-tools-sys/src/c/val.cpp @@ -0,0 +1,26 @@ +#include "spirv-tools/libspirv.hpp" + +struct Tool; + +extern "C" { + SPIRV_TOOLS_EXPORT Tool* tool_create(spv_target_env target_env) { + auto* tools = new spvtools::SpirvTools(target_env); + + return (Tool*)tools; + } + + SPIRV_TOOLS_EXPORT void tool_destroy(Tool* tool) { + delete (spvtools::SpirvTools*)tool; + } + + SPIRV_TOOLS_EXPORT bool validate( + const Tool* tool, + const uint32_t* binary, + size_t size, + spv_validator_options options + ) { + auto* tools = (spvtools::SpirvTools*)tool; + + return tools->Validate(binary, size, options); + } +} diff --git a/spirv-tools-sys/src/lib.rs b/spirv-tools-sys/src/lib.rs index 6117315177..e93ca7ae79 100644 --- a/spirv-tools-sys/src/lib.rs +++ b/spirv-tools-sys/src/lib.rs @@ -2,3 +2,6 @@ pub mod shared; #[cfg(feature = "opt")] pub mod opt; + +#[cfg(feature = "val")] +pub mod val; diff --git a/spirv-tools-sys/src/opt.rs b/spirv-tools-sys/src/opt.rs index d1f7ce6847..5e71609ddd 100644 --- a/spirv-tools-sys/src/opt.rs +++ b/spirv-tools-sys/src/opt.rs @@ -8,11 +8,6 @@ pub struct OptimizerOptions { _unused: [u8; 0], } -#[repr(C)] -pub struct ValidatorOptions { - _unused: [u8; 0], -} - #[derive(Copy, Clone, Debug)] #[repr(C)] pub enum Passes { @@ -517,10 +512,10 @@ pub enum RunResult { } extern "C" { - pub fn create_optimizer(env: crate::shared::TargetEnv) -> *mut Optimizer; - pub fn destroy_optimizer(opt: *mut Optimizer); + pub fn optimizer_create(env: crate::shared::TargetEnv) -> *mut Optimizer; + pub fn optimizer_destroy(opt: *mut Optimizer); - pub fn run_optimizer( + pub fn optimizer_run( opt: *const Optimizer, input_ptr: *const u32, input_size: usize, @@ -533,11 +528,11 @@ extern "C" { /// options object. The object remains valid until it is passed into /// |spvOptimizerOptionsDestroy|. #[link_name = "spvOptimizerOptionsCreate"] - pub fn create_optimizer_options() -> *mut OptimizerOptions; + pub fn optimizer_options_create() -> *mut OptimizerOptions; /// Destroys the given optimizer options object. #[link_name = "spvOptimizerOptionsDestroy"] - pub fn destroy_optimizer_options(options: *mut OptimizerOptions); + pub fn optimizer_options_destroy(options: *mut OptimizerOptions); /// Records whether or not the optimizer should run the validator before /// optimizing. If |val| is true, the validator will be run. @@ -549,7 +544,7 @@ extern "C" { #[link_name = "spvOptimizerOptionsSetValidatorOptions"] pub fn optimizer_options_set_validator_options( options: *mut OptimizerOptions, - validator_opts: *mut ValidatorOptions, + validator_opts: *mut crate::val::ValidatorOptions, ); /// Records the maximum possible value for the id bound. @@ -568,27 +563,27 @@ extern "C" { preserve: bool, ); - pub fn register_pass(opt: *mut Optimizer, which: Passes); + pub fn optimizer_register_pass(opt: *mut Optimizer, which: Passes); /// Registers passes that attempt to improve performance of generated code. /// This sequence of passes is subject to constant review and will change /// from time to time. - pub fn register_performance_passes(opt: *mut Optimizer); + pub fn optimizer_register_performance_passes(opt: *mut Optimizer); /// Registers passes that attempt to improve the size of generated code. /// This sequence of passes is subject to constant review and will change /// from time to time. - pub fn register_size_passes(opt: *mut Optimizer); + pub fn optimizer_register_size_passes(opt: *mut Optimizer); /// Registers passes that have been prescribed for converting from Vulkan to /// WebGPU. This sequence of passes is subject to constant review and will /// change from time to time. - pub fn register_vulkan_to_webgpu_passes(opt: *mut Optimizer); + pub fn optimizer_register_vulkan_to_webgpu_passes(opt: *mut Optimizer); /// Registers passes that have been prescribed for converting from WebGPU to /// Vulkan. This sequence of passes is subject to constant review and will /// change from time to time. - pub fn register_webgpu_to_vulkan_passes(opt: *mut Optimizer); + pub fn optimizer_register_webgpu_to_vulkan_passes(opt: *mut Optimizer); /// Registers passes that attempt to legalize the generated code. /// @@ -598,7 +593,7 @@ extern "C" { /// /// This sequence of passes is subject to constant review and will change /// from time to time. - pub fn register_legalization_passes(opt: *mut Optimizer); + pub fn optimizer_register_legalization_passes(opt: *mut Optimizer); // Some passes take arguments, so we create those separately on a // case-by-case basis diff --git a/spirv-tools-sys/src/shared.rs b/spirv-tools-sys/src/shared.rs index c9099d8d91..00f39380fb 100644 --- a/spirv-tools-sys/src/shared.rs +++ b/spirv-tools-sys/src/shared.rs @@ -64,3 +64,15 @@ pub enum TargetEnv { /// Vulkan 1.2 latest revision. Vulkan_1_2, } + +#[cfg(feature = "tools")] +#[repr(C)] +pub struct Tool { + _unused: [u8; 0], +} + +#[cfg(feature = "tools")] +extern "C" { + pub fn tool_create(env: TargetEnv) -> *mut Tool; + pub fn tool_destroy(opt: *mut Tool); +} diff --git a/spirv-tools-sys/src/val.rs b/spirv-tools-sys/src/val.rs new file mode 100644 index 0000000000..d5b3e75268 --- /dev/null +++ b/spirv-tools-sys/src/val.rs @@ -0,0 +1,124 @@ +#[repr(C)] +pub struct ValidatorOptions { + _unused: [u8; 0], +} + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub enum ValidatorLimits { + MaxStructMembers, + MaxStructDepth, + MaxLocalVariables, + MaxGlobalVariables, + MaxSwitchBranches, + MaxFunctionArgs, + MaxControlFlowNestingDepth, + MaxAccessChainIndexes, + MaxIdBound, +} + +extern "C" { + pub fn validate( + tool: *const crate::shared::Tool, + binary: *const u32, + size: usize, + options: *const ValidatorOptions, + ) -> bool; + + /// Creates a Validator options object with default options. Returns a valid + /// options object. The object remains valid until it is passed into + /// spvValidatorOptionsDestroy. + #[link_name = "spvValidatorOptionsCreate"] + pub fn validator_options_create() -> *mut ValidatorOptions; + + /// Destroys the given Validator options object. + #[link_name = "spvValidatorOptionsDestroy"] + pub fn validator_options_destroy(opts: *mut ValidatorOptions); + + /// Records the maximum Universal Limit that is considered valid in the given + /// Validator options object. argument must be a valid options object. + #[link_name = "spvValidatorOptionsSetUniversalLimit"] + pub fn validator_options_set_limit( + opts: *mut ValidatorOptions, + limit_type: ValidatorLimits, + limit: u32, + ); + + /// Record whether or not the validator should relax the rules on types for + /// stores to structs. When relaxed, it will allow a type mismatch as long as + /// the types are structs with the same layout. Two structs have the same layout + /// if + /// + /// 1) the members of the structs are either the same type or are structs with + /// same layout, and + /// + /// 2) the decorations that affect the memory layout are identical for both + /// types. Other decorations are not relevant. + #[link_name = "spvValidatorOptionsSetRelaxStoreStruct"] + pub fn validator_options_set_relax_store_struct(opts: *mut ValidatorOptions, toggle: bool); + + /// Records whether or not the validator should relax the rules on pointer usage + /// in logical addressing mode. + /// + /// When relaxed, it will allow the following usage cases of pointers: + /// 1) OpVariable allocating an object whose type is a pointer type + /// 2) OpReturnValue returning a pointer value + #[link_name = "spvValidatorOptionsSetRelaxLogicalPointer"] + pub fn validator_options_set_relax_logical_pointer(opts: *mut ValidatorOptions, toggle: bool); + + /// Records whether or not the validator should relax the rules because it is + /// expected that the optimizations will make the code legal. + /// + /// When relaxed, it will allow the following: + /// 1) It will allow relaxed logical pointers. Setting this option will also + /// set that option. + /// 2) Pointers that are pass as parameters to function calls do not have to + /// match the storage class of the formal parameter. + /// 3) Pointers that are actaul parameters on function calls do not have to point + /// to the same type pointed as the formal parameter. The types just need to + /// logically match. + #[link_name = "spvValidatorOptionsSetBeforeHlslLegalization"] + pub fn validator_options_set_before_legalization(opts: *mut ValidatorOptions, toggle: bool); + + /// Records whether the validator should use "relaxed" block layout rules. + /// Relaxed layout rules are described by Vulkan extension + /// VK_KHR_relaxed_block_layout, and they affect uniform blocks, storage blocks, + /// and push constants. + /// + /// This is enabled by default when targeting Vulkan 1.1 or later. + /// Relaxed layout is more permissive than the default rules in Vulkan 1.0. + #[link_name = "spvValidatorOptionsSetRelaxBlockLayout"] + pub fn validator_options_set_relax_block_layout(opts: *mut ValidatorOptions, toggle: bool); + + /// Records whether the validator should use standard block layout rules for + /// uniform blocks. + #[link_name = "spvValidatorOptionsSetUniformBufferStandardLayout"] + pub fn validator_options_set_uniform_buffer_standard_layout( + opts: *mut ValidatorOptions, + toggle: bool, + ); + + /// Records whether the validator should use "scalar" block layout rules. + /// Scalar layout rules are more permissive than relaxed block layout. + /// + /// See Vulkan extnesion VK_EXT_scalar_block_layout. The scalar alignment is + /// defined as follows: + /// - scalar alignment of a scalar is the scalar size + /// - scalar alignment of a vector is the scalar alignment of its component + /// - scalar alignment of a matrix is the scalar alignment of its component + /// - scalar alignment of an array is the scalar alignment of its element + /// - scalar alignment of a struct is the max scalar alignment among its + /// members + /// + /// For a struct in Uniform, StorageClass, or PushConstant: + /// - a member Offset must be a multiple of the member's scalar alignment + /// - ArrayStride or MatrixStride must be a multiple of the array or matrix + /// scalar alignment + #[link_name = "spvValidatorOptionsSetScalarBlockLayout"] + pub fn validator_options_set_scalar_block_layout(opts: *mut ValidatorOptions, toggle: bool); + + /// Records whether or not the validator should skip validating standard + /// uniform/storage block layout. + #[link_name = "spvValidatorOptionsSetSkipBlockLayout"] + pub fn validator_options_set_skip_block_layout(opts: *mut ValidatorOptions, toggle: bool); +} diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index d820d107f5..23706dbf5f 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [features] opt = ["spirv-tools-sys/opt"] +val = ["spirv-tools-sys/val"] [dependencies] spirv-tools-sys = { path = "../spirv-tools-sys" } diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index 9da7979f7e..a3fdb4c463 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -1,4 +1,6 @@ #[cfg(feature = "opt")] pub mod opt; +#[cfg(feature = "val")] +pub mod val; pub use spirv_tools_sys::shared; diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index bafc404746..443f93fe87 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -26,7 +26,7 @@ impl Optimizer { #[inline] pub fn new(target: spirv_tools_sys::shared::TargetEnv) -> Self { Self { - inner: unsafe { opt::create_optimizer(target) }, + inner: unsafe { opt::optimizer_create(target) }, } } @@ -60,7 +60,7 @@ impl Optimizer { None => std::ptr::null(), }; - let result = opt::run_optimizer( + let result = opt::optimizer_run( self.inner, input.as_ptr(), input.len(), @@ -98,7 +98,7 @@ impl Optimizer { /// Register a single pass with the the optimizer. #[inline] pub fn register_pass(&mut self, pass: Passes) -> &mut Self { - unsafe { opt::register_pass(self.inner, pass) } + unsafe { opt::optimizer_register_pass(self.inner, pass) } self } @@ -107,7 +107,7 @@ impl Optimizer { /// from time to time. #[inline] pub fn register_performance_passes(&mut self) -> &mut Self { - unsafe { opt::register_performance_passes(self.inner) } + unsafe { opt::optimizer_register_performance_passes(self.inner) } self } @@ -116,7 +116,7 @@ impl Optimizer { /// from time to time. #[inline] pub fn register_size_passes(&mut self) -> &mut Self { - unsafe { opt::register_size_passes(self.inner) } + unsafe { opt::optimizer_register_size_passes(self.inner) } self } @@ -125,7 +125,7 @@ impl Optimizer { /// change from time to time. #[inline] pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self { - unsafe { opt::register_vulkan_to_webgpu_passes(self.inner) } + unsafe { opt::optimizer_register_vulkan_to_webgpu_passes(self.inner) } self } @@ -134,7 +134,7 @@ impl Optimizer { /// change from time to time. #[inline] pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self { - unsafe { opt::register_webgpu_to_vulkan_passes(self.inner) } + unsafe { opt::optimizer_register_webgpu_to_vulkan_passes(self.inner) } self } @@ -148,7 +148,7 @@ impl Optimizer { /// from time to time. #[inline] pub fn register_legalization_passes(&mut self) -> &mut Self { - unsafe { opt::register_legalization_passes(self.inner) } + unsafe { opt::optimizer_register_legalization_passes(self.inner) } self } } @@ -156,6 +156,6 @@ impl Optimizer { impl Drop for Optimizer { #[inline] fn drop(&mut self) { - unsafe { opt::destroy_optimizer(self.inner) } + unsafe { opt::optimizer_destroy(self.inner) } } } diff --git a/spirv-tools/src/opt/options.rs b/spirv-tools/src/opt/options.rs index 1abfafe63b..da9b0f2066 100644 --- a/spirv-tools/src/opt/options.rs +++ b/spirv-tools/src/opt/options.rs @@ -8,7 +8,7 @@ impl Options { #[inline] pub fn new() -> Self { Self { - inner: unsafe { opt::create_optimizer_options() }, + inner: unsafe { opt::optimizer_options_create() }, } } @@ -34,6 +34,7 @@ impl Options { } impl Default for Options { + #[inline] fn default() -> Self { Self::new() } @@ -42,6 +43,6 @@ impl Default for Options { impl Drop for Options { #[inline] fn drop(&mut self) { - unsafe { opt::destroy_optimizer_options(self.inner) } + unsafe { opt::optimizer_options_destroy(self.inner) } } } diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs new file mode 100644 index 0000000000..c14be29e42 --- /dev/null +++ b/spirv-tools/src/val.rs @@ -0,0 +1,164 @@ +use spirv_tools_sys::{shared, val}; + +pub struct ValidatorOptsBuilder { + /// Record whether or not the validator should relax the rules on types for + /// stores to structs. When relaxed, it will allow a type mismatch as long as + /// the types are structs with the same layout. Two structs have the same layout + /// if + /// + /// 1) the members of the structs are either the same type or are structs with + /// same layout, and + /// + /// 2) the decorations that affect the memory layout are identical for both + /// types. Other decorations are not relevant. + pub relax_store_struct: bool, + /// Records whether or not the validator should relax the rules on pointer usage + /// in logical addressing mode. + /// + /// When relaxed, it will allow the following usage cases of pointers: + /// 1) OpVariable allocating an object whose type is a pointer type + /// 2) OpReturnValue returning a pointer value + pub relax_logical_pointer: bool, + /// Records whether or not the validator should relax the rules because it is + /// expected that the optimizations will make the code legal. + /// + /// When relaxed, it will allow the following: + /// 1) It will allow relaxed logical pointers. Setting this option will also + /// set that option. + /// 2) Pointers that are pass as parameters to function calls do not have to + /// match the storage class of the formal parameter. + /// 3) Pointers that are actaul parameters on function calls do not have to point + /// to the same type pointed as the formal parameter. The types just need to + /// logically match. + pub before_legalization: bool, + /// Records whether the validator should use "relaxed" block layout rules. + /// Relaxed layout rules are described by Vulkan extension + /// VK_KHR_relaxed_block_layout, and they affect uniform blocks, storage blocks, + /// and push constants. + /// + /// This is enabled by default when targeting Vulkan 1.1 or later. + /// Relaxed layout is more permissive than the default rules in Vulkan 1.0. + pub relax_block_layout: bool, + /// Records whether the validator should use standard block layout rules for + /// uniform blocks. + pub uniform_buffer_standard_layout: bool, + /// Records whether the validator should use "scalar" block layout rules. + /// Scalar layout rules are more permissive than relaxed block layout. + /// + /// See Vulkan extnesion VK_EXT_scalar_block_layout. The scalar alignment is + /// defined as follows: + /// - scalar alignment of a scalar is the scalar size + /// - scalar alignment of a vector is the scalar alignment of its component + /// - scalar alignment of a matrix is the scalar alignment of its component + /// - scalar alignment of an array is the scalar alignment of its element + /// - scalar alignment of a struct is the max scalar alignment among its + /// members + /// + /// For a struct in Uniform, StorageClass, or PushConstant: + /// - a member Offset must be a multiple of the member's scalar alignment + /// - ArrayStride or MatrixStride must be a multiple of the array or matrix + /// scalar alignment + pub scalar_block_layout: bool, + /// Records whether or not the validator should skip validating standard + /// uniform/storage block layout. + pub skip_block_layout: bool, +} + +impl ValidatorOptsBuilder { + pub fn into_opts(self) -> ValidatorOptions { + self.into_opts_with_limits(std::iter::empty()) + } + + pub fn into_opts_with_limits( + self, + limits: impl Iterator, + ) -> ValidatorOptions { + unsafe { + let vopts = val::validator_options_create(); + + // AFAICT this is the only one that _may_ default to true, so + // we always set it + val::validator_options_set_relax_block_layout(vopts, self.relax_block_layout); + + if self.relax_store_struct { + val::validator_options_set_relax_store_struct(vopts, self.relax_store_struct); + } + + if self.relax_logical_pointer { + val::validator_options_set_relax_logical_pointer(vopts, self.relax_logical_pointer); + } + + if self.before_legalization { + val::validator_options_set_before_legalization(vopts, self.before_legalization); + } + + if self.uniform_buffer_standard_layout { + val::validator_options_set_uniform_buffer_standard_layout( + vopts, + self.uniform_buffer_standard_layout, + ); + } + + if self.scalar_block_layout { + val::validator_options_set_scalar_block_layout(vopts, self.scalar_block_layout); + } + + if self.skip_block_layout { + val::validator_options_set_skip_block_layout(vopts, self.skip_block_layout); + } + + for (limit, val) in limits { + val::validator_options_set_limit(vopts, limit, val); + } + + ValidatorOptions { inner: vopts } + } + } +} + +pub struct ValidatorOptions { + inner: *mut val::ValidatorOptions, +} + +impl Default for ValidatorOptions { + fn default() -> Self { + Self { + inner: unsafe { val::validator_options_create() }, + } + } +} + +impl Drop for ValidatorOptions { + fn drop(&mut self) { + unsafe { val::validator_options_destroy(self.inner) } + } +} + +pub struct Validator { + inner: *mut shared::Tool, +} + +impl Validator { + pub fn new(target_env: shared::TargetEnv) -> Self { + Self { + inner: unsafe { shared::tool_create(target_env) }, + } + } + + pub fn validate(&self, binary: &[u32], options: &ValidatorOptions) -> Result<(), ()> { + let ret = + unsafe { val::validate(self.inner, binary.as_ptr(), binary.len(), options.inner) }; + + if ret { + Ok(()) + } else { + Err(()) + } + } +} + +impl Drop for Validator { + fn drop(&mut self) { + unsafe { shared::tool_destroy(self.inner) } + } +} From f5cd86db71360f70dc9e306fb5cc75503e5a1fa3 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 23 Oct 2020 22:02:04 +0200 Subject: [PATCH 09/41] Fix MSVC warning --- spirv-tools-sys/build.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 2736c50ed4..931f128855 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -242,9 +242,7 @@ fn main() { opt(&mut build); } - if build.get_compiler().is_like_msvc() { - build.flag("/std:c++11"); - } else { + if !build.get_compiler().is_like_msvc() { build .flag("-std=c++11") .flag("-fno-exceptions") From cbe33b7cfce05df82664fe3cb35af0c1e6877f33 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sat, 24 Oct 2020 10:55:11 +0200 Subject: [PATCH 10/41] Use patched spirv-tools --- .gitmodules | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 91c3a41ba1..415c626312 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,5 @@ url = https://github.com/KhronosGroup/SPIRV-Headers.git [submodule "spirv-tools-sys/spirv-tools"] path = spirv-tools-sys/spirv-tools - url = https://github.com/KhronosGroup/SPIRV-Tools.git + url = https://github.com/EmbarkStudios/SPIRV-Tools.git + branch = patch-to-string From 527388c9816dcaa06aa70e7829f74412cb4f5ce9 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sat, 24 Oct 2020 10:55:43 +0200 Subject: [PATCH 11/41] Fixup metadata --- spirv-tools-sys/Cargo.toml | 3 ++- spirv-tools/Cargo.toml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/spirv-tools-sys/Cargo.toml b/spirv-tools-sys/Cargo.toml index b4714f8fbf..f85d35d8d3 100644 --- a/spirv-tools-sys/Cargo.toml +++ b/spirv-tools-sys/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "spirv-tools-sys" version = "0.1.0" -authors = ["Jake Shadle "] +authors = ["Embark "] edition = "2018" build = "build.rs" +license = "MIT OR Apache-2.0" [features] opt = ["val"] diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index 23706dbf5f..ae646e7221 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -3,6 +3,7 @@ name = "spirv-tools" version = "0.1.0" authors = ["Embark "] edition = "2018" +license = "MIT OR Apache-2.0" [features] opt = ["spirv-tools-sys/opt"] From 8635e68c1bc40049bb915282bb3984cfd9e70444 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sat, 24 Oct 2020 10:56:11 +0200 Subject: [PATCH 12/41] Add same compiler flags as "official" build scripts --- spirv-tools-sys/build.rs | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 931f128855..8ec51461c4 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -242,11 +242,45 @@ fn main() { opt(&mut build); } - if !build.get_compiler().is_like_msvc() { + let compiler = build.get_compiler(); + + if compiler.is_like_gnu() { + build + .flag("-Wall") + .flag("-Wextra") + .flag("-Wnon-virtual-dtor") + .flag("-Wno-missing-field-initializers") + .flag("-Werror") + .flag("-std=c++11") + .flag("-fno-exceptions") + .flag("-fno-rtti") + .flag("-Wno-long-long") + .flag("-Wshadow") + .flag("-Wundef") + .flag("-Wconversion") + .flag("-Wno-sign-conversion") + .flag("-std=gnu++11") + .flag("-Wno-error=switch"); + } else if compiler.is_like_clang() { build + .flag("-Wextra-semi") + .flag("-Wall") + .flag("-Wextra") + .flag("-Wnon-virtual-dtor") + .flag("-Wno-missing-field-initializers") + .flag("-Wno-self-assign") + .flag("-Werror") .flag("-std=c++11") .flag("-fno-exceptions") - .flag("-fno-rtti"); + .flag("-fno-rtti") + .flag("-Wno-long-long") + .flag("-Wshadow") + .flag("-Wundef") + .flag("-Wconversion") + .flag("-Wno-sign-conversion") + .flag("-ftemplate-depth=1024") + .flag("-std=gnu++11") + .flag("-Wno-error=switch"); } build.cpp(true); From 69a20e26ebe199633356de9b2869d4cb68303e05 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sun, 25 Oct 2020 12:47:59 +0100 Subject: [PATCH 13/41] Update spirv-tools and generated files --- spirv-tools-sys/generated/build-version.inc | 2 +- .../generated/enum_string_mapping.inc | 12 +++++++++-- spirv-tools-sys/generated/extension_enum.inc | 2 ++ spirv-tools-sys/generated/generators.inc | 4 +++- .../generated/operand.kinds-unified1.inc | 20 ++++++++++++++++++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/spirv-tools-sys/generated/build-version.inc b/spirv-tools-sys/generated/build-version.inc index 594b63c26f..c8612120af 100644 --- a/spirv-tools-sys/generated/build-version.inc +++ b/spirv-tools-sys/generated/build-version.inc @@ -1 +1 @@ -"v2020.6", "SPIRV-Tools v2020.6 v2020.5-3-ge12087d6" +"v2020.6", "SPIRV-Tools v2020.6 v2020.5-81-g6c992630" diff --git a/spirv-tools-sys/generated/enum_string_mapping.inc b/spirv-tools-sys/generated/enum_string_mapping.inc index 3e672245ec..13d0f18862 100644 --- a/spirv-tools-sys/generated/enum_string_mapping.inc +++ b/spirv-tools-sys/generated/enum_string_mapping.inc @@ -34,6 +34,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_EXT_physical_storage_buffer"; case Extension::kSPV_EXT_shader_atomic_float_add: return "SPV_EXT_shader_atomic_float_add"; + case Extension::kSPV_EXT_shader_image_int64: + return "SPV_EXT_shader_image_int64"; case Extension::kSPV_EXT_shader_stencil_export: return "SPV_EXT_shader_stencil_export"; case Extension::kSPV_EXT_shader_viewport_index_layer: @@ -74,6 +76,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_KHR_device_group"; case Extension::kSPV_KHR_float_controls: return "SPV_KHR_float_controls"; + case Extension::kSPV_KHR_fragment_shading_rate: + return "SPV_KHR_fragment_shading_rate"; case Extension::kSPV_KHR_multiview: return "SPV_KHR_multiview"; case Extension::kSPV_KHR_no_integer_wrap_decoration: @@ -143,8 +147,8 @@ const char* ExtensionToString(Extension extension) { bool GetExtensionFromString(const char* str, Extension* extension) { - static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_kernel_attributes", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" }; - static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique }; + static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_kernel_attributes", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_fragment_shading_rate", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" }; + static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique }; const auto b = std::begin(known_ext_strs); const auto e = std::end(known_ext_strs); const auto found = std::equal_range( @@ -298,6 +302,8 @@ const char* CapabilityToString(SpvCapability capability) { return "ShaderLayer"; case SpvCapabilityShaderViewportIndex: return "ShaderViewportIndex"; + case SpvCapabilityFragmentShadingRateKHR: + return "FragmentShadingRateKHR"; case SpvCapabilitySubgroupBallotKHR: return "SubgroupBallotKHR"; case SpvCapabilityDrawParameters: @@ -354,6 +360,8 @@ const char* CapabilityToString(SpvCapability capability) { return "StencilExportEXT"; case SpvCapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case SpvCapabilityInt64ImageEXT: + return "Int64ImageEXT"; case SpvCapabilityShaderClockKHR: return "ShaderClockKHR"; case SpvCapabilitySampleMaskOverrideCoverageNV: diff --git a/spirv-tools-sys/generated/extension_enum.inc b/spirv-tools-sys/generated/extension_enum.inc index a5c14eedb0..0dbb6f84ab 100644 --- a/spirv-tools-sys/generated/extension_enum.inc +++ b/spirv-tools-sys/generated/extension_enum.inc @@ -15,6 +15,7 @@ kSPV_EXT_fragment_invocation_density, kSPV_EXT_fragment_shader_interlock, kSPV_EXT_physical_storage_buffer, kSPV_EXT_shader_atomic_float_add, +kSPV_EXT_shader_image_int64, kSPV_EXT_shader_stencil_export, kSPV_EXT_shader_viewport_index_layer, kSPV_GOOGLE_decorate_string, @@ -35,6 +36,7 @@ kSPV_KHR_16bit_storage, kSPV_KHR_8bit_storage, kSPV_KHR_device_group, kSPV_KHR_float_controls, +kSPV_KHR_fragment_shading_rate, kSPV_KHR_multiview, kSPV_KHR_no_integer_wrap_decoration, kSPV_KHR_non_semantic_info, diff --git a/spirv-tools-sys/generated/generators.inc b/spirv-tools-sys/generated/generators.inc index b0a58846be..212370fd47 100644 --- a/spirv-tools-sys/generated/generators.inc +++ b/spirv-tools-sys/generated/generators.inc @@ -22,4 +22,6 @@ {21, "Google", "Clspv", "Google Clspv"}, {22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"}, {23, "Google", "Tint Compiler", "Google Tint Compiler"}, -{24, "Google", "ANGLE Shader Compiler", "Google ANGLE Shader Compiler"}, \ No newline at end of file +{24, "Google", "ANGLE Shader Compiler", "Google ANGLE Shader Compiler"}, +{25, "Netease Games", "Messiah Shader Compiler", "Netease Games Messiah Shader Compiler"}, +{26, "Xenia", "Xenia Emulator Microcode Translator", "Xenia Xenia Emulator Microcode Translator"}, \ No newline at end of file diff --git a/spirv-tools-sys/generated/operand.kinds-unified1.inc b/spirv-tools-sys/generated/operand.kinds-unified1.inc index f07003d8da..163f48e7e5 100644 --- a/spirv-tools-sys/generated/operand.kinds-unified1.inc +++ b/spirv-tools-sys/generated/operand.kinds-unified1.inc @@ -19,6 +19,7 @@ static const SpvCapability pygen_variable_caps_FragmentFullyCoveredEXT[] = {SpvC static const SpvCapability pygen_variable_caps_FragmentShaderPixelInterlockEXT[] = {SpvCapabilityFragmentShaderPixelInterlockEXT}; static const SpvCapability pygen_variable_caps_FragmentShaderSampleInterlockEXT[] = {SpvCapabilityFragmentShaderSampleInterlockEXT}; static const SpvCapability pygen_variable_caps_FragmentShaderShadingRateInterlockEXT[] = {SpvCapabilityFragmentShaderShadingRateInterlockEXT}; +static const SpvCapability pygen_variable_caps_FragmentShadingRateKHR[] = {SpvCapabilityFragmentShadingRateKHR}; static const SpvCapability pygen_variable_caps_FunctionPointersINTEL[] = {SpvCapabilityFunctionPointersINTEL}; static const SpvCapability pygen_variable_caps_GenericPointer[] = {SpvCapabilityGenericPointer}; static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry}; @@ -40,6 +41,7 @@ static const SpvCapability pygen_variable_caps_IndirectReferencesINTEL[] = {SpvC static const SpvCapability pygen_variable_caps_InputAttachment[] = {SpvCapabilityInputAttachment}; static const SpvCapability pygen_variable_caps_InputAttachmentShaderNonUniform[] = {SpvCapabilityInputAttachment, SpvCapabilityShaderNonUniform}; static const SpvCapability pygen_variable_caps_Int64[] = {SpvCapabilityInt64}; +static const SpvCapability pygen_variable_caps_Int64ImageEXT[] = {SpvCapabilityInt64ImageEXT}; static const SpvCapability pygen_variable_caps_Kernel[] = {SpvCapabilityKernel}; static const SpvCapability pygen_variable_caps_KernelGroupNonUniform[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform}; static const SpvCapability pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform, SpvCapabilitySubgroupBallotKHR}; @@ -109,6 +111,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_invocation static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer, spvtools::Extension::kSPV_KHR_physical_storage_buffer}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_image_int64[] = {spvtools::Extension::kSPV_EXT_shader_image_int64}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_export[] = {spvtools::Extension::kSPV_EXT_shader_stencil_export}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2}; static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; @@ -128,6 +131,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_16bit_storage[] = { static const spvtools::Extension pygen_variable_exts_SPV_KHR_8bit_storage[] = {spvtools::Extension::kSPV_KHR_8bit_storage}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_device_group[] = {spvtools::Extension::kSPV_KHR_device_group}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_float_controls[] = {spvtools::Extension::kSPV_KHR_float_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_fragment_shading_rate[] = {spvtools::Extension::kSPV_KHR_fragment_shading_rate}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_multiview[] = {spvtools::Extension::kSPV_KHR_multiview}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration[] = {spvtools::Extension::kSPV_KHR_no_integer_wrap_decoration}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage}; @@ -279,6 +283,13 @@ static const spv_operand_desc_t pygen_variable_RayFlagsEntries[] = { {"SkipAABBsKHR", 0x0200, 1, pygen_variable_caps_RayTraversalPrimitiveCullingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} }; +static const spv_operand_desc_t pygen_variable_FragmentShadingRateEntries[] = { + {"Vertical2Pixels", 0x0001, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"Vertical4Pixels", 0x0002, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"Horizontal2Pixels", 0x0004, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"Horizontal4Pixels", 0x0008, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = { {"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"ESSL", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, @@ -485,7 +496,9 @@ static const spv_operand_desc_t pygen_variable_ImageFormatEntries[] = { {"Rg16ui", 36, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"Rg8ui", 37, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"R16ui", 38, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"R8ui", 39, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} + {"R8ui", 39, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R64ui", 40, 1, pygen_variable_caps_Int64ImageEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"R64i", 41, 1, pygen_variable_caps_Int64ImageEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_ImageChannelOrderEntries[] = { @@ -700,8 +713,10 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = { {"BaseVertex", 4424, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, {"BaseInstance", 4425, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, {"DrawIndex", 4426, 2, pygen_variable_caps_DrawParametersMeshShadingNV, 2, pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"PrimitiveShadingRateKHR", 4432, 1, pygen_variable_caps_FragmentShadingRateKHR, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, {"DeviceIndex", 4438, 1, pygen_variable_caps_DeviceGroup, 1, pygen_variable_exts_SPV_KHR_device_group, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, {"ViewIndex", 4440, 1, pygen_variable_caps_MultiView, 1, pygen_variable_exts_SPV_KHR_multiview, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"ShadingRateKHR", 4444, 1, pygen_variable_caps_FragmentShadingRateKHR, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, {"BaryCoordNoPerspAMD", 4992, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, {"BaryCoordNoPerspCentroidAMD", 4993, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, {"BaryCoordNoPerspSampleAMD", 4994, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, @@ -862,6 +877,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"GroupNonUniformQuad", 68, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, {"ShaderLayer", 69, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"ShaderViewportIndex", 70, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"FragmentShadingRateKHR", 4422, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, {"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu}, {"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, {"SubgroupVoteKHR", 4431, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, {}, 0xffffffffu, 0xffffffffu}, @@ -892,6 +908,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu}, {"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, {"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu}, + {"Int64ImageEXT", 5016, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_image_int64, {}, 0xffffffffu, 0xffffffffu}, {"ShaderClockKHR", 5055, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_clock, {}, 0xffffffffu, 0xffffffffu}, {"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu}, {"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, @@ -1110,6 +1127,7 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { {SPV_OPERAND_TYPE_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, {SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, ARRAY_SIZE(pygen_variable_KernelProfilingInfoEntries), pygen_variable_KernelProfilingInfoEntries}, {SPV_OPERAND_TYPE_RAY_FLAGS, ARRAY_SIZE(pygen_variable_RayFlagsEntries), pygen_variable_RayFlagsEntries}, + {SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, ARRAY_SIZE(pygen_variable_FragmentShadingRateEntries), pygen_variable_FragmentShadingRateEntries}, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, ARRAY_SIZE(pygen_variable_SourceLanguageEntries), pygen_variable_SourceLanguageEntries}, {SPV_OPERAND_TYPE_EXECUTION_MODEL, ARRAY_SIZE(pygen_variable_ExecutionModelEntries), pygen_variable_ExecutionModelEntries}, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, ARRAY_SIZE(pygen_variable_AddressingModelEntries), pygen_variable_AddressingModelEntries}, From 77eb69e188da282c4d0c08489ce156ae83212a2d Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sun, 25 Oct 2020 12:51:50 +0100 Subject: [PATCH 14/41] Fixup --- spirv-tools-sys/build.rs | 24 +++-- spirv-tools-sys/generate.rs | 21 +++-- spirv-tools-sys/src/c/val.cpp | 26 ----- spirv-tools-sys/src/shared.rs | 172 +++++++++++++++++++++++++++++++++- spirv-tools-sys/src/val.rs | 11 ++- spirv-tools/src/error.rs | 64 +++++++++++++ spirv-tools/src/lib.rs | 9 ++ spirv-tools/src/val.rs | 39 +++++--- 8 files changed, 308 insertions(+), 58 deletions(-) delete mode 100644 spirv-tools-sys/src/c/val.cpp create mode 100644 spirv-tools/src/error.rs diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 8ec51461c4..82447e335c 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -170,8 +170,6 @@ fn opt(build: &mut Build) { } fn val(build: &mut Build) { - build.file("src/c/val.cpp"); - add_sources( build, "spirv-tools/source/val", @@ -242,6 +240,22 @@ fn main() { opt(&mut build); } + build.define("SPIRV_CHECK_CONTEXT", None); + + let target_def = match std::env::var("CARGO_CFG_TARGET_OS") + .expect("CARGO_CFG_TARGET_OS not set") + .as_str() + { + "linux" => "SPIRV_LINUX", + "windows" => "SPIRV_WINDOWS", + "darwin" => "SPIRV_MAC", + android if android.starts_with("android") => "SPIRV_ANDROID", + "freebsd" => "SPIRV_FREEBSD", + other => panic!("unsupported target os '{}'", other), + }; + + build.define(target_def, None); + let compiler = build.get_compiler(); if compiler.is_like_gnu() { @@ -259,8 +273,7 @@ fn main() { .flag("-Wundef") .flag("-Wconversion") .flag("-Wno-sign-conversion") - .flag("-std=gnu++11") - .flag("-Wno-error=switch"); + .flag("-std=gnu++11"); } else if compiler.is_like_clang() { build .flag("-Wextra-semi") @@ -279,8 +292,7 @@ fn main() { .flag("-Wconversion") .flag("-Wno-sign-conversion") .flag("-ftemplate-depth=1024") - .flag("-std=gnu++11") - .flag("-Wno-error=switch"); + .flag("-std=gnu++11"); } build.cpp(true); diff --git a/spirv-tools-sys/generate.rs b/spirv-tools-sys/generate.rs index a4cb7fdd19..7a87a0ba31 100644 --- a/spirv-tools-sys/generate.rs +++ b/spirv-tools-sys/generate.rs @@ -22,15 +22,6 @@ fn python>(args: impl IntoIterator) -> Resul fn main() { fs::create_dir_all("generated").expect("unable to create 'generated'"); - python(&[ - "spirv-tools/utils/generate_grammar_tables.py", - "--spirv-core-grammar=spirv-headers/include/spirv/unified1/spirv.core.grammar.json", - "--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json", - "--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json", - "--extension-enum-output=generated/extension_enum.inc", - "--enum-string-mapping-output=generated/enum_string_mapping.inc", - ]).expect("failed to generate enum includes from spirv-headers"); - python(&[ "spirv-tools/utils/update_build_version.py", "spirv-tools", @@ -38,6 +29,7 @@ fn main() { ]) .expect("failed to generate build version from spirv-headers"); + enum_string_mapping("unified1"); core_table("unified1"); glsl_table("unified1"); opencl_table("unified1"); @@ -53,6 +45,17 @@ fn main() { registry_table(); } +fn enum_string_mapping(version: &str) { + python(&[ + "spirv-tools/utils/generate_grammar_tables.py".to_owned(), + format!("--spirv-core-grammar=spirv-headers/include/spirv/{}/spirv.core.grammar.json", version), + "--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(), + "--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(), + "--extension-enum-output=generated/extension_enum.inc".to_owned(), + "--enum-string-mapping-output=generated/enum_string_mapping.inc".to_owned(), + ]).expect("failed to generate enum includes from spirv-headers"); +} + fn vendor_table(which: &str, prefix: Option<&str>) { python(&[ "spirv-tools/utils/generate_grammar_tables.py".to_owned(), diff --git a/spirv-tools-sys/src/c/val.cpp b/spirv-tools-sys/src/c/val.cpp deleted file mode 100644 index 6bbf82ae56..0000000000 --- a/spirv-tools-sys/src/c/val.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "spirv-tools/libspirv.hpp" - -struct Tool; - -extern "C" { - SPIRV_TOOLS_EXPORT Tool* tool_create(spv_target_env target_env) { - auto* tools = new spvtools::SpirvTools(target_env); - - return (Tool*)tools; - } - - SPIRV_TOOLS_EXPORT void tool_destroy(Tool* tool) { - delete (spvtools::SpirvTools*)tool; - } - - SPIRV_TOOLS_EXPORT bool validate( - const Tool* tool, - const uint32_t* binary, - size_t size, - spv_validator_options options - ) { - auto* tools = (spvtools::SpirvTools*)tool; - - return tools->Validate(binary, size, options); - } -} diff --git a/spirv-tools-sys/src/shared.rs b/spirv-tools-sys/src/shared.rs index 00f39380fb..7300cee584 100644 --- a/spirv-tools-sys/src/shared.rs +++ b/spirv-tools-sys/src/shared.rs @@ -1,3 +1,5 @@ +use std::fmt; + /// Certain target environments impose additional restrictions on SPIR-V, so it's /// often necessary to specify which one applies. `Universal_*` implies an /// environment-agnostic SPIR-V. @@ -11,7 +13,7 @@ /// SPV_ENV_VULKAN_1_2 -> SPIR-V 1.5 /// /// Consult the description of API entry points for specific rules. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] #[repr(C)] #[allow(non_camel_case_types)] pub enum TargetEnv { @@ -65,14 +67,176 @@ pub enum TargetEnv { Vulkan_1_2, } +impl Default for TargetEnv { + fn default() -> Self { + // This is the default target environment for (AFAICT) all spirv-tools + Self::Universal_1_5 + } +} + +impl std::str::FromStr for TargetEnv { + type Err = SpirvResult; + + fn from_str(s: &str) -> Result { + Ok(match s { + "vulkan1.1spv1.4" => Self::Vulkan_1_1_Spirv_1_4, + "vulkan1.0" => Self::Vulkan_1_0, + "vulkan1.1" => Self::Vulkan_1_1, + "vulkan1.2" => Self::Vulkan_1_2, + "spv1.0" => Self::Universal_1_0, + "spv1.1" => Self::Universal_1_1, + "spv1.2" => Self::Universal_1_2, + "spv1.3" => Self::Universal_1_3, + "spv1.4" => Self::Universal_1_4, + "spv1.5" => Self::Universal_1_5, + "opencl1.2embedded" => Self::OpenCLEmbedded_1_2, + "opencl1.2" => Self::OpenCL_1_2, + "opencl2.0embedded" => Self::OpenCLEmbedded_2_0, + "opencl2.0" => Self::OpenCL_2_0, + "opencl2.1embedded" => Self::OpenCLEmbedded_2_1, + "opencl2.1" => Self::OpenCL_2_1, + "opencl2.2embedded" => Self::OpenCLEmbedded_2_2, + "opencl2.2" => Self::OpenCL_2_2, + "opengl4.0" => Self::OpenGL_4_0, + "opengl4.1" => Self::OpenGL_4_1, + "opengl4.2" => Self::OpenGL_4_2, + "opengl4.3" => Self::OpenGL_4_3, + "opengl4.5" => Self::OpenGL_4_5, + "webgpu0" => Self::WebGPU_0, + _ => return Err(SpirvResult::InvalidValue), + }) + } +} + +impl fmt::Display for TargetEnv { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Self::Vulkan_1_1_Spirv_1_4 => "vulkan1.1spv1.4", + Self::Vulkan_1_0 => "vulkan1.0", + Self::Vulkan_1_1 => "vulkan1.1", + Self::Vulkan_1_2 => "vulkan1.2", + Self::Universal_1_0 => "spv1.0", + Self::Universal_1_1 => "spv1.1", + Self::Universal_1_2 => "spv1.2", + Self::Universal_1_3 => "spv1.3", + Self::Universal_1_4 => "spv1.4", + Self::Universal_1_5 => "spv1.5", + Self::OpenCLEmbedded_1_2 => "opencl1.2embedded", + Self::OpenCL_1_2 => "opencl1.2", + Self::OpenCLEmbedded_2_0 => "opencl2.0embedded", + Self::OpenCL_2_0 => "opencl2.0", + Self::OpenCLEmbedded_2_1 => "opencl2.1embedded", + Self::OpenCL_2_1 => "opencl2.1", + Self::OpenCLEmbedded_2_2 => "opencl2.2embedded", + Self::OpenCL_2_2 => "opencl2.2", + Self::OpenGL_4_0 => "opengl4.0", + Self::OpenGL_4_1 => "opengl4.1", + Self::OpenGL_4_2 => "opengl4.2", + Self::OpenGL_4_3 => "opengl4.3", + Self::OpenGL_4_5 => "opengl4.5", + Self::WebGPU_0 => "webgpu0", + }) + } +} + +#[derive(Copy, Clone, Debug, PartialEq)] +#[repr(i32)] // SPV_FORCE_32_BIT_ENUM +pub enum SpirvResult { + Success = 0, + Unsupported = 1, + EndOfStream = 2, + Warning = 3, + FailedMatch = 4, + /// Success, but signals early termination. + RequestedTermination = 5, + InternalError = -1, + OutOfMemory = -2, + InvalidPointer = -3, + InvalidBinary = -4, + InvalidText = -5, + InvalidTable = -6, + InvalidValue = -7, + InvalidDiagnostic = -8, + InvalidLookup = -9, + InvalidId = -10, + InvalidCfg = -11, + InvalidLayout = -12, + InvalidCapability = -13, + /// Indicates data rules validation failure. + InvalidData = -14, + MissingExtension = -15, + /// Indicates wrong SPIR-V version + WrongVersion = -16, +} + +impl fmt::Display for SpirvResult { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use SpirvResult::*; + + match self { + Success => f.write_str("success"), + Unsupported => f.write_str("unsupported"), + EndOfStream => f.write_str("end of stream"), + Warning => f.write_str("warning"), + FailedMatch => f.write_str("failed match"), + RequestedTermination => f.write_str("requested termination"), + InternalError => f.write_str("internal error"), + OutOfMemory => f.write_str("out of memory"), + InvalidPointer => f.write_str("invalid pointer"), + InvalidBinary => f.write_str("invalid binary"), + InvalidText => f.write_str("invalid text"), + InvalidTable => f.write_str("invalid table"), + InvalidValue => f.write_str("invalid value"), + InvalidDiagnostic => f.write_str("invalid diagnostic"), + InvalidLookup => f.write_str("invalid lookup"), + InvalidId => f.write_str("invalid id"), + InvalidCfg => f.write_str("invalid cfg"), + InvalidLayout => f.write_str("invalid layout"), + InvalidCapability => f.write_str("invalid capability"), + InvalidData => f.write_str("invalid data"), + MissingExtension => f.write_str("missing extension"), + WrongVersion => f.write_str("wrong SPIR-V version"), + } + } +} + +impl std::error::Error for SpirvResult {} + #[cfg(feature = "tools")] #[repr(C)] -pub struct Tool { +pub struct ToolContext { _unused: [u8; 0], } +#[repr(C)] +pub struct Position { + pub line: usize, + pub column: usize, + pub index: usize, +} + +#[repr(C)] +pub struct Diagnostic { + pub position: Position, + pub error: *const std::os::raw::c_char, + pub is_text_source: bool, +} + #[cfg(feature = "tools")] extern "C" { - pub fn tool_create(env: TargetEnv) -> *mut Tool; - pub fn tool_destroy(opt: *mut Tool); + /// Creates a context object for most of the SPIRV-Tools API. + /// Returns null if env is invalid. + /// + /// See specific API calls for how the target environment is interpeted + /// (particularly assembly and validation). + #[link_name = "spvContextCreate"] + pub fn context_create(env: TargetEnv) -> *mut ToolContext; + /// Destroys the given context object. + #[link_name = "spvContextDestroy"] + pub fn context_destroy(opt: *mut ToolContext); + + /// Destroys a diagnostic object. This is a no-op if diagnostic is a null + /// pointer. + #[link_name = "spvDiagnosticDestroy"] + pub fn diagnostic_destroy(diag: *mut Diagnostic); } diff --git a/spirv-tools-sys/src/val.rs b/spirv-tools-sys/src/val.rs index d5b3e75268..a2af83c108 100644 --- a/spirv-tools-sys/src/val.rs +++ b/spirv-tools-sys/src/val.rs @@ -1,3 +1,5 @@ +use crate::shared; + #[repr(C)] pub struct ValidatorOptions { _unused: [u8; 0], @@ -18,12 +20,17 @@ pub enum ValidatorLimits { } extern "C" { + /// Validates a raw SPIR-V binary for correctness. Any errors will be written + /// into *diagnostic if diagnostic is non-null, otherwise the context's message + /// consumer will be used. + #[link_name = "spvValidateBinary"] pub fn validate( - tool: *const crate::shared::Tool, + tool: *const shared::ToolContext, binary: *const u32, size: usize, options: *const ValidatorOptions, - ) -> bool; + diagnostic: *mut *mut shared::Diagnostic, + ) -> crate::shared::SpirvResult; /// Creates a Validator options object with default options. Returns a valid /// options object. The object remains valid until it is passed into diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs new file mode 100644 index 0000000000..f7c91db16f --- /dev/null +++ b/spirv-tools/src/error.rs @@ -0,0 +1,64 @@ +use spirv_tools_sys::shared; + +#[derive(Debug, PartialEq)] +pub struct Error { + pub inner: shared::SpirvResult, + pub diagnostic: Option, +} + +use std::fmt; + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.diagnostic { + Some(diag) => f.write_fmt(format_args!( + "{}:{}:{} - {}", + self.inner, diag.line, diag.column, diag.message + )), + None => f.write_fmt(format_args!("{}", self.inner)), + } + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + Some(&self.inner) + } +} + +#[derive(Debug, PartialEq)] +pub struct Diagnostic { + pub line: usize, + pub column: usize, + pub index: usize, + pub message: String, + pub is_text: bool, +} + +impl std::convert::TryFrom<*mut shared::Diagnostic> for Diagnostic { + type Error = shared::SpirvResult; + + #[allow(clippy::not_unsafe_ptr_arg_deref)] + fn try_from(diag: *mut shared::Diagnostic) -> Result { + unsafe { + if diag.is_null() { + return Err(shared::SpirvResult::Success); + } + + let message = std::ffi::CStr::from_ptr((*diag).error) + .to_string_lossy() + .to_string(); + + let res = Self { + line: (*diag).position.line, + column: (*diag).position.column, + index: (*diag).position.index, + message, + is_text: (*diag).is_text_source, + }; + + shared::diagnostic_destroy(diag); + Ok(res) + } + } +} diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index a3fdb4c463..3fc5dd7c46 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -4,3 +4,12 @@ pub mod opt; pub mod val; pub use spirv_tools_sys::shared; + +pub mod error; + +pub use error::Error; + +/// Gets the default target environment, currently Universal_1_5 +pub fn default_target_env() -> shared::TargetEnv { + shared::TargetEnv::default() +} diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index c14be29e42..87b16da783 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -135,30 +135,47 @@ impl Drop for ValidatorOptions { } pub struct Validator { - inner: *mut shared::Tool, + inner: *mut shared::ToolContext, } impl Validator { pub fn new(target_env: shared::TargetEnv) -> Self { Self { - inner: unsafe { shared::tool_create(target_env) }, + inner: unsafe { shared::context_create(target_env) }, } } - pub fn validate(&self, binary: &[u32], options: &ValidatorOptions) -> Result<(), ()> { - let ret = - unsafe { val::validate(self.inner, binary.as_ptr(), binary.len(), options.inner) }; - - if ret { - Ok(()) - } else { - Err(()) + pub fn validate( + &self, + binary: &[u32], + options: &ValidatorOptions, + ) -> Result<(), crate::error::Error> { + unsafe { + let mut diagnostic = std::ptr::null_mut(); + let res = val::validate( + self.inner, + binary.as_ptr(), + binary.len(), + options.inner, + &mut diagnostic, + ); + + use std::convert::TryFrom; + let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok(); + + match res { + shared::SpirvResult::Success => Ok(()), + other => Err(crate::error::Error { + inner: other, + diagnostic, + }), + } } } } impl Drop for Validator { fn drop(&mut self) { - unsafe { shared::tool_destroy(self.inner) } + unsafe { shared::context_destroy(self.inner) } } } From e499051192e13155b7c58be400f346b0dbc1338e Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sun, 25 Oct 2020 12:52:26 +0100 Subject: [PATCH 15/41] Add assembler and example --- Cargo.lock | 1 + spirv-tools-sys/Cargo.toml | 1 + spirv-tools-sys/src/assembler.rs | 40 +++++++++++ spirv-tools-sys/src/lib.rs | 3 + spirv-tools/Cargo.toml | 8 +++ spirv-tools/examples/as.rs | 61 ++++++++++++++++ spirv-tools/src/assembler.rs | 119 +++++++++++++++++++++++++++++++ spirv-tools/src/lib.rs | 3 + 8 files changed, 236 insertions(+) create mode 100644 spirv-tools-sys/src/assembler.rs create mode 100644 spirv-tools/examples/as.rs create mode 100644 spirv-tools/src/assembler.rs diff --git a/Cargo.lock b/Cargo.lock index 36ccad42db..f49a5e4a22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2205,6 +2205,7 @@ name = "spirv-tools" version = "0.1.0" dependencies = [ "spirv-tools-sys", + "structopt", ] [[package]] diff --git a/spirv-tools-sys/Cargo.toml b/spirv-tools-sys/Cargo.toml index f85d35d8d3..9e2c752fb5 100644 --- a/spirv-tools-sys/Cargo.toml +++ b/spirv-tools-sys/Cargo.toml @@ -7,6 +7,7 @@ build = "build.rs" license = "MIT OR Apache-2.0" [features] +as = ["tools"] opt = ["val"] val = ["tools"] tools = [] diff --git a/spirv-tools-sys/src/assembler.rs b/spirv-tools-sys/src/assembler.rs new file mode 100644 index 0000000000..be626f2a7d --- /dev/null +++ b/spirv-tools-sys/src/assembler.rs @@ -0,0 +1,40 @@ +use crate::shared; + +#[repr(u32)] // SPV_FORCE_32_BIT_ENUM +pub enum BinaryOptions { + None = 0x1, + PreserveNumberIds = 1 << 1, +} + +#[repr(C)] +pub struct Binary { + pub code: *const u32, + pub size: usize, +} + +extern "C" { + /// Encodes the given SPIR-V assembly text to its binary representation. The + /// length parameter specifies the number of bytes for text. Encoded binary will + /// be stored into *binary. Any error will be written into *diagnostic if + /// diagnostic is non-null, otherwise the context's message consumer will be + /// used. The generated binary is independent of the context and may outlive it. + /// The SPIR-V binary version is set to the highest version of SPIR-V supported + /// by the context's target environment. + /// + /// The options parameter is a bit field of + /// spv_text_to_binary_options_t. + #[link_name = "spvTextToBinaryWithOptions"] + pub fn assemble( + tool: *const shared::ToolContext, + text: *const std::os::raw::c_char, + size: usize, + options: u32, + binary: *mut *mut Binary, + diagnostic: *mut *mut shared::Diagnostic, + ) -> crate::shared::SpirvResult; + + /// Frees a binary stream from memory. This is a no-op if binary is a null + /// pointer. + #[link_name = "spvBinaryDestroy"] + pub fn binary_destroy(binary: *mut Binary); +} diff --git a/spirv-tools-sys/src/lib.rs b/spirv-tools-sys/src/lib.rs index e93ca7ae79..780c8817e4 100644 --- a/spirv-tools-sys/src/lib.rs +++ b/spirv-tools-sys/src/lib.rs @@ -5,3 +5,6 @@ pub mod opt; #[cfg(feature = "val")] pub mod val; + +#[cfg(feature = "as")] +pub mod assembler; diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index ae646e7221..0e2ad9f088 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -6,8 +6,16 @@ edition = "2018" license = "MIT OR Apache-2.0" [features] +as = ["spirv-tools-sys/as"] opt = ["spirv-tools-sys/opt"] val = ["spirv-tools-sys/val"] [dependencies] spirv-tools-sys = { path = "../spirv-tools-sys" } + +[dev-dependencies] +structopt = "0.3" + +[[example]] +name = "as" +required-features = ["as"] diff --git a/spirv-tools/examples/as.rs b/spirv-tools/examples/as.rs new file mode 100644 index 0000000000..624ac2ed9d --- /dev/null +++ b/spirv-tools/examples/as.rs @@ -0,0 +1,61 @@ +use structopt::StructOpt; + +/// Create a SPIR-V binary module from SPIR-V assembly text +#[derive(StructOpt)] +struct Args { + /// Set the output filename. Use '-' for stdout. + #[structopt(short, default_value = "out.spv")] + output: String, + /// Numeric IDs in the binary will have the same values as in the + /// source. Non-numeric IDs are allocated by filling in the gaps, + /// starting with 1 and going up. + #[structopt(long = "preserve-numeric-ids")] + preserve_ids: bool, + /// Use specified environment. + #[structopt(long = "target-env", parse(try_from_str))] + target_env: Option, + /// The input file. Use '-' for stdin. + #[structopt(name = "FILE")] + input: String, +} + +fn main() { + use spirv_tools::assembler; + + let args = Args::from_args(); + + let contents = if args.input == "-" { + use std::io::Read; + let mut v = Vec::with_capacity(1024); + std::io::stdin() + .read_to_end(&mut v) + .expect("failed to read stdin"); + String::from_utf8(v).expect("stdin had invalid utf-8") + } else { + std::fs::read_to_string(&args.input).expect("failed to read input file") + }; + + let assembler_opts = assembler::AssemblerOptions { + preserve_numeric_ids: args.preserve_ids, + }; + + let assembler = assembler::Assembler::new(args.target_env.unwrap_or_default()); + + match assembler.assemble(&contents, assembler_opts) { + Ok(binary) => { + if args.output == "-" { + use std::io::Write; + std::io::stdout() + .lock() + .write(binary.as_ref()) + .expect("failed to write binary to stdout"); + } else { + std::fs::write(args.output, &binary).expect("failed to write binary"); + } + } + Err(e) => { + eprintln!("{}", e); + std::process::exit(1); + } + } +} diff --git a/spirv-tools/src/assembler.rs b/spirv-tools/src/assembler.rs new file mode 100644 index 0000000000..cb1aa59f40 --- /dev/null +++ b/spirv-tools/src/assembler.rs @@ -0,0 +1,119 @@ +use spirv_tools_sys::{assembler, shared}; + +pub struct Binary { + inner: *mut assembler::Binary, +} + +impl AsRef<[u32]> for Binary { + fn as_ref(&self) -> &[u32] { + unsafe { std::slice::from_raw_parts((*self.inner).code, (*self.inner).size) } + } +} + +impl AsRef<[u8]> for Binary { + fn as_ref(&self) -> &[u8] { + unsafe { + std::slice::from_raw_parts( + (*self.inner).code as *const u8, + (*self.inner).size * std::mem::size_of::(), + ) + } + } +} + +impl Drop for Binary { + fn drop(&mut self) { + unsafe { + assembler::binary_destroy(self.inner); + } + } +} + +#[derive(Copy, Clone, Default)] +pub struct AssemblerOptions { + /// Numeric IDs in the binary will have the same values as in the source. + /// Non-numeric IDs are allocated by filling in the gaps, starting with 1 + /// and going up. + pub preserve_numeric_ids: bool, +} + +impl Into for AssemblerOptions { + fn into(self) -> u32 { + // This is weird, the "none" is 1, so I'm not sure if that means having + // it disables all other options or...? + let mut res = 0; //assembler::BinaryOptions::None as u32; + + if self.preserve_numeric_ids { + res |= assembler::BinaryOptions::PreserveNumberIds as u32; + } + + res + } +} + +pub struct Assembler { + inner: *mut shared::ToolContext, +} + +impl Assembler { + pub fn new(target_env: shared::TargetEnv) -> Self { + Self { + inner: unsafe { shared::context_create(target_env) }, + } + } + + pub fn assemble( + &self, + text: &str, + options: AssemblerOptions, + ) -> Result { + unsafe { + let mut binary = std::ptr::null_mut(); + let mut diagnostic = std::ptr::null_mut(); + + let res = assembler::assemble( + self.inner, + text.as_ptr() as *const _, + text.len(), + options.into(), + &mut binary, + &mut diagnostic, + ); + + // Always wrap diagnostic, it's fine if it's null + use std::convert::TryFrom; + let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok(); + + match res { + shared::SpirvResult::Success => { + if binary.is_null() { + return Err(crate::error::Error { + inner: shared::SpirvResult::InternalError, + diagnostic: Some(crate::error::Diagnostic { + line: 0, + column: 0, + index: 0, + message: "spirv assemble indicated success but did not return a valid binary".to_owned(), + is_text: true, + }), + }); + } + + Ok(Binary { inner: binary }) + } + other => Err(crate::error::Error { + inner: other, + diagnostic, + }), + } + } + } +} + +impl Drop for Assembler { + fn drop(&mut self) { + unsafe { + shared::context_destroy(self.inner); + } + } +} diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index 3fc5dd7c46..d870927dfa 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -3,6 +3,9 @@ pub mod opt; #[cfg(feature = "val")] pub mod val; +#[cfg(feature = "as")] +pub mod assembler; + pub use spirv_tools_sys::shared; pub mod error; From c951704912511409e0edd8886bd9166e7d6587a3 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sun, 25 Oct 2020 12:52:58 +0100 Subject: [PATCH 16/41] Use assembler in tests --- rustc_codegen_spirv/Cargo.toml | 9 ++- rustc_codegen_spirv/src/linker/mod.rs | 10 +++ rustc_codegen_spirv/src/linker/test.rs | 88 +++++++++----------------- 3 files changed, 46 insertions(+), 61 deletions(-) diff --git a/rustc_codegen_spirv/Cargo.toml b/rustc_codegen_spirv/Cargo.toml index d6304f5ae7..9189dc09d8 100644 --- a/rustc_codegen_spirv/Cargo.toml +++ b/rustc_codegen_spirv/Cargo.toml @@ -19,11 +19,16 @@ tar = "0.4.30" thiserror = "1.0.20" topological-sort = "0.1" +[dependencies.spirv-tools] +version = "0.1.0" +path = "../spirv-tools" +features = ["opt", "val"] + [dev-dependencies] pretty_assertions = "0.6" tempfile = "3.1" -[dependencies.spirv-tools] +[dev-dependencies.spirv-tools] version = "0.1.0" path = "../spirv-tools" -features = ["opt", "val"] +features = ["as"] diff --git a/rustc_codegen_spirv/src/linker/mod.rs b/rustc_codegen_spirv/src/linker/mod.rs index 60b19caf14..c5e68df1ea 100644 --- a/rustc_codegen_spirv/src/linker/mod.rs +++ b/rustc_codegen_spirv/src/linker/mod.rs @@ -26,6 +26,16 @@ pub enum LinkerError { MultipleExports(String), #[error("Types mismatch for {:?}", .name)] TypeMismatch { name: String }, + #[error("spirv-tools error {:#}", .0)] + #[cfg(test)] + SpirvTool(spirv_tools::Error), +} + +#[cfg(test)] +impl From for LinkerError { + fn from(err: spirv_tools::Error) -> Self { + Self::SpirvTool(err) + } } pub type Result = std::result::Result; diff --git a/rustc_codegen_spirv/src/linker/test.rs b/rustc_codegen_spirv/src/linker/test.rs index 725eb6c58d..16b853d877 100644 --- a/rustc_codegen_spirv/src/linker/test.rs +++ b/rustc_codegen_spirv/src/linker/test.rs @@ -12,54 +12,24 @@ impl<'a> std::fmt::Debug for PrettyString<'a> { } } -fn assemble_spirv(spirv: &str) -> Vec { - use std::process::Command; - use tempfile::tempdir; +fn assemble_spirv(spirv: &str) -> Result> { + use spirv_tools::assembler; - let temp = tempdir().expect("Unable to create temp dir"); - let input = temp.path().join("code.txt"); - let output = temp.path().join("code.spv"); + let assembler = assembler::Assembler::new(spirv_tools::default_target_env()); - std::fs::write(&input, spirv).unwrap(); + let spv_binary = assembler.assemble(spirv, assembler::AssemblerOptions::default())?; - let process = Command::new("spirv-as") - .arg(input.to_str().unwrap()) - .arg("-o") - .arg(output.to_str().unwrap()) - .output() - .expect("failed to execute process"); - - println!("status: {}", process.status); - println!("stdout: {}", String::from_utf8_lossy(&process.stdout)); - println!("stderr: {}", String::from_utf8_lossy(&process.stderr)); - - assert!(process.status.success()); - - std::fs::read(&output).unwrap() + let contents: &[u8] = spv_binary.as_ref(); + Ok(contents.to_vec()) } #[allow(unused)] fn validate(spirv: &[u32]) { - use std::process::Command; - use tempfile::tempdir; - - let temp = tempdir().expect("Unable to create temp dir"); - let input = temp.path().join("code.spv"); - - let spirv = unsafe { std::slice::from_raw_parts(spirv.as_ptr() as *const u8, spirv.len() * 4) }; - - std::fs::write(&input, spirv).unwrap(); - - let process = Command::new("spirv-val.exe") - .arg(input.to_str().unwrap()) - .output() - .expect("failed to execute process"); + let validator = spirv_tools::val::Validator::new(spirv_tools::default_target_env()); - println!("status: {}", process.status); - println!("stdout: {}", String::from_utf8_lossy(&process.stdout)); - println!("stderr: {}", String::from_utf8_lossy(&process.stderr)); - - assert!(process.status.success()); + validator + .validate(spirv, &spirv_tools::val::ValidatorOptions::default()) + .expect("validation error occurred"); } fn load(bytes: &[u8]) -> Module { @@ -126,7 +96,7 @@ fn standard() -> Result<()> { %2 = OpTypeFloat 32 %1 = OpVariable %2 Uniform %3 = OpVariable %2 Input"#, - ); + )?; let b = assemble_spirv( r#"OpCapability Linkage @@ -135,7 +105,7 @@ fn standard() -> Result<()> { %3 = OpConstant %2 42 %1 = OpVariable %2 Uniform %3 "#, - ); + )?; let result = assemble_and_link(&[&a, &b])?; let expect = r#"%1 = OpTypeFloat 32 @@ -154,7 +124,7 @@ fn not_a_lib_extra_exports() -> Result<()> { OpDecorate %1 LinkageAttributes "foo" Export %2 = OpTypeFloat 32 %1 = OpVariable %2 Uniform"#, - ); + )?; let result = assemble_and_link(&[&a])?; let expect = r#"%1 = OpTypeFloat 32 @@ -191,9 +161,9 @@ fn unresolved_symbol() -> Result<()> { OpDecorate %1 LinkageAttributes "foo" Import %2 = OpTypeFloat 32 %1 = OpVariable %2 Uniform"#, - ); + )?; - let b = assemble_spirv("OpCapability Linkage"); + let b = assemble_spirv("OpCapability Linkage")?; let result = assemble_and_link(&[&a, &b]); @@ -213,7 +183,7 @@ fn type_mismatch() -> Result<()> { %2 = OpTypeFloat 32 %1 = OpVariable %2 Uniform %3 = OpVariable %2 Input"#, - ); + )?; let b = assemble_spirv( r#"OpCapability Linkage @@ -222,7 +192,7 @@ fn type_mismatch() -> Result<()> { %3 = OpConstant %2 42 %1 = OpVariable %2 Uniform %3 "#, - ); + )?; let result = assemble_and_link(&[&a, &b]); assert_eq!( @@ -242,7 +212,7 @@ fn multiple_definitions() -> Result<()> { %2 = OpTypeFloat 32 %1 = OpVariable %2 Uniform %3 = OpVariable %2 Input"#, - ); + )?; let b = assemble_spirv( r#"OpCapability Linkage @@ -251,7 +221,7 @@ fn multiple_definitions() -> Result<()> { %2 = OpTypeFloat 32 %3 = OpConstant %2 42 %1 = OpVariable %2 Uniform %3"#, - ); + )?; let c = assemble_spirv( r#"OpCapability Linkage @@ -259,7 +229,7 @@ fn multiple_definitions() -> Result<()> { %2 = OpTypeFloat 32 %3 = OpConstant %2 -1 %1 = OpVariable %2 Uniform %3"#, - ); + )?; let result = assemble_and_link(&[&a, &b, &c]); assert_eq!( @@ -277,7 +247,7 @@ fn multiple_definitions_different_types() -> Result<()> { %2 = OpTypeFloat 32 %1 = OpVariable %2 Uniform %3 = OpVariable %2 Input"#, - ); + )?; let b = assemble_spirv( r#"OpCapability Linkage @@ -286,7 +256,7 @@ fn multiple_definitions_different_types() -> Result<()> { %2 = OpTypeInt 32 0 %3 = OpConstant %2 42 %1 = OpVariable %2 Uniform %3"#, - ); + )?; let c = assemble_spirv( r#"OpCapability Linkage @@ -294,7 +264,7 @@ fn multiple_definitions_different_types() -> Result<()> { %2 = OpTypeFloat 32 %3 = OpConstant %2 12 %1 = OpVariable %2 Uniform %3"#, - ); + )?; let result = assemble_and_link(&[&a, &b, &c]); assert_eq!( @@ -343,7 +313,7 @@ fn func_ctrl() -> Result<()> { %5 = OpVariable %4 Uniform %1 = OpFunction %2 None %3 OpFunctionEnd"#, - ); + )?; let b = assemble_spirv( r#"OpCapability Linkage @@ -354,7 +324,7 @@ fn func_ctrl() -> Result<()> { %4 = OpLabel OpReturn OpFunctionEnd"#, - ); + )?; let result = assemble_and_link(&[&a, &b])?; @@ -390,7 +360,7 @@ fn use_exported_func_param_attr() -> Result<()> { %4 = OpFunctionParameter %6 OpFunctionEnd "#, - ); + )?; let b = assemble_spirv( r#"OpCapability Kernel @@ -406,7 +376,7 @@ fn use_exported_func_param_attr() -> Result<()> { OpReturn OpFunctionEnd "#, - ); + )?; let result = assemble_and_link(&[&a, &b])?; @@ -454,7 +424,7 @@ fn names_and_decorations() -> Result<()> { %4 = OpFunctionParameter %9 OpFunctionEnd "#, - ); + )?; let b = assemble_spirv( r#"OpCapability Kernel @@ -473,7 +443,7 @@ fn names_and_decorations() -> Result<()> { OpReturn OpFunctionEnd "#, - ); + )?; let result = assemble_and_link(&[&a, &b])?; From 26730ae8a0b6123d210d8c60418926b74e77eb88 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sun, 25 Oct 2020 13:12:16 +0100 Subject: [PATCH 17/41] Oops, fix macos TARGET_OS --- spirv-tools-sys/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 82447e335c..9bc37e1356 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -248,7 +248,7 @@ fn main() { { "linux" => "SPIRV_LINUX", "windows" => "SPIRV_WINDOWS", - "darwin" => "SPIRV_MAC", + "macos" => "SPIRV_MAC", android if android.starts_with("android") => "SPIRV_ANDROID", "freebsd" => "SPIRV_FREEBSD", other => panic!("unsupported target os '{}'", other), From 504002581dd132778f719604b5ee4ecf6c58d556 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Sun, 25 Oct 2020 13:27:40 +0100 Subject: [PATCH 18/41] write -> write_all --- spirv-tools/examples/as.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirv-tools/examples/as.rs b/spirv-tools/examples/as.rs index 624ac2ed9d..83766ee61b 100644 --- a/spirv-tools/examples/as.rs +++ b/spirv-tools/examples/as.rs @@ -47,7 +47,7 @@ fn main() { use std::io::Write; std::io::stdout() .lock() - .write(binary.as_ref()) + .write_all(binary.as_ref()) .expect("failed to write binary to stdout"); } else { std::fs::write(args.output, &binary).expect("failed to write binary"); From 67a526b78a2aa0cc473fc9076150beeb8f166675 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Mon, 26 Oct 2020 10:02:32 +0100 Subject: [PATCH 19/41] Start splitting spirv-tools into a compiled vs tool feature set --- rustc_codegen_spirv/Cargo.toml | 11 +- rustc_codegen_spirv/src/link.rs | 43 +++--- spirv-tools-sys/Cargo.toml | 8 +- spirv-tools-sys/build.rs | 16 +-- spirv-tools-sys/src/assembler.rs | 17 +-- spirv-tools-sys/src/c/opt.cpp | 73 +++++++--- spirv-tools-sys/src/diagnostics.rs | 50 +++++++ spirv-tools-sys/src/lib.rs | 11 +- spirv-tools-sys/src/opt.rs | 19 +-- spirv-tools-sys/src/shared.rs | 26 ++-- spirv-tools-sys/src/val.rs | 2 +- spirv-tools/Cargo.toml | 5 +- spirv-tools/src/assembler.rs | 33 +---- spirv-tools/src/error.rs | 69 +++++++++- spirv-tools/src/lib.rs | 15 +-- spirv-tools/src/opt.rs | 186 ++++---------------------- spirv-tools/src/opt/compiled.rs | 205 +++++++++++++++++++++++++++++ spirv-tools/src/opt/options.rs | 48 ------- spirv-tools/src/opt/tool.rs | 0 spirv-tools/src/shared.rs | 36 +++++ spirv-tools/src/val.rs | 46 ------- spirv-tools/src/val/compiled.rs | 45 +++++++ 22 files changed, 541 insertions(+), 423 deletions(-) create mode 100644 spirv-tools-sys/src/diagnostics.rs create mode 100644 spirv-tools/src/opt/compiled.rs delete mode 100644 spirv-tools/src/opt/options.rs create mode 100644 spirv-tools/src/opt/tool.rs create mode 100644 spirv-tools/src/shared.rs create mode 100644 spirv-tools/src/val/compiled.rs diff --git a/rustc_codegen_spirv/Cargo.toml b/rustc_codegen_spirv/Cargo.toml index 9189dc09d8..509758e09f 100644 --- a/rustc_codegen_spirv/Cargo.toml +++ b/rustc_codegen_spirv/Cargo.toml @@ -12,6 +12,11 @@ repository = "https://github.com/EmbarkStudios/rust-gpu" [lib] crate-type = ["dylib"] +[features] +# If enabled, uses spirv-tools binaries installed in PATH, instead of +# compiling and linking the spirv-tools C++ code +use-installed-tools = ["spirv-tools/use-installed"] + [dependencies] bimap = "0.5" rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "f11f8797bd4df2d1d22cf10767b39a5119c57551" } @@ -22,13 +27,7 @@ topological-sort = "0.1" [dependencies.spirv-tools] version = "0.1.0" path = "../spirv-tools" -features = ["opt", "val"] [dev-dependencies] pretty_assertions = "0.6" tempfile = "3.1" - -[dev-dependencies.spirv-tools] -version = "0.1.0" -path = "../spirv-tools" -features = ["as"] diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 9972feb7a3..30db113f57 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -155,41 +155,41 @@ fn link_exe( } fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec { - use spirv_tools::{opt, shared}; + use spirv_tools::{error, opt}; - // This is the same default target environment that spirv-opt uses - let mut optimizer = opt::Optimizer::new(shared::TargetEnv::Universal_1_5); + let mut optimizer = opt::Optimizer::new(spirv_tools::TargetEnv::default()); optimizer .register_size_passes() .register_pass(opt::Passes::EliminateDeadConstant) .register_pass(opt::Passes::StripDebugInfo); - let mut opts = opt::Options::new(); + let result = optimizer.optimize( + &spv_binary, + &mut |msg: error::Message<'_>| { + use error::MessageLevel as Level; - // We run the validator separately - opts.run_validator(false); + // TODO: Adds spans here? Not sure how useful with binary, but maybe? - let mut optimized_binary = None; + let mut err = match msg.level { + Level::Fatal | Level::InternalError => sess.struct_fatal(&msg.message), + Level::Error => sess.struct_err(&msg.message), + Level::Warning => sess.struct_warn(&msg.message), + Level::Info | Level::Debug => sess.struct_note_without_error(&msg.message), + }; - let result = optimizer.optimize( - &spv_binary, - &mut |data: &[u32]| { - optimized_binary = Some(data.to_vec()); + err.note(&format!("module {:?}", filename)); + err.emit(); }, - Some(&opts), + // We currently run the validator separately after optimization or even + // if we don't run optimization, the default options don't run the validator + None, ); match result { - Err(opt::RunResult::OptimizerFailed) => { - let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); - err.note(&format!("module {:?}", filename)); - spv_binary - } - Ok(_) => optimized_binary.unwrap(), + Ok(binary) => binary.as_ref().to_vec(), Err(_) => { - let mut err = - sess.struct_warn("invalid arguments supplied to spirv-opt, leaving as unoptimized"); + let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); err.note(&format!("module {:?}", filename)); spv_binary } @@ -199,8 +199,7 @@ fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec crate::shared::SpirvResult; - - /// Frees a binary stream from memory. This is a no-op if binary is a null - /// pointer. - #[link_name = "spvBinaryDestroy"] - pub fn binary_destroy(binary: *mut Binary); + binary: *mut *mut shared::Binary, + diagnostic: *mut *mut crate::diagnostics::Diagnostic, + ) -> shared::SpirvResult; } diff --git a/spirv-tools-sys/src/c/opt.cpp b/spirv-tools-sys/src/c/opt.cpp index fab1d32b23..4a1d60202d 100644 --- a/spirv-tools-sys/src/c/opt.cpp +++ b/spirv-tools-sys/src/c/opt.cpp @@ -1,4 +1,5 @@ #include "spirv-tools/optimizer.hpp" +#include struct Optimus; @@ -64,17 +65,13 @@ enum Passes { AmdExtToKhr, }; -enum RunResult { - InvalidInputBuffer, - InvalidInputSize, - InvalidOutputBuffer, - InvalidOutputSize, - InvalidCallback, - OptimizerFailed, - OptimizerSucceeded, -}; - -typedef void (*optimized_callback)(const uint32_t* data, size_t len, void* ctx); +typedef void (*message_callback)( + spv_message_level_t level, + const char* source, + const spv_position_t* position, + const char* message, + void* ctx +); extern "C" { SPIRV_TOOLS_EXPORT Optimus* optimizer_create(spv_target_env target_env) { @@ -87,25 +84,47 @@ extern "C" { delete (spvtools::Optimizer*)optimizer; } - SPIRV_TOOLS_EXPORT RunResult optimizer_run( + SPIRV_TOOLS_EXPORT spv_result_t optimizer_run( const Optimus* optimizer, const uint32_t* input_ptr, size_t input_size, - optimized_callback callback, + spv_binary* out_binary, + message_callback msg_callback, void* ctx, const spv_optimizer_options options ) { if (input_ptr == nullptr) { - return RunResult::InvalidInputBuffer; + return SPV_ERROR_INVALID_POINTER; } - if (callback == nullptr) { - return RunResult::InvalidCallback; + if (out_binary == nullptr) { + return SPV_ERROR_INVALID_POINTER; } - auto output_buff = std::vector(); - auto op = (spvtools::Optimizer*)optimizer; + + if (msg_callback) { + op->SetMessageConsumer([msg_callback, ctx]( + spv_message_level_t level, + const char* source, + const spv_position_t& position, + const char* message) { + msg_callback(level, source, &position, message, ctx); + }); + } else { + // The optimizer keeps the message consumer as state, so if no + // callback is passed to us, we insert a noop callback to ensure + // we don't use the state from a previous optimizer run + op->SetMessageConsumer([]( + spv_message_level_t, + const char*, + const spv_position_t&, + const char*) + {} + ); + } + + auto output_buff = std::vector(); bool success = false; if (options == nullptr) { success = op->Run(input_ptr, input_size, &output_buff); @@ -114,12 +133,24 @@ extern "C" { } if (!success) { - return RunResult::OptimizerFailed; + return SPV_ERROR_INTERNAL; + } + + uint32_t* data = new uint32_t[output_buff.size()]; + if (data == nullptr) { + return SPV_ERROR_OUT_OF_MEMORY; + } + + spv_binary binary = new spv_binary_t(); + if (binary == nullptr) { + delete[] data; + return SPV_ERROR_OUT_OF_MEMORY; } - callback(output_buff.data(), output_buff.size(), ctx); + memcpy(data, output_buff.data(), output_buff.size()); + *out_binary = binary; - return RunResult::OptimizerSucceeded; + return SPV_SUCCESS; } SPIRV_TOOLS_EXPORT void optimizer_register_pass(Optimus* optimizer, Passes pass) { diff --git a/spirv-tools-sys/src/diagnostics.rs b/spirv-tools-sys/src/diagnostics.rs new file mode 100644 index 0000000000..8b47bdfc26 --- /dev/null +++ b/spirv-tools-sys/src/diagnostics.rs @@ -0,0 +1,50 @@ +#[repr(C)] +pub struct Position { + pub line: usize, + pub column: usize, + pub index: usize, +} + +#[repr(C)] +pub struct Diagnostic { + pub position: Position, + pub error: *const std::os::raw::c_char, + pub is_text_source: bool, +} + +#[derive(Copy, Clone, PartialEq, Debug)] +#[repr(C)] +pub enum MessageLevel { + /// Unrecoverable error due to environment. + /// Will exit the program immediately. E.g., + /// out of memory. + Fatal, + /// Unrecoverable error due to SPIRV-Tools + /// internals. + /// Will exit the program immediately. E.g., + /// unimplemented feature. + InternalError, + /// Normal error due to user input. + Error, + /// Warning information. + Warning, + /// General information. + Info, + /// Debug information. + Debug, +} + +pub type MessageCallback = extern "C" fn( + MessageLevel, // level + *const std::os::raw::c_char, // source + *const Position, // source position + *const std::os::raw::c_char, // the actual message + *mut std::ffi::c_void, // context we use for mapping +); + +extern "C" { + /// Destroys a diagnostic object. This is a no-op if diagnostic is a null + /// pointer. + #[link_name = "spvDiagnosticDestroy"] + pub fn diagnostic_destroy(diag: *mut Diagnostic); +} diff --git a/spirv-tools-sys/src/lib.rs b/spirv-tools-sys/src/lib.rs index 780c8817e4..e40dccc47b 100644 --- a/spirv-tools-sys/src/lib.rs +++ b/spirv-tools-sys/src/lib.rs @@ -1,10 +1,5 @@ -pub mod shared; - -#[cfg(feature = "opt")] +pub mod assembler; +pub mod diagnostics; pub mod opt; - -#[cfg(feature = "val")] +pub mod shared; pub mod val; - -#[cfg(feature = "as")] -pub mod assembler; diff --git a/spirv-tools-sys/src/opt.rs b/spirv-tools-sys/src/opt.rs index 5e71609ddd..4b7080a8f7 100644 --- a/spirv-tools-sys/src/opt.rs +++ b/spirv-tools-sys/src/opt.rs @@ -499,18 +499,6 @@ pub enum Passes { AmdExtToKhr, } -#[derive(Copy, Clone, Debug, PartialEq)] -#[repr(C)] -pub enum RunResult { - InvalidInputBuffer, - InvalidInputSize, - InvalidOutputBuffer, - InvalidOutputSize, - InvalidCallback, - OptimizerFailed, - OptimizerSucceeded, -} - extern "C" { pub fn optimizer_create(env: crate::shared::TargetEnv) -> *mut Optimizer; pub fn optimizer_destroy(opt: *mut Optimizer); @@ -519,10 +507,11 @@ extern "C" { opt: *const Optimizer, input_ptr: *const u32, input_size: usize, - callback: extern "C" fn(*const u32, usize, *mut std::ffi::c_void), - ctx: *mut std::ffi::c_void, + binary: *mut *mut crate::shared::Binary, + message_callback: crate::diagnostics::MessageCallback, + message_ctx: *mut std::ffi::c_void, options: *const OptimizerOptions, - ) -> RunResult; + ) -> crate::shared::SpirvResult; /// Creates an optimizer options object with default options. Returns a valid /// options object. The object remains valid until it is passed into diff --git a/spirv-tools-sys/src/shared.rs b/spirv-tools-sys/src/shared.rs index 7300cee584..89f1af0495 100644 --- a/spirv-tools-sys/src/shared.rs +++ b/spirv-tools-sys/src/shared.rs @@ -202,27 +202,17 @@ impl fmt::Display for SpirvResult { impl std::error::Error for SpirvResult {} -#[cfg(feature = "tools")] #[repr(C)] -pub struct ToolContext { - _unused: [u8; 0], +pub struct Binary { + pub code: *const u32, + pub size: usize, } #[repr(C)] -pub struct Position { - pub line: usize, - pub column: usize, - pub index: usize, -} - -#[repr(C)] -pub struct Diagnostic { - pub position: Position, - pub error: *const std::os::raw::c_char, - pub is_text_source: bool, +pub struct ToolContext { + _unused: [u8; 0], } -#[cfg(feature = "tools")] extern "C" { /// Creates a context object for most of the SPIRV-Tools API. /// Returns null if env is invalid. @@ -235,8 +225,8 @@ extern "C" { #[link_name = "spvContextDestroy"] pub fn context_destroy(opt: *mut ToolContext); - /// Destroys a diagnostic object. This is a no-op if diagnostic is a null + /// Frees a binary stream from memory. This is a no-op if binary is a null /// pointer. - #[link_name = "spvDiagnosticDestroy"] - pub fn diagnostic_destroy(diag: *mut Diagnostic); + #[link_name = "spvBinaryDestroy"] + pub fn binary_destroy(binary: *mut Binary); } diff --git a/spirv-tools-sys/src/val.rs b/spirv-tools-sys/src/val.rs index a2af83c108..f82b35d033 100644 --- a/spirv-tools-sys/src/val.rs +++ b/spirv-tools-sys/src/val.rs @@ -29,7 +29,7 @@ extern "C" { binary: *const u32, size: usize, options: *const ValidatorOptions, - diagnostic: *mut *mut shared::Diagnostic, + diagnostic: *mut *mut crate::diagnostics::Diagnostic, ) -> crate::shared::SpirvResult; /// Creates a Validator options object with default options. Returns a valid diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index 0e2ad9f088..096b868115 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -6,9 +6,7 @@ edition = "2018" license = "MIT OR Apache-2.0" [features] -as = ["spirv-tools-sys/as"] -opt = ["spirv-tools-sys/opt"] -val = ["spirv-tools-sys/val"] +use-installed = ["spirv-tools-sys/use-installed"] [dependencies] spirv-tools-sys = { path = "../spirv-tools-sys" } @@ -18,4 +16,3 @@ structopt = "0.3" [[example]] name = "as" -required-features = ["as"] diff --git a/spirv-tools/src/assembler.rs b/spirv-tools/src/assembler.rs index cb1aa59f40..3d67d9edfc 100644 --- a/spirv-tools/src/assembler.rs +++ b/spirv-tools/src/assembler.rs @@ -1,34 +1,5 @@ use spirv_tools_sys::{assembler, shared}; -pub struct Binary { - inner: *mut assembler::Binary, -} - -impl AsRef<[u32]> for Binary { - fn as_ref(&self) -> &[u32] { - unsafe { std::slice::from_raw_parts((*self.inner).code, (*self.inner).size) } - } -} - -impl AsRef<[u8]> for Binary { - fn as_ref(&self) -> &[u8] { - unsafe { - std::slice::from_raw_parts( - (*self.inner).code as *const u8, - (*self.inner).size * std::mem::size_of::(), - ) - } - } -} - -impl Drop for Binary { - fn drop(&mut self) { - unsafe { - assembler::binary_destroy(self.inner); - } - } -} - #[derive(Copy, Clone, Default)] pub struct AssemblerOptions { /// Numeric IDs in the binary will have the same values as in the source. @@ -66,7 +37,7 @@ impl Assembler { &self, text: &str, options: AssemblerOptions, - ) -> Result { + ) -> Result { unsafe { let mut binary = std::ptr::null_mut(); let mut diagnostic = std::ptr::null_mut(); @@ -99,7 +70,7 @@ impl Assembler { }); } - Ok(Binary { inner: binary }) + Ok(crate::shared::Binary::new(binary)) } other => Err(crate::error::Error { inner: other, diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs index f7c91db16f..6413ecc4dd 100644 --- a/spirv-tools/src/error.rs +++ b/spirv-tools/src/error.rs @@ -1,4 +1,6 @@ -use spirv_tools_sys::shared; +use spirv_tools_sys::{diagnostics, shared}; + +pub use diagnostics::MessageLevel; #[derive(Debug, PartialEq)] pub struct Error { @@ -35,11 +37,11 @@ pub struct Diagnostic { pub is_text: bool, } -impl std::convert::TryFrom<*mut shared::Diagnostic> for Diagnostic { +impl std::convert::TryFrom<*mut diagnostics::Diagnostic> for Diagnostic { type Error = shared::SpirvResult; #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn try_from(diag: *mut shared::Diagnostic) -> Result { + fn try_from(diag: *mut diagnostics::Diagnostic) -> Result { unsafe { if diag.is_null() { return Err(shared::SpirvResult::Success); @@ -57,8 +59,67 @@ impl std::convert::TryFrom<*mut shared::Diagnostic> for Diagnostic { is_text: (*diag).is_text_source, }; - shared::diagnostic_destroy(diag); + diagnostics::diagnostic_destroy(diag); Ok(res) } } } + +pub struct Message<'a> { + pub level: MessageLevel, + pub source: std::borrow::Cow<'a, str>, + pub line: usize, + pub column: usize, + pub index: usize, + pub message: std::borrow::Cow<'a, str>, +} + +impl<'a> Message<'a> { + pub(crate) fn from_parts( + level: MessageLevel, + source: *const std::os::raw::c_char, + source_pos: *const diagnostics::Position, + msg: *const std::os::raw::c_char, + ) -> Self { + unsafe { + let source = std::ffi::CStr::from_ptr(source).to_string_lossy(); + let message = std::ffi::CStr::from_ptr(msg).to_string_lossy(); + + let (line, column, index) = if source_pos.is_null() { + (0, 0, 0) + } else { + ( + (*source_pos).line, + (*source_pos).column, + (*source_pos).index, + ) + }; + + Self { + level, + source, + line, + column, + index, + message, + } + } + } + + pub(crate) fn parse(_s: &str) -> Self { + unimplemented!() + } +} + +pub trait MessageCallback { + fn on_message(&mut self, msg: Message<'_>); +} + +impl MessageCallback for F +where + F: FnMut(Message<'_>), +{ + fn on_message(&mut self, msg: Message<'_>) { + self(msg) + } +} diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index d870927dfa..99e923dcb4 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -1,18 +1,9 @@ -#[cfg(feature = "opt")] +pub mod assembler; pub mod opt; -#[cfg(feature = "val")] +pub mod shared; pub mod val; -#[cfg(feature = "as")] -pub mod assembler; - -pub use spirv_tools_sys::shared; - pub mod error; - pub use error::Error; -/// Gets the default target environment, currently Universal_1_5 -pub fn default_target_env() -> shared::TargetEnv { - shared::TargetEnv::default() -} +pub use spirv_tools_sys::shared::TargetEnv; diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index 443f93fe87..e79cc98e5a 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -1,161 +1,27 @@ -mod options; - -use spirv_tools_sys::opt; - -pub use opt::{Passes, RunResult}; -pub use options::Options; - -pub trait OptimizeCallback { - fn optimized(&mut self, data: &[u32]); -} - -impl OptimizeCallback for F -where - F: FnMut(&[u32]), -{ - fn optimized(&mut self, data: &[u32]) { - self(data) - } -} - -pub struct Optimizer { - inner: *mut opt::Optimizer, -} - -impl Optimizer { - #[inline] - pub fn new(target: spirv_tools_sys::shared::TargetEnv) -> Self { - Self { - inner: unsafe { opt::optimizer_create(target) }, - } - } - - #[inline] - pub fn optimize( - &self, - input: &[u32], - oc: &mut F, - options: Option<&Options>, - ) -> Result<(), RunResult> { - unsafe { - struct Ctx<'a> { - cb: &'a mut dyn OptimizeCallback, - } - - let mut ctx = Ctx { cb: oc }; - - let cb_ctx: *mut std::ffi::c_void = std::mem::transmute(&mut ctx); - - extern "C" fn callback(data: *const u32, len: usize, ctx: *mut std::ffi::c_void) { - unsafe { - let optimized_binary = std::slice::from_raw_parts(data, len); - let ctx: &mut Ctx<'_> = &mut *(ctx as *mut Ctx); - - ctx.cb.optimized(optimized_binary); - } - } - - let options = match options { - Some(opts) => opts.inner, - None => std::ptr::null(), - }; - - let result = opt::optimizer_run( - self.inner, - input.as_ptr(), - input.len(), - callback, - cb_ctx, - options, - ); - - if result != opt::RunResult::OptimizerSucceeded { - return Err(result); - } - } - - Ok(()) - } - - #[inline] - pub fn optimize_to_buffer( - &self, - input: &[u32], - options: Option<&Options>, - ) -> Result, RunResult> { - let mut buffer = None; - self.optimize( - input, - &mut |data: &[u32]| { - buffer = Some(data.to_vec()); - }, - options, - )?; - - buffer.ok_or(RunResult::OptimizerFailed) - } - - /// Register a single pass with the the optimizer. - #[inline] - pub fn register_pass(&mut self, pass: Passes) -> &mut Self { - unsafe { opt::optimizer_register_pass(self.inner, pass) } - self - } - - /// Registers passes that attempt to improve performance of generated code. - /// This sequence of passes is subject to constant review and will change - /// from time to time. - #[inline] - pub fn register_performance_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_performance_passes(self.inner) } - self - } - - /// Registers passes that attempt to improve the size of generated code. - /// This sequence of passes is subject to constant review and will change - /// from time to time. - #[inline] - pub fn register_size_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_size_passes(self.inner) } - self - } - - /// Registers passes that have been prescribed for converting from Vulkan to - /// WebGPU. This sequence of passes is subject to constant review and will - /// change from time to time. - #[inline] - pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_vulkan_to_webgpu_passes(self.inner) } - self - } - - /// Registers passes that have been prescribed for converting from WebGPU to - /// Vulkan. This sequence of passes is subject to constant review and will - /// change from time to time. - #[inline] - pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_webgpu_to_vulkan_passes(self.inner) } - self - } - - /// Registers passes that attempt to legalize the generated code. - /// - /// Note: this recipe is specially designed for legalizing SPIR-V. It should be - /// used by compilers after translating HLSL source code literally. It should - /// *not* be used by general workloads for performance or size improvement. - /// - /// This sequence of passes is subject to constant review and will change - /// from time to time. - #[inline] - pub fn register_legalization_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_legalization_passes(self.inner) } - self - } -} - -impl Drop for Optimizer { - #[inline] - fn drop(&mut self) { - unsafe { opt::optimizer_destroy(self.inner) } - } +#[cfg(not(feature = "use-installed"))] +mod compiled; +#[cfg(feature = "use-installed")] +mod tool; + +#[cfg(not(feature = "use-installed"))] +pub use compiled::Optimizer; + +#[cfg(feature = "use-installed")] +pub use tool::Optimizer; + +pub use spirv_tools_sys::opt::Passes; + +/// Options for specifying the behavior of the optimizer +#[derive(Default)] +pub struct Options { + /// Records the validator options that should be passed to the validator, + /// the validator will run with the options before optimizer. + pub validator_options: Option, + /// Records the maximum possible value for the id bound. + pub max_id_bound: Option, + /// Records whether all bindings within the module should be preserved. + pub preserve_bindings: bool, + /// Records whether all specialization constants within the module + /// should be preserved. + pub preserve_spec_constants: bool, } diff --git a/spirv-tools/src/opt/compiled.rs b/spirv-tools/src/opt/compiled.rs new file mode 100644 index 0000000000..1299279011 --- /dev/null +++ b/spirv-tools/src/opt/compiled.rs @@ -0,0 +1,205 @@ +use crate::error; +use spirv_tools_sys::opt; + +pub struct Options { + pub(crate) inner: *mut opt::OptimizerOptions, +} + +impl From for Options { + fn from(o: super::Options) -> Self { + unsafe { + let inner = opt::optimizer_options_create(); + + if let Some(vopts) = o.validator_options { + let vopts = crate::val::compiled::Options::from(vopts); + + opt::optimizer_options_run_validator(inner, true); + + // The validator options are copied, so it's fine to drop vopts + // after this call + opt::optimizer_options_set_validator_options(inner, vopts.inner); + } + + if let Some(max_bounds) = o.max_id_bounds { + opt::optimizer_options_set_max_id_bound(inner, max_bounds); + } + + if o.preserve_bindings { + opt::optimizer_options_preserve_bindings(inner, true); + } + + if o.preserve_spec_constants { + opt::optimizer_options_preserve_spec_constants(inner, true); + } + + Self { inner } + } + } +} + +impl Default for Options { + #[inline] + fn default() -> Self { + Self::new() + } +} + +impl Drop for Options { + #[inline] + fn drop(&mut self) { + unsafe { opt::optimizer_options_destroy(self.inner) } + } +} + +pub struct Optimizer { + inner: *mut opt::Optimizer, +} + +impl Optimizer { + #[inline] + pub fn new(target: crate::TargetEnv) -> Self { + Self { + inner: unsafe { opt::optimizer_create(target) }, + } + } + + #[inline] + pub fn optimize( + &self, + input: &[u32], + msg_callback: &mut MC, + options: Option, + ) -> Result { + unsafe { + struct Ctx<'a> { + cb: &'a mut dyn error::MessageCallback, + } + + let mut ctx = Ctx { cb: msg_callback }; + + let cb_ctx: *mut std::ffi::c_void = std::mem::transmute(&mut ctx); + + extern "C" fn callback( + level: spirv_tools_sys::diagnostics::MessageLevel, + source: *const std::os::raw::c_char, + source_pos: *const spirv_tools_sys::diagnostics::Position, + msg: *const std::os::raw::c_char, + ctx: *mut std::ffi::c_void, + ) { + unsafe { + let ctx: &mut Ctx<'_> = &mut *(ctx as *mut Ctx); + + let msg = error::Message::from_parts(level, source, source_pos, msg); + + ctx.cb.on_message(msg); + } + } + + let mut binary = std::ptr::null_mut(); + + let options = options.map(Options::from); + + let options = match options { + Some(opts) => opts.inner, + None => std::ptr::null(), + }; + + let res = opt::optimizer_run( + self.inner, + input.as_ptr(), + input.len(), + &mut binary, + callback, + cb_ctx, + options, + ); + + match res { + spirv_tools_sys::shared::SpirvResult::Success => { + if binary.is_null() { + return Err(error::Error { + inner: spirv_tools_sys::shared::SpirvResult::InternalError, + diagnostic: Some(crate::error::Diagnostic { + line: 0, + column: 0, + index: 0, + message: "spirv optimizer indicated success but did not return a valid binary".to_owned(), + is_text: false, + }), + }); + } + + Ok(crate::shared::Binary::new(binary)) + } + other => Err(error::Error { + inner: other, + diagnostic: None, + }), + } + } + } + + /// Register a single pass with the the optimizer. + #[inline] + pub fn register_pass(&mut self, pass: super::Passes) -> &mut Self { + unsafe { opt::optimizer_register_pass(self.inner, pass) } + self + } + + /// Registers passes that attempt to improve performance of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + pub fn register_performance_passes(&mut self) -> &mut Self { + unsafe { opt::optimizer_register_performance_passes(self.inner) } + self + } + + /// Registers passes that attempt to improve the size of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + pub fn register_size_passes(&mut self) -> &mut Self { + unsafe { opt::optimizer_register_size_passes(self.inner) } + self + } + + /// Registers passes that have been prescribed for converting from Vulkan to + /// WebGPU. This sequence of passes is subject to constant review and will + /// change from time to time. + #[inline] + pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self { + unsafe { opt::optimizer_register_vulkan_to_webgpu_passes(self.inner) } + self + } + + /// Registers passes that have been prescribed for converting from WebGPU to + /// Vulkan. This sequence of passes is subject to constant review and will + /// change from time to time. + #[inline] + pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self { + unsafe { opt::optimizer_register_webgpu_to_vulkan_passes(self.inner) } + self + } + + /// Registers passes that attempt to legalize the generated code. + /// + /// Note: this recipe is specially designed for legalizing SPIR-V. It should be + /// used by compilers after translating HLSL source code literally. It should + /// *not* be used by general workloads for performance or size improvement. + /// + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + pub fn register_legalization_passes(&mut self) -> &mut Self { + unsafe { opt::optimizer_register_legalization_passes(self.inner) } + self + } +} + +impl Drop for Optimizer { + #[inline] + fn drop(&mut self) { + unsafe { opt::optimizer_destroy(self.inner) } + } +} diff --git a/spirv-tools/src/opt/options.rs b/spirv-tools/src/opt/options.rs deleted file mode 100644 index da9b0f2066..0000000000 --- a/spirv-tools/src/opt/options.rs +++ /dev/null @@ -1,48 +0,0 @@ -use spirv_tools_sys::opt; - -pub struct Options { - pub(crate) inner: *mut opt::OptimizerOptions, -} - -impl Options { - #[inline] - pub fn new() -> Self { - Self { - inner: unsafe { opt::optimizer_options_create() }, - } - } - - #[inline] - pub fn run_validator(&mut self, toggle: bool) { - unsafe { opt::optimizer_options_run_validator(self.inner, toggle) } - } - - #[inline] - pub fn set_max_id_bounds(&mut self, max: u32) { - unsafe { opt::optimizer_options_set_max_id_bound(self.inner, max) } - } - - #[inline] - pub fn preserve_bindings(&mut self, toggle: bool) { - unsafe { opt::optimizer_options_preserve_bindings(self.inner, toggle) } - } - - #[inline] - pub fn preserve_spec_constants(&mut self, toggle: bool) { - unsafe { opt::optimizer_options_preserve_spec_constants(self.inner, toggle) } - } -} - -impl Default for Options { - #[inline] - fn default() -> Self { - Self::new() - } -} - -impl Drop for Options { - #[inline] - fn drop(&mut self) { - unsafe { opt::optimizer_options_destroy(self.inner) } - } -} diff --git a/spirv-tools/src/opt/tool.rs b/spirv-tools/src/opt/tool.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spirv-tools/src/shared.rs b/spirv-tools/src/shared.rs new file mode 100644 index 0000000000..44e3b9c83f --- /dev/null +++ b/spirv-tools/src/shared.rs @@ -0,0 +1,36 @@ +use spirv_tools_sys::shared; + +pub struct Binary { + inner: *mut shared::Binary, +} + +impl Binary { + pub(crate) fn new(bin: *mut shared::Binary) -> Self { + Self { inner: bin } + } +} + +impl AsRef<[u32]> for Binary { + fn as_ref(&self) -> &[u32] { + unsafe { std::slice::from_raw_parts((*self.inner).code, (*self.inner).size) } + } +} + +impl AsRef<[u8]> for Binary { + fn as_ref(&self) -> &[u8] { + unsafe { + std::slice::from_raw_parts( + (*self.inner).code as *const u8, + (*self.inner).size * std::mem::size_of::(), + ) + } + } +} + +impl Drop for Binary { + fn drop(&mut self) { + unsafe { + shared::binary_destroy(self.inner); + } + } +} diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index 87b16da783..dbb24dfc4a 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -133,49 +133,3 @@ impl Drop for ValidatorOptions { unsafe { val::validator_options_destroy(self.inner) } } } - -pub struct Validator { - inner: *mut shared::ToolContext, -} - -impl Validator { - pub fn new(target_env: shared::TargetEnv) -> Self { - Self { - inner: unsafe { shared::context_create(target_env) }, - } - } - - pub fn validate( - &self, - binary: &[u32], - options: &ValidatorOptions, - ) -> Result<(), crate::error::Error> { - unsafe { - let mut diagnostic = std::ptr::null_mut(); - let res = val::validate( - self.inner, - binary.as_ptr(), - binary.len(), - options.inner, - &mut diagnostic, - ); - - use std::convert::TryFrom; - let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok(); - - match res { - shared::SpirvResult::Success => Ok(()), - other => Err(crate::error::Error { - inner: other, - diagnostic, - }), - } - } - } -} - -impl Drop for Validator { - fn drop(&mut self) { - unsafe { shared::context_destroy(self.inner) } - } -} diff --git a/spirv-tools/src/val/compiled.rs b/spirv-tools/src/val/compiled.rs new file mode 100644 index 0000000000..e062690198 --- /dev/null +++ b/spirv-tools/src/val/compiled.rs @@ -0,0 +1,45 @@ +pub struct Validator { + inner: *mut shared::ToolContext, +} + +impl Validator { + pub fn new(target_env: shared::TargetEnv) -> Self { + Self { + inner: unsafe { shared::context_create(target_env) }, + } + } + + pub fn validate( + &self, + binary: &[u32], + options: &ValidatorOptions, + ) -> Result<(), crate::error::Error> { + unsafe { + let mut diagnostic = std::ptr::null_mut(); + let res = val::validate( + self.inner, + binary.as_ptr(), + binary.len(), + options.inner, + &mut diagnostic, + ); + + use std::convert::TryFrom; + let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok(); + + match res { + shared::SpirvResult::Success => Ok(()), + other => Err(crate::error::Error { + inner: other, + diagnostic, + }), + } + } + } +} + +impl Drop for Validator { + fn drop(&mut self) { + unsafe { shared::context_destroy(self.inner) } + } +} From be90051e38976dcc408f73a710e18329a89effc2 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Mon, 26 Oct 2020 18:37:14 +0100 Subject: [PATCH 20/41] Checkpointing --- spirv-tools/src/error.rs | 29 ++++++++++- spirv-tools/src/opt.rs | 2 +- spirv-tools/src/opt/compiled.rs | 11 +---- spirv-tools/src/val.rs | 88 ++++++--------------------------- spirv-tools/src/val/compiled.rs | 70 +++++++++++++++++++++++++- spirv-tools/src/val/tool.rs | 38 ++++++++++++++ 6 files changed, 151 insertions(+), 87 deletions(-) create mode 100644 spirv-tools/src/val/tool.rs diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs index 6413ecc4dd..b3ad2ab112 100644 --- a/spirv-tools/src/error.rs +++ b/spirv-tools/src/error.rs @@ -106,8 +106,33 @@ impl<'a> Message<'a> { } } - pub(crate) fn parse(_s: &str) -> Self { - unimplemented!() + pub(crate) fn parse(s: &'a str) -> Option { + s.find(": ") + .and_then(|i| { + let level = match &s[..i] { + "error" => MessageLevel::Error, + "warning" => MessageLevel::Warning, + "info" => MessageLevel::Info, + _ => return None, + }; + + Some((level, i)) + }).and_then(|(level, i)| { + s[i + 7..].find(": ").and_then(|i2| { + s[i + 7..i + 7 + i2].parse::().ok().map(|index| (index, i2)) + }).map(|(index, i2)| { + (level, index, i + 7 + i2 + 2) + }) + }).map(|(level, index, last)| { + Self { + level, + index, + message: std::borrow::Cow::Borrowed(&s[last..]), + source: std::borrow::Cow::Borrowed(""), + line: 0, + column: 0, + } + }) } } diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index e79cc98e5a..8bf4321fed 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -12,7 +12,7 @@ pub use tool::Optimizer; pub use spirv_tools_sys::opt::Passes; /// Options for specifying the behavior of the optimizer -#[derive(Default)] +#[derive(Default, Clone)] pub struct Options { /// Records the validator options that should be passed to the validator, /// the validator will run with the options before optimizer. diff --git a/spirv-tools/src/opt/compiled.rs b/spirv-tools/src/opt/compiled.rs index 1299279011..298df24501 100644 --- a/spirv-tools/src/opt/compiled.rs +++ b/spirv-tools/src/opt/compiled.rs @@ -20,8 +20,8 @@ impl From for Options { opt::optimizer_options_set_validator_options(inner, vopts.inner); } - if let Some(max_bounds) = o.max_id_bounds { - opt::optimizer_options_set_max_id_bound(inner, max_bounds); + if let Some(max_bound) = o.max_id_bound { + opt::optimizer_options_set_max_id_bound(inner, max_bound); } if o.preserve_bindings { @@ -37,13 +37,6 @@ impl From for Options { } } -impl Default for Options { - #[inline] - fn default() -> Self { - Self::new() - } -} - impl Drop for Options { #[inline] fn drop(&mut self) { diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index dbb24dfc4a..d47d10b901 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -1,6 +1,16 @@ -use spirv_tools_sys::{shared, val}; +#[cfg(not(feature = "use-installed"))] +pub(crate) mod compiled; +#[cfg(feature = "use-installed")] +mod tool; -pub struct ValidatorOptsBuilder { +#[cfg(not(feature = "use-installed"))] +pub use compiled::Validator; + +#[cfg(feature = "use-installed")] +pub use tool::Optimizer; + +#[derive(Default, Clone)] +pub struct ValidatorOptions { /// Record whether or not the validator should relax the rules on types for /// stores to structs. When relaxed, it will allow a type mismatch as long as /// the types are structs with the same layout. Two structs have the same layout @@ -38,7 +48,7 @@ pub struct ValidatorOptsBuilder { /// /// This is enabled by default when targeting Vulkan 1.1 or later. /// Relaxed layout is more permissive than the default rules in Vulkan 1.0. - pub relax_block_layout: bool, + pub relax_block_layout: Option, /// Records whether the validator should use standard block layout rules for /// uniform blocks. pub uniform_buffer_standard_layout: bool, @@ -62,74 +72,6 @@ pub struct ValidatorOptsBuilder { /// Records whether or not the validator should skip validating standard /// uniform/storage block layout. pub skip_block_layout: bool, -} - -impl ValidatorOptsBuilder { - pub fn into_opts(self) -> ValidatorOptions { - self.into_opts_with_limits(std::iter::empty()) - } - - pub fn into_opts_with_limits( - self, - limits: impl Iterator, - ) -> ValidatorOptions { - unsafe { - let vopts = val::validator_options_create(); - - // AFAICT this is the only one that _may_ default to true, so - // we always set it - val::validator_options_set_relax_block_layout(vopts, self.relax_block_layout); - - if self.relax_store_struct { - val::validator_options_set_relax_store_struct(vopts, self.relax_store_struct); - } - - if self.relax_logical_pointer { - val::validator_options_set_relax_logical_pointer(vopts, self.relax_logical_pointer); - } - - if self.before_legalization { - val::validator_options_set_before_legalization(vopts, self.before_legalization); - } - - if self.uniform_buffer_standard_layout { - val::validator_options_set_uniform_buffer_standard_layout( - vopts, - self.uniform_buffer_standard_layout, - ); - } - - if self.scalar_block_layout { - val::validator_options_set_scalar_block_layout(vopts, self.scalar_block_layout); - } - - if self.skip_block_layout { - val::validator_options_set_skip_block_layout(vopts, self.skip_block_layout); - } - - for (limit, val) in limits { - val::validator_options_set_limit(vopts, limit, val); - } - - ValidatorOptions { inner: vopts } - } - } -} - -pub struct ValidatorOptions { - inner: *mut val::ValidatorOptions, -} - -impl Default for ValidatorOptions { - fn default() -> Self { - Self { - inner: unsafe { val::validator_options_create() }, - } - } -} - -impl Drop for ValidatorOptions { - fn drop(&mut self) { - unsafe { val::validator_options_destroy(self.inner) } - } + /// Applies a maximum to one or more Universal limits + pub max_limits: Vec<(spirv_tools_sys::val::ValidatorLimits, u32)>, } diff --git a/spirv-tools/src/val/compiled.rs b/spirv-tools/src/val/compiled.rs index e062690198..375089fe40 100644 --- a/spirv-tools/src/val/compiled.rs +++ b/spirv-tools/src/val/compiled.rs @@ -1,3 +1,61 @@ +use spirv_tools_sys::{shared, val}; + +pub struct Options { + pub(crate) inner: *mut val::ValidatorOptions, +} + +impl From for Options { + fn from(vo: super::ValidatorOptions) -> Self { + unsafe { + let inner = val::validator_options_create(); + + // This is AFAICT the only one that _can_ default to true based on our target + // so we treat it differently + if let Some(relax) = vo.relax_block_layout { + val::validator_options_set_relax_block_layout(inner, relax); + } + + if vo.relax_store_struct { + val::validator_options_set_relax_store_struct(inner, true); + } + + if vo.relax_logical_pointer { + val::validator_options_set_relax_logical_pointer(inner, true); + } + + if vo.before_legalization { + val::validator_options_set_before_legalization(inner, true); + } + + if vo.uniform_buffer_standard_layout { + val::validator_options_set_uniform_buffer_standard_layout(inner, true); + } + + if vo.scalar_block_layout { + val::validator_options_set_scalar_block_layout(inner, true); + } + + if vo.skip_block_layout { + val::validator_options_set_skip_block_layout(inner, true); + } + + for (limit, val) in vo.max_limits { + val::validator_options_set_limit(inner, limit, val); + } + + Self { + inner + } + } + } +} + +impl Drop for Options { + fn drop(&mut self) { + unsafe { val::validator_options_destroy(self.inner) } + } +} + pub struct Validator { inner: *mut shared::ToolContext, } @@ -12,15 +70,23 @@ impl Validator { pub fn validate( &self, binary: &[u32], - options: &ValidatorOptions, + options: Option, ) -> Result<(), crate::error::Error> { unsafe { let mut diagnostic = std::ptr::null_mut(); + + let options = options.map(Options::from); + + let options = match options { + Some(opts) => opts.inner, + None => std::ptr::null(), + }; + let res = val::validate( self.inner, binary.as_ptr(), binary.len(), - options.inner, + options, &mut diagnostic, ); diff --git a/spirv-tools/src/val/tool.rs b/spirv-tools/src/val/tool.rs new file mode 100644 index 0000000000..a6d2220fd7 --- /dev/null +++ b/spirv-tools/src/val/tool.rs @@ -0,0 +1,38 @@ + +pub struct Validator { + target_env: crate::TargetEnv, +} + +impl Validator { + pub fn new(target_env: crate::TargetEnv) -> Self { + Self { + target_env, + } + } + + pub fn validate( + &self, + binary: &[u32], + options: Option, + ) -> Result<(), crate::error::Error> { + use std::process::Command; + + + let mut cmd = Command::new("spirv-val"); + + cmd.arg("--target-env") + .arg(self.target_env.to_string()); + + if let Some(opts) = options { + + } + + cmd.status() + } +} + +impl Drop for Validator { + fn drop(&mut self) { + unsafe { shared::context_destroy(self.inner) } + } +} From e10885231ce7f9f044eeaab95cd3da221ff89fb8 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 28 Oct 2020 10:09:56 +0100 Subject: [PATCH 21/41] Checkpoint --- Cargo.lock | 1 + rustc_codegen_spirv/src/link.rs | 7 +- spirv-tools-sys/src/val.rs | 18 ++-- spirv-tools/Cargo.toml | 4 +- spirv-tools/src/assembler.rs | 6 +- spirv-tools/src/cmd.rs | 170 ++++++++++++++++++++++++++++++++ spirv-tools/src/error.rs | 71 ++++++++----- spirv-tools/src/lib.rs | 5 + spirv-tools/src/util.rs | 24 +++++ spirv-tools/src/val.rs | 2 +- spirv-tools/src/val/compiled.rs | 6 +- spirv-tools/src/val/tool.rs | 69 ++++++++++--- 12 files changed, 323 insertions(+), 60 deletions(-) create mode 100644 spirv-tools/src/cmd.rs create mode 100644 spirv-tools/src/util.rs diff --git a/Cargo.lock b/Cargo.lock index f49a5e4a22..bd1ea53e67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2204,6 +2204,7 @@ version = "0.1.0" name = "spirv-tools" version = "0.1.0" dependencies = [ + "memchr", "spirv-tools-sys", "structopt", ] diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 30db113f57..489cf86055 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -187,7 +187,7 @@ fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec binary.as_ref().to_vec(), + Ok(binary) => Vec::from(binary.as_ref()), Err(_) => { let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); err.note(&format!("module {:?}", filename)); @@ -197,12 +197,11 @@ fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec Err(crate::error::Error { inner: other, - diagnostic, + diagnostics: vec![diagnostic], }), } } diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs new file mode 100644 index 0000000000..f830148bbe --- /dev/null +++ b/spirv-tools/src/cmd.rs @@ -0,0 +1,170 @@ +use crate::error::Diagnostic; +use std::process::{Command, Stdio}; + +pub enum CmdError { + /// The binary failed to spawn, probably because it's not installed + /// or not in PATH + BinaryNotFound(std::io::Error), + /// An I/O error occurred accessing the process' pipes + Io(std::io::Error), + /// The binary ran, but returned a non-zero exit code and (hopefully) + /// diagnostics + ToolErrors { + exit_code: i32, + /// Diagnostics that were parsed from the output + diagnostics: Vec, + }, +} + +impl From for crate::error::Error { + fn from(ce: CmdError) -> Self {} +} + +pub struct CmdOutput { + /// The output the command is actually supposed to give back + pub binary: Vec, + /// Warning or Info level diagnostics that were gathered during execution + pub diagnostics: Vec, +} + +#[derive(PartialEq, Copy, Clone)] +pub enum Output { + /// Doesn't try to read stdout for tool output (other than diagnostics) + Ignore, + /// Attempts to retrieve the tool's output from stdout + Retrieve, +} + +pub fn exec( + cmd: Command, + input: Option<&[u8]>, + retrieve_output: Output, +) -> Result { + if input.is_some() { + cmd.stdin(Stdio::piped()); + } + + cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); + + let mut child = cmd.spawn().map_err(|e| CmdError::BinaryNotFound(e))?; + + if let Some(input) = input { + use std::io::Write; + + child + .stdin + .take() + .unwrap() + .write_all(input) + .map_err(|e| CmdError::Io(e))?; + } + + let output = child.wait_with_output().map_err(|e| CmdError::Io(e))?; + + let code = match output.status.code() { + Some(code) => code, + None => { + #[cfg(unix)] + let message = { + use std::os::unix::process::ExitStatusExt; + format!( + "process terminated by signal: {}", + output.status.signal().unwrap_or(666) + ) + }; + #[cfg(not(unix))] + let message = "process ended in an unknown state".to_owned(); + + return Err(CmdError::ToolErrors { + exit_code: -1, + diagnostics: vec![Diagnostic { + line: 0, + column: 0, + index: 0, + message, + is_text: false, + }], + }); + } + }; + + // stderr should only ever contain error+ level diagnostics + if code != 0 { + let diagnostics: Vec<_> = match String::from_utf8(output.stderr) { + Ok(errors) => errors + .lines() + .filter_map(|line| crate::error::Message::parse(line).map(Diagnostic::from)) + .collect(), + Err(e) => vec![Diagnostic { + line: 0, + column: 0, + index: 0, + message: format!( + "unable to read stderr ({}) but process exited with code {}", + e, code + ), + is_text: false, + }], + }; + + return Err(CmdError::ToolErrors { + exit_code: code, + diagnostics, + }); + } + + fn split<'a>(haystack: &'a [u8], needle: u8) -> impl Iterator + 'a { + struct Split<'a> { + haystack: &'a [u8], + needle: u8, + } + + impl<'a> Iterator for Split<'a> { + type Item = &'a [u8]; + + fn next(&mut self) -> Option<&'a [u8]> { + if self.haystack.is_empty() { + return None; + } + let (ret, remaining) = match memchr::memchr(self.needle, self.haystack) { + Some(pos) => (&self.haystack[..pos], &self.haystack[pos + 1..]), + None => (self.haystack, &[][..]), + }; + self.haystack = remaining; + Some(ret) + } + } + + Split { haystack, needle } + } + + let retrieve_output = retrieve_output == Output::Retrieve; + + // Since we are retrieving the results via stdout, but it can also contain + // diagnostic messages, we need to be careful + let mut diagnostics = Vec::new(); + let mut binary = Vec::with_capacity(if retrieve_output { 1024 } else { 0 }); + + let mut iter = split(&output.stdout, b'\n'); + let mut maybe_diagnostic = true; + for line in iter { + if maybe_diagnostic { + if let Some(s) = std::str::from_utf8(line).ok() { + if let Some(msg) = crate::error::Message::parse(s) { + diagnostics.push(Diagnostic::from(msg)); + continue; + } + } + } + + if retrieve_output { + binary.extend_from_slice(line); + } + maybe_diagnostic = false; + } + + Ok(CmdOutput { + binary, + diagnostics, + }) +} diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs index b3ad2ab112..d38b9bfcb7 100644 --- a/spirv-tools/src/error.rs +++ b/spirv-tools/src/error.rs @@ -5,20 +5,25 @@ pub use diagnostics::MessageLevel; #[derive(Debug, PartialEq)] pub struct Error { pub inner: shared::SpirvResult, - pub diagnostic: Option, + pub diagnostics: Vec, } use std::fmt; impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.diagnostic { - Some(diag) => f.write_fmt(format_args!( - "{}:{}:{} - {}", - self.inner, diag.line, diag.column, diag.message - )), - None => f.write_fmt(format_args!("{}", self.inner)), + f.write_fmt(format_args!("{}", self.inner))?; + + if !self.diagnostics.is_empty() { + for diag in &self.diagnostics { + f.write_fmt(format_args!( + "\n{}:{}:{} - {}", + self.inner, diag.line, diag.column, diag.message + ))? + } } + + Ok(()) } } @@ -65,6 +70,18 @@ impl std::convert::TryFrom<*mut diagnostics::Diagnostic> for Diagnostic { } } +impl<'a> From> for Diagnostic { + fn from(msg: Message<'a>) -> Self { + Self { + line: msg.line, + column: msg.column, + index: msg.index, + message: msg.message.to_string(), + is_text: false, + } + } +} + pub struct Message<'a> { pub level: MessageLevel, pub source: std::borrow::Cow<'a, str>, @@ -108,31 +125,35 @@ impl<'a> Message<'a> { pub(crate) fn parse(s: &'a str) -> Option { s.find(": ") - .and_then(|i| { - let level = match &s[..i] { - "error" => MessageLevel::Error, - "warning" => MessageLevel::Warning, - "info" => MessageLevel::Info, - _ => return None, - }; - - Some((level, i)) - }).and_then(|(level, i)| { - s[i + 7..].find(": ").and_then(|i2| { - s[i + 7..i + 7 + i2].parse::().ok().map(|index| (index, i2)) - }).map(|(index, i2)| { - (level, index, i + 7 + i2 + 2) + .and_then(|i| { + let level = match &s[..i] { + "error" => MessageLevel::Error, + "warning" => MessageLevel::Warning, + "info" => MessageLevel::Info, + _ => return None, + }; + + Some((level, i)) }) - }).map(|(level, index, last)| { - Self { + .and_then(|(level, i)| { + s[i + 7..] + .find(": ") + .and_then(|i2| { + s[i + 7..i + 7 + i2] + .parse::() + .ok() + .map(|index| (index, i2)) + }) + .map(|(index, i2)| (level, index, i + 7 + i2 + 2)) + }) + .map(|(level, index, last)| Self { level, index, message: std::borrow::Cow::Borrowed(&s[last..]), source: std::borrow::Cow::Borrowed(""), line: 0, column: 0, - } - }) + }) } } diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index 99e923dcb4..740d145b00 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -7,3 +7,8 @@ pub mod error; pub use error::Error; pub use spirv_tools_sys::shared::TargetEnv; + +#[cfg(feature = "use-installed")] +pub(crate) mod cmd; + +pub mod util; diff --git a/spirv-tools/src/util.rs b/spirv-tools/src/util.rs new file mode 100644 index 0000000000..fa3dfb5572 --- /dev/null +++ b/spirv-tools/src/util.rs @@ -0,0 +1,24 @@ +pub fn from_binary(bin: &[u32]) -> &[u8] { + unsafe { + std::slice::from_raw_parts( + bin.as_ptr() as *const u8, + bin.len() * std::mem::size_of::(), + ) + } +} + +pub fn to_binary(bytes: &[u8]) -> Result<&[u32], crate::Error> { + if bytes.len() % std::mem::size_of::() != 0 { + return Err(crate::Error { + inner: spirv_tools_sys::shared::SpirvResult::InvalidBinary, + diagnostics: vec![], + }); + } + + Ok(unsafe { + std::slice::from_raw_parts( + bytes.as_ptr() as *const u32, + bytes.len() / std::mem::size_of::(), + ) + }) +} diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index d47d10b901..ea969ad5b4 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -21,7 +21,7 @@ pub struct ValidatorOptions { /// /// 2) the decorations that affect the memory layout are identical for both /// types. Other decorations are not relevant. - pub relax_store_struct: bool, + pub relax_struct_store: bool, /// Records whether or not the validator should relax the rules on pointer usage /// in logical addressing mode. /// diff --git a/spirv-tools/src/val/compiled.rs b/spirv-tools/src/val/compiled.rs index 375089fe40..ffd3721463 100644 --- a/spirv-tools/src/val/compiled.rs +++ b/spirv-tools/src/val/compiled.rs @@ -43,9 +43,7 @@ impl From for Options { val::validator_options_set_limit(inner, limit, val); } - Self { - inner - } + Self { inner } } } } @@ -97,7 +95,7 @@ impl Validator { shared::SpirvResult::Success => Ok(()), other => Err(crate::error::Error { inner: other, - diagnostic, + diagnostics: vec![diagnostic], }), } } diff --git a/spirv-tools/src/val/tool.rs b/spirv-tools/src/val/tool.rs index a6d2220fd7..cbd570440d 100644 --- a/spirv-tools/src/val/tool.rs +++ b/spirv-tools/src/val/tool.rs @@ -1,3 +1,4 @@ +use std::process::Command; pub struct Validator { target_env: crate::TargetEnv, @@ -5,9 +6,7 @@ pub struct Validator { impl Validator { pub fn new(target_env: crate::TargetEnv) -> Self { - Self { - target_env, - } + Self { target_env } } pub fn validate( @@ -15,24 +14,68 @@ impl Validator { binary: &[u32], options: Option, ) -> Result<(), crate::error::Error> { - use std::process::Command; - - let mut cmd = Command::new("spirv-val"); - - cmd.arg("--target-env") - .arg(self.target_env.to_string()); + + cmd.arg("--target-env").arg(self.target_env.to_string()); if let Some(opts) = options { + if opts.relax_logical_pointer { + cmd.arg("--relax-logical-pointer"); + } + + if let Some(true) = opts.relax_block_layout { + cmd.arg("--relax-block-layout"); + } + + if opts.uniform_buffer_standard_layout { + cmd.arg("--uniform-buffer-standard-layout"); + } + if opts.scalar_block_layout { + cmd.arg("--scalar-block-layout"); + } + + if opts.skip_block_layout { + cmd.arg("--skip-block-layout"); + } + + if opts.relax_struct_store { + cmd.arg("--relax-struct-store"); + } + + if opts.before_legalization { + cmd.arg("--before-hlsl-legalization"); + } + + add_limits(&mut cmd, &opts.max_limits); } - cmd.status() + let input = crate::util::from_binary(binary); + + crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Ignore)?; + Ok(()) } } -impl Drop for Validator { - fn drop(&mut self) { - unsafe { shared::context_destroy(self.inner) } +#[inline] +fn add_limits(cmd: &mut Command, limits: &[(spirv_tools_sys::val::ValidatorLimits, u32)]) { + use spirv_tools_sys::val::ValidatorLimits; + + for (limit, val) in limits { + cmd.arg(format!( + "--max-{}", + match limit { + ValidatorLimits::StructMembers => "struct-members", + ValidatorLimits::StructDepth => "struct-depth", + ValidatorLimits::LocalVariables => "local-variables", + ValidatorLimits::GlobalVariables => "global-variables", + ValidatorLimits::SwitchBranches => "switch-branches", + ValidatorLimits::FunctionArgs => "function-args", + ValidatorLimits::ControlFlowNestingDepth => "control-flow-nesting-depth", + ValidatorLimits::AccessChainIndexes => "access-chain-indexes", + ValidatorLimits::IdBound => "id-bound", + } + )) + .arg(val.to_string()); } } From 1ba0c895b400e9d2e0c2e7c3d0767dd9ab4263eb Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 28 Oct 2020 18:03:03 +0100 Subject: [PATCH 22/41] Boop --- rustc_codegen_spirv/Cargo.toml | 9 ++ rustc_codegen_spirv/src/link.rs | 12 +- spirv-tools-sys/Cargo.toml | 2 + spirv-tools-sys/build.rs | 2 +- spirv-tools-sys/src/c/opt.cpp | 2 +- spirv-tools-sys/src/opt.rs | 2 +- spirv-tools/Cargo.toml | 2 + spirv-tools/examples/as.rs | 6 +- spirv-tools/src/assembler.rs | 76 ++--------- spirv-tools/src/assembler/compiled.rs | 70 ++++++++++ spirv-tools/src/assembler/tool.rs | 39 ++++++ spirv-tools/src/binary.rs | 86 +++++++++++++ spirv-tools/src/cmd.rs | 85 +++++++----- spirv-tools/src/error.rs | 73 +++++++---- spirv-tools/src/lib.rs | 4 +- spirv-tools/src/opt.rs | 43 +++++-- spirv-tools/src/opt/compiled.rs | 48 ++++--- spirv-tools/src/opt/tool.rs | 178 ++++++++++++++++++++++++++ spirv-tools/src/shared.rs | 36 ------ spirv-tools/src/util.rs | 2 +- spirv-tools/src/val.rs | 21 +-- spirv-tools/src/val/compiled.rs | 22 +++- spirv-tools/src/val/tool.rs | 57 +++++---- 23 files changed, 629 insertions(+), 248 deletions(-) create mode 100644 spirv-tools/src/assembler/compiled.rs create mode 100644 spirv-tools/src/assembler/tool.rs create mode 100644 spirv-tools/src/binary.rs delete mode 100644 spirv-tools/src/shared.rs diff --git a/rustc_codegen_spirv/Cargo.toml b/rustc_codegen_spirv/Cargo.toml index 509758e09f..6c78dbe709 100644 --- a/rustc_codegen_spirv/Cargo.toml +++ b/rustc_codegen_spirv/Cargo.toml @@ -13,9 +13,18 @@ repository = "https://github.com/EmbarkStudios/rust-gpu" crate-type = ["dylib"] [features] +# By default, the use-compiled-tools is enabled, as doesn't require additional +# setup steps for the user. This does however mean that you will need to disable +# default features and explicitly enable `use-installed-tools` if you are using +# this in an environment with spirv-tools in PATH, and you don't want to take +# the compile time cost +default = ["use-compiled-tools"] # If enabled, uses spirv-tools binaries installed in PATH, instead of # compiling and linking the spirv-tools C++ code use-installed-tools = ["spirv-tools/use-installed"] +# If enabled will compile and link the C++ code for the spirv tools, the compiled +# version is preferred if both this and `use-installed-tools` are enabled +use-compiled-tools = ["spirv-tools/use-compiled"] [dependencies] bimap = "0.5" diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 489cf86055..ed1c0ec3ad 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -155,9 +155,15 @@ fn link_exe( } fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec { - use spirv_tools::{error, opt}; - - let mut optimizer = opt::Optimizer::new(spirv_tools::TargetEnv::default()); + use spirv_tools::{error, opt::{ + self, + Optimizer, + }}; + + #[cfg(feature = "use-compiled-tools")] + let mut optimizer = opt::compiled::CompiledOptimizer; + #[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))] + let mut optimizer = opt::tool::ToolOptimizer; optimizer .register_size_passes() diff --git a/spirv-tools-sys/Cargo.toml b/spirv-tools-sys/Cargo.toml index 9802381546..d6f6fd9821 100644 --- a/spirv-tools-sys/Cargo.toml +++ b/spirv-tools-sys/Cargo.toml @@ -11,6 +11,8 @@ license = "MIT OR Apache-2.0" # preserves the types so that spirv-tools can still work without needing # to keep copies of some of the basic enums etc use-installed = [] +# Forces compilation of the C++ code, even if `use-installed` is enabled +use-compiled = [] [build-dependencies] cc = { version = "1.0", features = ["parallel"] } diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 384c2d5ca7..a67222d270 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -219,7 +219,7 @@ fn val(build: &mut Build) { } fn main() { - if std::env::var("CARGO_FEATURE_USE_INSTALLED").is_ok() { + if std::env::var("CARGO_FEATURE_USE_INSTALLED").is_ok() && std::env::var("CARGO_FEATURE_USE_COMPILED").is_err() { println!("use-installed feature on, skipping compilation of C++ code"); return; } diff --git a/spirv-tools-sys/src/c/opt.cpp b/spirv-tools-sys/src/c/opt.cpp index 4a1d60202d..4bd4f06ec7 100644 --- a/spirv-tools-sys/src/c/opt.cpp +++ b/spirv-tools-sys/src/c/opt.cpp @@ -242,7 +242,7 @@ extern "C" { ((spvtools::Optimizer*)optimizer)->RegisterWebGPUToVulkanPasses(); } - SPIRV_TOOLS_EXPORT void optimizer_register_legalization_passes(Optimus* optimizer) { + SPIRV_TOOLS_EXPORT void optimizer_register_hlsl_legalization_passes(Optimus* optimizer) { ((spvtools::Optimizer*)optimizer)->RegisterLegalizationPasses(); } } diff --git a/spirv-tools-sys/src/opt.rs b/spirv-tools-sys/src/opt.rs index 4b7080a8f7..4eeb42907e 100644 --- a/spirv-tools-sys/src/opt.rs +++ b/spirv-tools-sys/src/opt.rs @@ -582,7 +582,7 @@ extern "C" { /// /// This sequence of passes is subject to constant review and will change /// from time to time. - pub fn optimizer_register_legalization_passes(opt: *mut Optimizer); + pub fn optimizer_register_hlsl_legalization_passes(opt: *mut Optimizer); // Some passes take arguments, so we create those separately on a // case-by-case basis diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index e5c7308b71..521c9ca2e7 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0" [features] use-installed = ["spirv-tools-sys/use-installed", "memchr"] +use-compiled = ["spirv-tools-sys/use-compiled"] [dependencies] spirv-tools-sys = { path = "../spirv-tools-sys" } @@ -18,3 +19,4 @@ structopt = "0.3" [[example]] name = "as" +required-features = ["use-compiled"] diff --git a/spirv-tools/examples/as.rs b/spirv-tools/examples/as.rs index 83766ee61b..db002b6950 100644 --- a/spirv-tools/examples/as.rs +++ b/spirv-tools/examples/as.rs @@ -13,14 +13,14 @@ struct Args { preserve_ids: bool, /// Use specified environment. #[structopt(long = "target-env", parse(try_from_str))] - target_env: Option, + target_env: Option, /// The input file. Use '-' for stdin. #[structopt(name = "FILE")] input: String, } fn main() { - use spirv_tools::assembler; + use spirv_tools::assembler::{self, Assembler}; let args = Args::from_args(); @@ -39,7 +39,7 @@ fn main() { preserve_numeric_ids: args.preserve_ids, }; - let assembler = assembler::Assembler::new(args.target_env.unwrap_or_default()); + let assembler = assembler::compiled::CompiledAssembler::default(); match assembler.assemble(&contents, assembler_opts) { Ok(binary) => { diff --git a/spirv-tools/src/assembler.rs b/spirv-tools/src/assembler.rs index 29e725c7b9..95d84bdea5 100644 --- a/spirv-tools/src/assembler.rs +++ b/spirv-tools/src/assembler.rs @@ -1,4 +1,8 @@ -use spirv_tools_sys::{assembler, shared}; +#[cfg(feature = "use-compiled")] +pub mod compiled; + +#[cfg(feature = "use-installed")] +pub mod tool; #[derive(Copy, Clone, Default)] pub struct AssemblerOptions { @@ -15,76 +19,18 @@ impl Into for AssemblerOptions { let mut res = 0; //assembler::BinaryOptions::None as u32; if self.preserve_numeric_ids { - res |= assembler::BinaryOptions::PreserveNumberIds as u32; + res |= spirv_tools_sys::assembler::BinaryOptions::PreserveNumberIds as u32; } res } } -pub struct Assembler { - inner: *mut shared::ToolContext, -} - -impl Assembler { - pub fn new(target_env: shared::TargetEnv) -> Self { - Self { - inner: unsafe { shared::context_create(target_env) }, - } - } - - pub fn assemble( +pub trait Assembler: Default { + fn with_env(target_env: crate::TargetEnv) -> Self; + fn assemble( &self, text: &str, options: AssemblerOptions, - ) -> Result { - unsafe { - let mut binary = std::ptr::null_mut(); - let mut diagnostic = std::ptr::null_mut(); - - let res = assembler::assemble( - self.inner, - text.as_ptr() as *const _, - text.len(), - options.into(), - &mut binary, - &mut diagnostic, - ); - - // Always wrap diagnostic, it's fine if it's null - use std::convert::TryFrom; - let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok(); - - match res { - shared::SpirvResult::Success => { - if binary.is_null() { - return Err(crate::error::Error { - inner: shared::SpirvResult::InternalError, - diagnostics: vec![crate::error::Diagnostic { - line: 0, - column: 0, - index: 0, - message: "spirv assemble indicated success but did not return a valid binary".to_owned(), - is_text: true, - }], - }); - } - - Ok(crate::shared::Binary::new(binary)) - } - other => Err(crate::error::Error { - inner: other, - diagnostics: vec![diagnostic], - }), - } - } - } -} - -impl Drop for Assembler { - fn drop(&mut self) { - unsafe { - shared::context_destroy(self.inner); - } - } -} + ) -> Result; +} \ No newline at end of file diff --git a/spirv-tools/src/assembler/compiled.rs b/spirv-tools/src/assembler/compiled.rs new file mode 100644 index 0000000000..307438aed8 --- /dev/null +++ b/spirv-tools/src/assembler/compiled.rs @@ -0,0 +1,70 @@ +use spirv_tools_sys::{assembler, shared}; + +pub struct CompiledAssembler { + inner: *mut shared::ToolContext, +} + +use super::Assembler; + +impl Assembler for CompiledAssembler { + fn with_env(target_env: crate::TargetEnv) -> Self { + Self { + inner: unsafe { shared::context_create(target_env) }, + } + } + + fn assemble( + &self, + text: &str, + options: super::AssemblerOptions, + ) -> Result { + unsafe { + let mut binary = std::ptr::null_mut(); + let mut diagnostic = std::ptr::null_mut(); + + let res = assembler::assemble( + self.inner, + text.as_ptr() as *const _, + text.len(), + options.into(), + &mut binary, + &mut diagnostic, + ); + + // Always wrap diagnostic, it's fine if it's null + use std::convert::TryFrom; + let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok(); + + match res { + shared::SpirvResult::Success => { + if binary.is_null() { + return Err(crate::error::Error { + inner: shared::SpirvResult::InternalError, + diagnostic: Some("spirv assemble indicated success but did not return a valid binary".to_owned().into()), + }); + } + + Ok(crate::binary::Binary::External(crate::binary::external::ExternalBinary::new(binary))) + } + other => Err(crate::error::Error { + inner: other, + diagnostic, + }), + } + } + } +} + +impl Default for CompiledAssembler { + fn default() -> Self { + Self::with_env(crate::TargetEnv::default()) + } +} + +impl Drop for CompiledAssembler { + fn drop(&mut self) { + unsafe { + shared::context_destroy(self.inner); + } + } +} diff --git a/spirv-tools/src/assembler/tool.rs b/spirv-tools/src/assembler/tool.rs new file mode 100644 index 0000000000..64ddae1e0b --- /dev/null +++ b/spirv-tools/src/assembler/tool.rs @@ -0,0 +1,39 @@ +pub struct ToolAssembler { + target_env: crate::TargetEnv, +} + +use super::Assembler; + +impl Assembler for ToolAssembler { + fn with_env(target_env: crate::TargetEnv) -> Self { + Self { + target_env, + } + } + + fn assemble( + &self, + text: &str, + options: super::AssemblerOptions, + ) -> Result { + let mut cmd = std::process::Command::new("spirv-as"); + cmd.arg("--target-env").arg(self.target_env.to_string()); + + if options.preserve_numeric_ids { + cmd.arg("--preserve-numeric-ids"); + } + + cmd.arg("-o").arg("-"); + + let cmd_output = crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Retrieve)?; + + use std::convert::TryFrom; + crate::binary::Binary::try_from(cmd_output.binary) + } +} + +impl Default for ToolAssembler { + fn default() -> Self { + Self::with_env(crate::TargetEnv::default()) + } +} diff --git a/spirv-tools/src/binary.rs b/spirv-tools/src/binary.rs new file mode 100644 index 0000000000..b9d90a2ae1 --- /dev/null +++ b/spirv-tools/src/binary.rs @@ -0,0 +1,86 @@ +#[cfg(feature = "use-compiled")] +pub mod external { + use spirv_tools_sys::shared; + + pub struct ExternalBinary { + inner: *mut shared::Binary, + } + + impl ExternalBinary { + pub(crate) fn new(bin: *mut shared::Binary) -> Self { + Self { inner: bin } + } + } + + impl AsRef<[u32]> for ExternalBinary { + fn as_ref(&self) -> &[u32] { + unsafe { std::slice::from_raw_parts((*self.inner).code, (*self.inner).size) } + } + } + + impl AsRef<[u8]> for ExternalBinary { + fn as_ref(&self) -> &[u8] { + unsafe { + std::slice::from_raw_parts( + (*self.inner).code as *const u8, + (*self.inner).size * std::mem::size_of::(), + ) + } + } + } + + impl Drop for ExternalBinary { + fn drop(&mut self) { + unsafe { + shared::binary_destroy(self.inner); + } + } + } +} + +pub enum Binary { + #[cfg(feature = "use-compiled")] + External(self::external::ExternalBinary), + OwnedU32(Vec), + OwnedU8(Vec), +} + +impl std::convert::TryFrom> for Binary { + type Error = crate::Error; + + fn try_from(v: Vec) -> Result { + if v.len() % std::mem::size_of::() != 0 { + return Err(crate::Error { + inner: spirv_tools_sys::shared::SpirvResult::InvalidBinary, + diagnostic: None, + }); + } else { + Ok(Binary::OwnedU8(v)) + } + } +} + +impl AsRef<[u32]> for Binary { + fn as_ref(&self) -> &[u32] { + match self { + #[cfg(feature = "use-compiled")] + Self::External(bin) => bin.as_ref(), + Self::OwnedU32(v) => &v, + Self::OwnedU8(v) => { + // If you hit a panic here it's because try_from wasn't used ;) + crate::util::to_binary(&v).unwrap() + }, + } + } +} + +impl AsRef<[u8]> for Binary { + fn as_ref(&self) -> &[u8] { + match self { + #[cfg(feature = "use-compiled")] + Self::External(bin) => bin.as_ref(), + Self::OwnedU32(v) => crate::util::from_binary(&v), + Self::OwnedU8(v) => &v, + } + } +} \ No newline at end of file diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs index f830148bbe..e08bd2f182 100644 --- a/spirv-tools/src/cmd.rs +++ b/spirv-tools/src/cmd.rs @@ -1,4 +1,4 @@ -use crate::error::Diagnostic; +use crate::error::Message; use std::process::{Command, Stdio}; pub enum CmdError { @@ -11,20 +11,47 @@ pub enum CmdError { /// diagnostics ToolErrors { exit_code: i32, - /// Diagnostics that were parsed from the output - diagnostics: Vec, + /// Messages that were parsed from the output + messages: Vec, }, } impl From for crate::error::Error { - fn from(ce: CmdError) -> Self {} + fn from(ce: CmdError) -> Self { + use crate::SpirvResult; + + match ce { + CmdError::BinaryNotFound(e) => { + Self { + inner: SpirvResult::Unsupported, + diagnostic: Some(format!("failed spawn executable: {}", e).into()), + } + } + CmdError::Io(e) => { + Self { + inner: SpirvResult::EndOfStream, + diagnostic: Some(format!("i/o error occurred communicating with executable: {}", e).into()), + } + } + CmdError::ToolErrors { exit_code: _, messages } => { + // The C API just puts the last message as the diagnostic, so just do the + // same for now + let diagnostic = messages.into_iter().last().map(crate::error::Diagnostic::from); + + Self { + inner: SpirvResult::InternalError, // this isn't really correct + diagnostic, + } + } + } + } } pub struct CmdOutput { /// The output the command is actually supposed to give back pub binary: Vec, /// Warning or Info level diagnostics that were gathered during execution - pub diagnostics: Vec, + pub messages: Vec, } #[derive(PartialEq, Copy, Clone)] @@ -36,7 +63,7 @@ pub enum Output { } pub fn exec( - cmd: Command, + mut cmd: Command, input: Option<&[u8]>, retrieve_output: Output, ) -> Result { @@ -77,43 +104,31 @@ pub fn exec( return Err(CmdError::ToolErrors { exit_code: -1, - diagnostics: vec![Diagnostic { - line: 0, - column: 0, - index: 0, - message, - is_text: false, - }], + messages: vec![Message::fatal(message)], }); } }; // stderr should only ever contain error+ level diagnostics if code != 0 { - let diagnostics: Vec<_> = match String::from_utf8(output.stderr) { + let messages: Vec<_> = match String::from_utf8(output.stderr) { Ok(errors) => errors .lines() - .filter_map(|line| crate::error::Message::parse(line).map(Diagnostic::from)) + .filter_map(|line| crate::error::Message::parse(line)) .collect(), - Err(e) => vec![Diagnostic { - line: 0, - column: 0, - index: 0, - message: format!( - "unable to read stderr ({}) but process exited with code {}", - e, code - ), - is_text: false, - }], + Err(e) => vec![Message::fatal(format!( + "unable to read stderr ({}) but process exited with code {}", + e, code + ))], }; return Err(CmdError::ToolErrors { exit_code: code, - diagnostics, + messages, }); } - fn split<'a>(haystack: &'a [u8], needle: u8) -> impl Iterator + 'a { + fn split(haystack: &[u8], needle: u8) -> impl Iterator { struct Split<'a> { haystack: &'a [u8], needle: u8, @@ -142,16 +157,15 @@ pub fn exec( // Since we are retrieving the results via stdout, but it can also contain // diagnostic messages, we need to be careful - let mut diagnostics = Vec::new(); + let mut messages = Vec::new(); let mut binary = Vec::with_capacity(if retrieve_output { 1024 } else { 0 }); - let mut iter = split(&output.stdout, b'\n'); - let mut maybe_diagnostic = true; - for line in iter { - if maybe_diagnostic { + let mut maybe_msg = true; + for line in split(&output.stdout, b'\n') { + if maybe_msg { if let Some(s) = std::str::from_utf8(line).ok() { if let Some(msg) = crate::error::Message::parse(s) { - diagnostics.push(Diagnostic::from(msg)); + messages.push(msg); continue; } } @@ -160,11 +174,12 @@ pub fn exec( if retrieve_output { binary.extend_from_slice(line); } - maybe_diagnostic = false; + + maybe_msg = false; } Ok(CmdOutput { binary, - diagnostics, + messages, }) } diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs index d38b9bfcb7..210fdafa02 100644 --- a/spirv-tools/src/error.rs +++ b/spirv-tools/src/error.rs @@ -1,29 +1,25 @@ use spirv_tools_sys::{diagnostics, shared}; +pub use shared::SpirvResult; pub use diagnostics::MessageLevel; #[derive(Debug, PartialEq)] pub struct Error { pub inner: shared::SpirvResult, - pub diagnostics: Vec, + pub diagnostic: Option, } use std::fmt; impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_fmt(format_args!("{}", self.inner))?; - - if !self.diagnostics.is_empty() { - for diag in &self.diagnostics { - f.write_fmt(format_args!( - "\n{}:{}:{} - {}", - self.inner, diag.line, diag.column, diag.message - ))? - } + match &self.diagnostic { + Some(diag) => f.write_fmt(format_args!( + "{}:{}:{} - {}", + self.inner, diag.line, diag.column, diag.message + )), + None => f.write_fmt(format_args!("{}", self.inner)), } - - Ok(()) } } @@ -70,28 +66,51 @@ impl std::convert::TryFrom<*mut diagnostics::Diagnostic> for Diagnostic { } } -impl<'a> From> for Diagnostic { - fn from(msg: Message<'a>) -> Self { +impl From for Diagnostic{ + fn from(message: String) -> Self { + Self { + line: 0, + column: 0, + index: 0, + is_text: false, + message, + } + } +} + +impl From for Diagnostic { + fn from(msg: Message) -> Self { Self { line: msg.line, column: msg.column, index: msg.index, - message: msg.message.to_string(), + message: msg.message, is_text: false, } } } -pub struct Message<'a> { +pub struct Message { pub level: MessageLevel, - pub source: std::borrow::Cow<'a, str>, + pub source: Option, pub line: usize, pub column: usize, pub index: usize, - pub message: std::borrow::Cow<'a, str>, + pub message: String, } -impl<'a> Message<'a> { +impl Message { + pub(crate) fn fatal(message: String) -> Self { + Self { + level: MessageLevel::Fatal, + source: None, + line: 0, + column: 0, + index: 0, + message, + } + } + pub(crate) fn from_parts( level: MessageLevel, source: *const std::os::raw::c_char, @@ -114,16 +133,16 @@ impl<'a> Message<'a> { Self { level, - source, + source: if source.is_empty() { None } else { Some(source.into_owned()) }, line, column, index, - message, + message: message.into_owned(), } } } - pub(crate) fn parse(s: &'a str) -> Option { + pub(crate) fn parse(s: &str) -> Option { s.find(": ") .and_then(|i| { let level = match &s[..i] { @@ -149,8 +168,8 @@ impl<'a> Message<'a> { .map(|(level, index, last)| Self { level, index, - message: std::borrow::Cow::Borrowed(&s[last..]), - source: std::borrow::Cow::Borrowed(""), + message: s[last..].to_owned(), + source: None, line: 0, column: 0, }) @@ -158,14 +177,14 @@ impl<'a> Message<'a> { } pub trait MessageCallback { - fn on_message(&mut self, msg: Message<'_>); + fn on_message(&mut self, msg: Message); } impl MessageCallback for F where - F: FnMut(Message<'_>), + F: FnMut(Message), { - fn on_message(&mut self, msg: Message<'_>) { + fn on_message(&mut self, msg: Message) { self(msg) } } diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index 740d145b00..41d0f4371d 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -1,10 +1,10 @@ pub mod assembler; pub mod opt; -pub mod shared; +pub mod binary; pub mod val; pub mod error; -pub use error::Error; +pub use error::{Error, SpirvResult}; pub use spirv_tools_sys::shared::TargetEnv; diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index 8bf4321fed..55a8f0c2e0 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -1,13 +1,7 @@ -#[cfg(not(feature = "use-installed"))] -mod compiled; +#[cfg(feature = "use-compiled")] +pub mod compiled; #[cfg(feature = "use-installed")] -mod tool; - -#[cfg(not(feature = "use-installed"))] -pub use compiled::Optimizer; - -#[cfg(feature = "use-installed")] -pub use tool::Optimizer; +pub mod tool; pub use spirv_tools_sys::opt::Passes; @@ -25,3 +19,34 @@ pub struct Options { /// should be preserved. pub preserve_spec_constants: bool, } + +pub trait Optimizer { + fn with_env(target_env: crate::TargetEnv) -> Self; + + fn optimize( + &self, + input: &[u32], + msg_callback: &mut MC, + options: Option, + ) -> Result; + + /// Register a single pass with the the optimizer. + fn register_pass(&mut self, pass: Passes) -> &mut Self; + /// Registers passes that attempt to improve performance of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + fn register_performance_passes(&mut self) -> &mut Self; + /// Registers passes that attempt to improve the size of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + fn register_size_passes(&mut self) -> &mut Self; + /// Registers passes that attempt to legalize the generated code. + /// + /// Note: this recipe is specially designed for legalizing SPIR-V. It should be + /// used by compilers after translating HLSL source code literally. It should + /// *not* be used by general workloads for performance or size improvement. + /// + /// This sequence of passes is subject to constant review and will change + /// from time to time. + fn register_hlsl_legalization_passes(&mut self) -> &mut Self; +} diff --git a/spirv-tools/src/opt/compiled.rs b/spirv-tools/src/opt/compiled.rs index 298df24501..412c191195 100644 --- a/spirv-tools/src/opt/compiled.rs +++ b/spirv-tools/src/opt/compiled.rs @@ -62,7 +62,7 @@ impl Optimizer { input: &[u32], msg_callback: &mut MC, options: Option, - ) -> Result { + ) -> Result { unsafe { struct Ctx<'a> { cb: &'a mut dyn error::MessageCallback, @@ -122,7 +122,7 @@ impl Optimizer { }); } - Ok(crate::shared::Binary::new(binary)) + Ok(crate::binary::Binary::External(crate::binary::external::ExternalBinary::new(binary))) } other => Err(error::Error { inner: other, @@ -157,23 +157,23 @@ impl Optimizer { self } - /// Registers passes that have been prescribed for converting from Vulkan to - /// WebGPU. This sequence of passes is subject to constant review and will - /// change from time to time. - #[inline] - pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_vulkan_to_webgpu_passes(self.inner) } - self - } - - /// Registers passes that have been prescribed for converting from WebGPU to - /// Vulkan. This sequence of passes is subject to constant review and will - /// change from time to time. - #[inline] - pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_webgpu_to_vulkan_passes(self.inner) } - self - } + // /// Registers passes that have been prescribed for converting from Vulkan to + // /// WebGPU. This sequence of passes is subject to constant review and will + // /// change from time to time. + // #[inline] + // pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self { + // unsafe { opt::optimizer_register_vulkan_to_webgpu_passes(self.inner) } + // self + // } + + // /// Registers passes that have been prescribed for converting from WebGPU to + // /// Vulkan. This sequence of passes is subject to constant review and will + // /// change from time to time. + // #[inline] + // pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self { + // unsafe { opt::optimizer_register_webgpu_to_vulkan_passes(self.inner) } + // self + // } /// Registers passes that attempt to legalize the generated code. /// @@ -184,12 +184,18 @@ impl Optimizer { /// This sequence of passes is subject to constant review and will change /// from time to time. #[inline] - pub fn register_legalization_passes(&mut self) -> &mut Self { - unsafe { opt::optimizer_register_legalization_passes(self.inner) } + pub fn register_hlsl_legalization_passes(&mut self) -> &mut Self { + unsafe { opt::optimizer_register_hlsl_legalization_passes(self.inner) } self } } +impl Default for Optimizer { + fn default() -> Self { + Self::new(crate::TargetEnv::default()) + } +} + impl Drop for Optimizer { #[inline] fn drop(&mut self) { diff --git a/spirv-tools/src/opt/tool.rs b/spirv-tools/src/opt/tool.rs index e69de29bb2..7f1f5ec078 100644 --- a/spirv-tools/src/opt/tool.rs +++ b/spirv-tools/src/opt/tool.rs @@ -0,0 +1,178 @@ +use crate::error; + +#[derive(Default)] +pub struct ToolOptimizer { + target_env: crate::TargetEnv, + passes: Vec, + use_perf_passes: bool, + use_size_passes: bool, + //use_vulkan_to_webgpu: bool, + //use_webgpu_to_vulkan: bool, + legalize_hlsl: bool, +} + +use super::Optimizer; + +impl Optimizer for ToolOptimizer { + fn with_env(target_env: crate::TargetEnv) -> Self { + Self { target_env, ..Default::default() } + } + + fn optimize( + &self, + input: &[u32], + msg_callback: &mut MC, + options: Option, + ) -> Result { + let mut cmd = std::process::Command::new("spirv-opt"); + cmd.arg("--target-env").arg(self.target_env.to_string()); + + cmd.args(self.passes.iter().filter_map(|p| pass_to_string(*p).map(|s| format!("--{}", s)))); + + if self.use_perf_passes { + cmd.arg("-O"); + } + + if self.use_size_passes { + cmd.arg("-Os"); + } + + if self.legalize_hlsl { + cmd.arg("--legalize-hlsl"); + } + + if let Some(opts) = options { + if let Some(max_id_bound) = opts.max_id_bound { + cmd.arg(format!("--max-id-bound={}", max_id_bound)); + } + + if opts.preserve_bindings { + cmd.arg("--preserve-bindings"); + } + + if opts.preserve_spec_constants { + cmd.arg("--preserve-spec-constants"); + } + + if let Some(vopts) = opts.validator_options { + crate::val::tool::add_options(&mut cmd, vopts); + } + } + + let input = crate::util::from_binary(input); + + let cmd_output = crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Retrieve)?; + + for msg in cmd_output.messages { + msg_callback.on_message(msg); + } + + use std::convert::TryFrom; + crate::binary::Binary::try_from(cmd_output.binary) + } + + /// Register a single pass with the the optimizer. + #[inline] + fn register_pass(&mut self, pass: super::Passes) -> &mut Self { + self.passes.push(pass); + self + } + + /// Registers passes that attempt to improve performance of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + fn register_performance_passes(&mut self) -> &mut Self { + self.use_perf_passes = true; + self + } + + /// Registers passes that attempt to improve the size of generated code. + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + fn register_size_passes(&mut self) -> &mut Self { + self.use_size_passes = true; + self + } + + /// Registers passes that attempt to legalize the generated code. + /// + /// Note: this recipe is specially designed for legalizing SPIR-V. It should be + /// used by compilers after translating HLSL source code literally. It should + /// *not* be used by general workloads for performance or size improvement. + /// + /// This sequence of passes is subject to constant review and will change + /// from time to time. + #[inline] + fn register_hlsl_legalization_passes(&mut self) -> &mut Self { + self.legalize_hlsl = true; + self + } +} + +fn pass_to_string(pass: super::Passes) -> Option<&'static str> { + use super::Passes::*; + + Some(match pass { + Null => return None, + StripAtomicCounterMemory => "strip-atomic-counter-memory", + StripDebugInfo => "strip-debug", + StripReflectInfo => "strip-reflect", + EliminateDeadFunctions => "eliminate-dead-functions", + EliminateDeadMembers => "eliminate-dead-members", + FlattenDecoration => "flatten-decorations", + FreezeSpecConstantValue => "freeze-spec-const", + FoldSpecConstantOpAndComposite => "fold-spec-const-op-composite", + UnifyConstant => "unify-const", + EliminateDeadConstant => "eliminate-dead-const", + StrengthReduction => "strength-reduction", + BlockMerge => "merge-blocks", + InlineExhaustive => "inline-entry-points-exhaustive", + InlineOpaque => "inline-entry-points-opaque", + LocalSingleBlockLoadStoreElim => "eliminate-local-single-block", + DeadBranchElim => "eliminate-dead-branches", + LocalMultiStoreElim => "eliminate-local-multi-store", + LocalAccessChainConvert => "convert-local-access-chains", + LocalSingleStoreElim => "eliminate-local-single-store", + InsertExtractElim => "eliminate-insert-extract", + DeadInsertElim => "eliminate-dead-inserts", + AggressiveDCE => "eliminate-dead-code-aggressive", + PropagateLineInfo => "propagate-line-info", + RedundantLineInfoElim => "eliminate-redundant-line-info", + CompactIds => "compact-ids", + RemoveDuplicates => "remove-duplicates", + CFGCleanup => "cfg-cleanup", + DeadVariableElimination => "eliminate-dead-variables", + MergeReturn => "merge-return", + LocalRedundancyElimination => "local-redundancy-elimination", + LoopInvariantCodeMotion => "loop-invariant-code-motion", + LoopPeeling => "loop-peeling", + LoopUnswitch => "loop-unswitch", + RedundancyElimination => "redundancy-elimination", + PrivateToLocal => "private-to-local", + ConditionalConstantPropagation => "ccp", + Workaround1209 => "workaround-1209", + IfConversion => "if-conversion", + ReplaceInvalidOpcode => "replace-invalid-opcode", + Simplification => "simplify-instructions", + SSARewrite => "ssa-rewrite", + ConvertRelaxedToHalf => "convert-relaxed-to-half", + RelaxFloatOps => "relax-float-ops", + CopyPropagateArrays => "copy-propagate-arrays", + VectorDCE => "vector-dce", + ReduceLoadSize => "reduce-load-size", + CombineAccessChains => "combine-access-chains", + UpgradeMemoryModel => "upgrade-memory-model", + CodeSinking => "code-sink", + GenerateWebGPUInitializers => "generate-webgpu-initializers", + FixStorageClass => "fix-storage-class", + LegalizeVectorShuffle => "legalize-vector-shuffle", + DecomposeInitializedVariables => "decompose-initialized-variables", + SplitInvalidUnreachable => "split-invalid-unreachable", + GraphicsRobustAccess => "graphics-robust-access", + DescriptorScalarReplacement => "descriptor-scalar-replacement", + WrapOpKill => "wrap-opkill", + AmdExtToKhr => "amd-ext-to-khr", + }) +} \ No newline at end of file diff --git a/spirv-tools/src/shared.rs b/spirv-tools/src/shared.rs deleted file mode 100644 index 44e3b9c83f..0000000000 --- a/spirv-tools/src/shared.rs +++ /dev/null @@ -1,36 +0,0 @@ -use spirv_tools_sys::shared; - -pub struct Binary { - inner: *mut shared::Binary, -} - -impl Binary { - pub(crate) fn new(bin: *mut shared::Binary) -> Self { - Self { inner: bin } - } -} - -impl AsRef<[u32]> for Binary { - fn as_ref(&self) -> &[u32] { - unsafe { std::slice::from_raw_parts((*self.inner).code, (*self.inner).size) } - } -} - -impl AsRef<[u8]> for Binary { - fn as_ref(&self) -> &[u8] { - unsafe { - std::slice::from_raw_parts( - (*self.inner).code as *const u8, - (*self.inner).size * std::mem::size_of::(), - ) - } - } -} - -impl Drop for Binary { - fn drop(&mut self) { - unsafe { - shared::binary_destroy(self.inner); - } - } -} diff --git a/spirv-tools/src/util.rs b/spirv-tools/src/util.rs index fa3dfb5572..1f99aba7a2 100644 --- a/spirv-tools/src/util.rs +++ b/spirv-tools/src/util.rs @@ -11,7 +11,7 @@ pub fn to_binary(bytes: &[u8]) -> Result<&[u32], crate::Error> { if bytes.len() % std::mem::size_of::() != 0 { return Err(crate::Error { inner: spirv_tools_sys::shared::SpirvResult::InvalidBinary, - diagnostics: vec![], + diagnostic: None, }); } diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index ea969ad5b4..c1d7067323 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -1,13 +1,7 @@ -#[cfg(not(feature = "use-installed"))] -pub(crate) mod compiled; +#[cfg(feature = "use-compiled")] +pub mod compiled; #[cfg(feature = "use-installed")] -mod tool; - -#[cfg(not(feature = "use-installed"))] -pub use compiled::Validator; - -#[cfg(feature = "use-installed")] -pub use tool::Optimizer; +pub mod tool; #[derive(Default, Clone)] pub struct ValidatorOptions { @@ -75,3 +69,12 @@ pub struct ValidatorOptions { /// Applies a maximum to one or more Universal limits pub max_limits: Vec<(spirv_tools_sys::val::ValidatorLimits, u32)>, } + +pub trait Validator: Default { + fn with_env(target_env: crate::TargetEnv) -> Self; + fn validate( + &self, + binary: &[u32], + options: Option, + ) -> Result<(), crate::error::Error>; +} diff --git a/spirv-tools/src/val/compiled.rs b/spirv-tools/src/val/compiled.rs index ffd3721463..3b360e8aeb 100644 --- a/spirv-tools/src/val/compiled.rs +++ b/spirv-tools/src/val/compiled.rs @@ -15,7 +15,7 @@ impl From for Options { val::validator_options_set_relax_block_layout(inner, relax); } - if vo.relax_store_struct { + if vo.relax_struct_store { val::validator_options_set_relax_store_struct(inner, true); } @@ -54,18 +54,20 @@ impl Drop for Options { } } -pub struct Validator { +pub struct CompiledValidator { inner: *mut shared::ToolContext, } -impl Validator { - pub fn new(target_env: shared::TargetEnv) -> Self { +use super::Validator; + +impl Validator for CompiledValidator { + fn with_env(target_env: crate::TargetEnv) -> Self { Self { inner: unsafe { shared::context_create(target_env) }, } } - pub fn validate( + fn validate( &self, binary: &[u32], options: Option, @@ -95,14 +97,20 @@ impl Validator { shared::SpirvResult::Success => Ok(()), other => Err(crate::error::Error { inner: other, - diagnostics: vec![diagnostic], + diagnostic, }), } } } } -impl Drop for Validator { +impl Default for CompiledValidator { + fn default() -> Self { + Self::with_env(crate::TargetEnv::default()) + } +} + +impl Drop for CompiledValidator { fn drop(&mut self) { unsafe { shared::context_destroy(self.inner) } } diff --git a/spirv-tools/src/val/tool.rs b/spirv-tools/src/val/tool.rs index cbd570440d..5eb0d5c9f5 100644 --- a/spirv-tools/src/val/tool.rs +++ b/spirv-tools/src/val/tool.rs @@ -19,45 +19,48 @@ impl Validator { cmd.arg("--target-env").arg(self.target_env.to_string()); if let Some(opts) = options { - if opts.relax_logical_pointer { - cmd.arg("--relax-logical-pointer"); - } + add_options(&mut cmd, opts); + } - if let Some(true) = opts.relax_block_layout { - cmd.arg("--relax-block-layout"); - } + let input = crate::util::from_binary(binary); - if opts.uniform_buffer_standard_layout { - cmd.arg("--uniform-buffer-standard-layout"); - } + crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Ignore)?; + Ok(()) + } +} - if opts.scalar_block_layout { - cmd.arg("--scalar-block-layout"); - } +pub(crate) fn add_options(cmd: &mut Command, opts: super::ValidatorOptions) { + if opts.relax_logical_pointer { + cmd.arg("--relax-logical-pointer"); + } - if opts.skip_block_layout { - cmd.arg("--skip-block-layout"); - } + if let Some(true) = opts.relax_block_layout { + cmd.arg("--relax-block-layout"); + } - if opts.relax_struct_store { - cmd.arg("--relax-struct-store"); - } + if opts.uniform_buffer_standard_layout { + cmd.arg("--uniform-buffer-standard-layout"); + } - if opts.before_legalization { - cmd.arg("--before-hlsl-legalization"); - } + if opts.scalar_block_layout { + cmd.arg("--scalar-block-layout"); + } - add_limits(&mut cmd, &opts.max_limits); - } + if opts.skip_block_layout { + cmd.arg("--skip-block-layout"); + } - let input = crate::util::from_binary(binary); + if opts.relax_struct_store { + cmd.arg("--relax-struct-store"); + } - crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Ignore)?; - Ok(()) + if opts.before_legalization { + cmd.arg("--before-hlsl-legalization"); } + + add_limits(cmd, &opts.max_limits); } -#[inline] fn add_limits(cmd: &mut Command, limits: &[(spirv_tools_sys::val::ValidatorLimits, u32)]) { use spirv_tools_sys::val::ValidatorLimits; From 91823a013b8a1003dfdc63ae6d68450b3fa4ffdf Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 28 Oct 2020 19:38:09 +0100 Subject: [PATCH 23/41] Get tests to work both with installed and compiled tools --- .github/workflows/ci.yaml | 1 + rustc_codegen_spirv/src/link.rs | 19 +++++------- rustc_codegen_spirv/src/linker/test.rs | 10 +++--- spirv-builder/Cargo.toml | 2 -- spirv-tools/examples/as.rs | 3 +- spirv-tools/src/assembler.rs | 16 +++++++++- spirv-tools/src/assembler/compiled.rs | 3 +- spirv-tools/src/assembler/tool.rs | 7 ++--- spirv-tools/src/cmd.rs | 43 +++++++++++++++----------- spirv-tools/src/error.rs | 13 ++++++-- spirv-tools/src/opt.rs | 16 +++++++++- spirv-tools/src/opt/compiled.rs | 30 +++++++++--------- spirv-tools/src/opt/tool.rs | 17 +++++++--- spirv-tools/src/val.rs | 14 +++++++++ spirv-tools/src/val/tool.rs | 11 ++++--- 15 files changed, 137 insertions(+), 68 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 833ba81d0f..a585f3fd3e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -58,6 +58,7 @@ jobs: - run: rustup component add rustfmt clippy rust-src rustc-dev llvm-tools-preview - run: cargo fmt --all -- --check - run: cargo clippy --workspace --all-targets -- -D warnings + cargo-deny: runs-on: ubuntu-latest steps: diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index ed1c0ec3ad..52d7c0f5a5 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -155,15 +155,12 @@ fn link_exe( } fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec { - use spirv_tools::{error, opt::{ - self, - Optimizer, - }}; + use spirv_tools::{ + error, + opt::{self, Optimizer}, + }; - #[cfg(feature = "use-compiled-tools")] - let mut optimizer = opt::compiled::CompiledOptimizer; - #[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))] - let mut optimizer = opt::tool::ToolOptimizer; + let mut optimizer = opt::create(None); optimizer .register_size_passes() @@ -172,7 +169,7 @@ fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec| { + &mut |msg: error::Message| { use error::MessageLevel as Level; // TODO: Adds spans here? Not sure how useful with binary, but maybe? @@ -203,9 +200,9 @@ fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec std::fmt::Debug for PrettyString<'a> { } fn assemble_spirv(spirv: &str) -> Result> { - use spirv_tools::assembler; + use spirv_tools::assembler::{self, Assembler}; - let assembler = assembler::Assembler::new(spirv_tools::default_target_env()); + let assembler = assembler::create(None); let spv_binary = assembler.assemble(spirv, assembler::AssemblerOptions::default())?; @@ -25,10 +25,12 @@ fn assemble_spirv(spirv: &str) -> Result> { #[allow(unused)] fn validate(spirv: &[u32]) { - let validator = spirv_tools::val::Validator::new(spirv_tools::default_target_env()); + use spirv_tools::val::{self, Validator}; + + let validator = val::create(None); validator - .validate(spirv, &spirv_tools::val::ValidatorOptions::default()) + .validate(spirv, None) .expect("validation error occurred"); } diff --git a/spirv-builder/Cargo.toml b/spirv-builder/Cargo.toml index 0263521ea4..4283d52245 100644 --- a/spirv-builder/Cargo.toml +++ b/spirv-builder/Cargo.toml @@ -5,8 +5,6 @@ authors = ["Embark "] edition = "2018" license = "MIT OR Apache-2.0" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] memchr = "2.3" raw-string = "0.3.5" diff --git a/spirv-tools/examples/as.rs b/spirv-tools/examples/as.rs index db002b6950..15207cb629 100644 --- a/spirv-tools/examples/as.rs +++ b/spirv-tools/examples/as.rs @@ -39,7 +39,8 @@ fn main() { preserve_numeric_ids: args.preserve_ids, }; - let assembler = assembler::compiled::CompiledAssembler::default(); + let assembler = + assembler::compiled::CompiledAssembler::with_env(args.target_env.unwrap_or_default()); match assembler.assemble(&contents, assembler_opts) { Ok(binary) => { diff --git a/spirv-tools/src/assembler.rs b/spirv-tools/src/assembler.rs index 95d84bdea5..d2a874444d 100644 --- a/spirv-tools/src/assembler.rs +++ b/spirv-tools/src/assembler.rs @@ -33,4 +33,18 @@ pub trait Assembler: Default { text: &str, options: AssemblerOptions, ) -> Result; -} \ No newline at end of file +} + +pub fn create(te: Option) -> impl Assembler { + let target_env = te.unwrap_or_default(); + + #[cfg(feature = "use-compiled")] + { + compiled::CompiledAssembler::with_env(target_env) + } + + #[cfg(all(feature = "use-installed", not(feature = "use-compiled")))] + { + tool::ToolAssembler::with_env(target_env) + } +} diff --git a/spirv-tools/src/assembler/compiled.rs b/spirv-tools/src/assembler/compiled.rs index 307438aed8..a145b13840 100644 --- a/spirv-tools/src/assembler/compiled.rs +++ b/spirv-tools/src/assembler/compiled.rs @@ -44,7 +44,8 @@ impl Assembler for CompiledAssembler { }); } - Ok(crate::binary::Binary::External(crate::binary::external::ExternalBinary::new(binary))) + let bin = crate::binary::external::ExternalBinary::new(binary); + Ok(crate::binary::Binary::External(bin)) } other => Err(crate::error::Error { inner: other, diff --git a/spirv-tools/src/assembler/tool.rs b/spirv-tools/src/assembler/tool.rs index 64ddae1e0b..08fc88d806 100644 --- a/spirv-tools/src/assembler/tool.rs +++ b/spirv-tools/src/assembler/tool.rs @@ -6,9 +6,7 @@ use super::Assembler; impl Assembler for ToolAssembler { fn with_env(target_env: crate::TargetEnv) -> Self { - Self { - target_env, - } + Self { target_env } } fn assemble( @@ -25,7 +23,8 @@ impl Assembler for ToolAssembler { cmd.arg("-o").arg("-"); - let cmd_output = crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Retrieve)?; + let cmd_output = + crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Retrieve)?; use std::convert::TryFrom; crate::binary::Binary::try_from(cmd_output.binary) diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs index e08bd2f182..9e82ffac7a 100644 --- a/spirv-tools/src/cmd.rs +++ b/spirv-tools/src/cmd.rs @@ -21,22 +21,26 @@ impl From for crate::error::Error { use crate::SpirvResult; match ce { - CmdError::BinaryNotFound(e) => { - Self { - inner: SpirvResult::Unsupported, - diagnostic: Some(format!("failed spawn executable: {}", e).into()), - } - } - CmdError::Io(e) => { - Self { - inner: SpirvResult::EndOfStream, - diagnostic: Some(format!("i/o error occurred communicating with executable: {}", e).into()), - } - } - CmdError::ToolErrors { exit_code: _, messages } => { + CmdError::BinaryNotFound(e) => Self { + inner: SpirvResult::Unsupported, + diagnostic: Some(format!("failed spawn executable: {}", e).into()), + }, + CmdError::Io(e) => Self { + inner: SpirvResult::EndOfStream, + diagnostic: Some( + format!("i/o error occurred communicating with executable: {}", e).into(), + ), + }, + CmdError::ToolErrors { + exit_code: _, + messages, + } => { // The C API just puts the last message as the diagnostic, so just do the // same for now - let diagnostic = messages.into_iter().last().map(crate::error::Diagnostic::from); + let diagnostic = messages + .into_iter() + .last() + .map(crate::error::Diagnostic::from); Self { inner: SpirvResult::InternalError, // this isn't really correct @@ -172,14 +176,17 @@ pub fn exec( } if retrieve_output { + // Handle case where there is a '\n' in the stream, but it's not the + // end of an output message + if !maybe_msg || messages.is_empty() && !binary.is_empty() { + binary.push(b'\n'); + } + binary.extend_from_slice(line); } maybe_msg = false; } - Ok(CmdOutput { - binary, - messages, - }) + Ok(CmdOutput { binary, messages }) } diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs index 210fdafa02..87b6fc9529 100644 --- a/spirv-tools/src/error.rs +++ b/spirv-tools/src/error.rs @@ -1,7 +1,7 @@ use spirv_tools_sys::{diagnostics, shared}; -pub use shared::SpirvResult; pub use diagnostics::MessageLevel; +pub use shared::SpirvResult; #[derive(Debug, PartialEq)] pub struct Error { @@ -66,7 +66,7 @@ impl std::convert::TryFrom<*mut diagnostics::Diagnostic> for Diagnostic { } } -impl From for Diagnostic{ +impl From for Diagnostic { fn from(message: String) -> Self { Self { line: 0, @@ -90,6 +90,7 @@ impl From for Diagnostic { } } +#[derive(Debug)] pub struct Message { pub level: MessageLevel, pub source: Option, @@ -100,6 +101,7 @@ pub struct Message { } impl Message { + #[cfg(feature = "use-installed")] pub(crate) fn fatal(message: String) -> Self { Self { level: MessageLevel::Fatal, @@ -133,7 +135,11 @@ impl Message { Self { level, - source: if source.is_empty() { None } else { Some(source.into_owned()) }, + source: if source.is_empty() { + None + } else { + Some(source.into_owned()) + }, line, column, index, @@ -142,6 +148,7 @@ impl Message { } } + #[cfg(feature = "use-installed")] pub(crate) fn parse(s: &str) -> Option { s.find(": ") .and_then(|i| { diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index 55a8f0c2e0..4d3c679dda 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -22,7 +22,7 @@ pub struct Options { pub trait Optimizer { fn with_env(target_env: crate::TargetEnv) -> Self; - + fn optimize( &self, input: &[u32], @@ -50,3 +50,17 @@ pub trait Optimizer { /// from time to time. fn register_hlsl_legalization_passes(&mut self) -> &mut Self; } + +pub fn create(te: Option) -> impl Optimizer { + let target_env = te.unwrap_or_default(); + + #[cfg(feature = "use-compiled")] + { + compiled::CompiledOptimizer::with_env(target_env) + } + + #[cfg(all(feature = "use-installed", not(feature = "use-compiled")))] + { + tool::ToolOptimizer::with_env(target_env) + } +} diff --git a/spirv-tools/src/opt/compiled.rs b/spirv-tools/src/opt/compiled.rs index 412c191195..a6aadbd1fe 100644 --- a/spirv-tools/src/opt/compiled.rs +++ b/spirv-tools/src/opt/compiled.rs @@ -44,20 +44,20 @@ impl Drop for Options { } } -pub struct Optimizer { +pub struct CompiledOptimizer { inner: *mut opt::Optimizer, } -impl Optimizer { - #[inline] - pub fn new(target: crate::TargetEnv) -> Self { +use super::Optimizer; + +impl Optimizer for CompiledOptimizer { + fn with_env(target: crate::TargetEnv) -> Self { Self { inner: unsafe { opt::optimizer_create(target) }, } } - #[inline] - pub fn optimize( + fn optimize( &self, input: &[u32], msg_callback: &mut MC, @@ -122,7 +122,9 @@ impl Optimizer { }); } - Ok(crate::binary::Binary::External(crate::binary::external::ExternalBinary::new(binary))) + Ok(crate::binary::Binary::External( + crate::binary::external::ExternalBinary::new(binary), + )) } other => Err(error::Error { inner: other, @@ -134,7 +136,7 @@ impl Optimizer { /// Register a single pass with the the optimizer. #[inline] - pub fn register_pass(&mut self, pass: super::Passes) -> &mut Self { + fn register_pass(&mut self, pass: super::Passes) -> &mut Self { unsafe { opt::optimizer_register_pass(self.inner, pass) } self } @@ -143,7 +145,7 @@ impl Optimizer { /// This sequence of passes is subject to constant review and will change /// from time to time. #[inline] - pub fn register_performance_passes(&mut self) -> &mut Self { + fn register_performance_passes(&mut self) -> &mut Self { unsafe { opt::optimizer_register_performance_passes(self.inner) } self } @@ -152,7 +154,7 @@ impl Optimizer { /// This sequence of passes is subject to constant review and will change /// from time to time. #[inline] - pub fn register_size_passes(&mut self) -> &mut Self { + fn register_size_passes(&mut self) -> &mut Self { unsafe { opt::optimizer_register_size_passes(self.inner) } self } @@ -184,19 +186,19 @@ impl Optimizer { /// This sequence of passes is subject to constant review and will change /// from time to time. #[inline] - pub fn register_hlsl_legalization_passes(&mut self) -> &mut Self { + fn register_hlsl_legalization_passes(&mut self) -> &mut Self { unsafe { opt::optimizer_register_hlsl_legalization_passes(self.inner) } self } } -impl Default for Optimizer { +impl Default for CompiledOptimizer { fn default() -> Self { - Self::new(crate::TargetEnv::default()) + Self::with_env(crate::TargetEnv::default()) } } -impl Drop for Optimizer { +impl Drop for CompiledOptimizer { #[inline] fn drop(&mut self) { unsafe { opt::optimizer_destroy(self.inner) } diff --git a/spirv-tools/src/opt/tool.rs b/spirv-tools/src/opt/tool.rs index 7f1f5ec078..f779b3ced5 100644 --- a/spirv-tools/src/opt/tool.rs +++ b/spirv-tools/src/opt/tool.rs @@ -15,7 +15,10 @@ use super::Optimizer; impl Optimizer for ToolOptimizer { fn with_env(target_env: crate::TargetEnv) -> Self { - Self { target_env, ..Default::default() } + Self { + target_env, + ..Default::default() + } } fn optimize( @@ -27,8 +30,12 @@ impl Optimizer for ToolOptimizer { let mut cmd = std::process::Command::new("spirv-opt"); cmd.arg("--target-env").arg(self.target_env.to_string()); - cmd.args(self.passes.iter().filter_map(|p| pass_to_string(*p).map(|s| format!("--{}", s)))); - + cmd.args( + self.passes + .iter() + .filter_map(|p| pass_to_string(*p).map(|s| format!("--{}", s))), + ); + if self.use_perf_passes { cmd.arg("-O"); } @@ -59,6 +66,8 @@ impl Optimizer for ToolOptimizer { } } + cmd.arg("-o").arg("-"); + let input = crate::util::from_binary(input); let cmd_output = crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Retrieve)?; @@ -175,4 +184,4 @@ fn pass_to_string(pass: super::Passes) -> Option<&'static str> { WrapOpKill => "wrap-opkill", AmdExtToKhr => "amd-ext-to-khr", }) -} \ No newline at end of file +} diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index c1d7067323..c2ace05fe2 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -78,3 +78,17 @@ pub trait Validator: Default { options: Option, ) -> Result<(), crate::error::Error>; } + +pub fn create(te: Option) -> impl Validator { + let target_env = te.unwrap_or_default(); + + #[cfg(feature = "use-compiled")] + { + compiled::CompiledValidator::with_env(target_env) + } + + #[cfg(all(feature = "use-installed", not(feature = "use-compiled")))] + { + tool::ToolValidator::with_env(target_env) + } +} diff --git a/spirv-tools/src/val/tool.rs b/spirv-tools/src/val/tool.rs index 5eb0d5c9f5..649f931268 100644 --- a/spirv-tools/src/val/tool.rs +++ b/spirv-tools/src/val/tool.rs @@ -1,15 +1,18 @@ use std::process::Command; -pub struct Validator { +#[derive(Default)] +pub struct ToolValidator { target_env: crate::TargetEnv, } -impl Validator { - pub fn new(target_env: crate::TargetEnv) -> Self { +use super::Validator; + +impl Validator for ToolValidator { + fn with_env(target_env: crate::TargetEnv) -> Self { Self { target_env } } - pub fn validate( + fn validate( &self, binary: &[u32], options: Option, From 66d4785921d81b76d3efda4f3400700dc25aa373 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 09:09:14 +0100 Subject: [PATCH 24/41] Cleanup CI config * Splits steps to clearly show how long each part of a longer (eg test) step actually takes * Label all steps --- .github/workflows/ci.yaml | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a585f3fd3e..5fc1c35c67 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,16 +20,19 @@ jobs: # Ubuntu does have `brew install spirv-tools`, but it installs from # source and so takes >8 minutes. - if: ${{ runner.os == 'Linux' }} + name: Linux - Install native dependencies run: | sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev mkdir "${HOME}/spirv-tools" curl -fL https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/linux-clang-release/continuous/1305/20201026-063148/install.tgz | tar -xz -C "${HOME}/spirv-tools" echo "${HOME}/spirv-tools/install/bin" >> $GITHUB_PATH - if: ${{ runner.os == 'macOS' }} + name: Mac - Install spirv-tools run: brew install spirv-tools # Currently SPIR-V tools aren't available in any package manager # on Windows that put the tools in the path. - if: ${{ runner.os == 'Windows' }} + name: Windows - Install spirv-tools shell: bash run: | tmparch=$(mktemp) @@ -39,25 +42,45 @@ jobs: - if: ${{ runner.os == 'Windows' }} # Runs separately to add spir-v tools to Powershell's Path. run: echo "$HOME/spirv-tools/install/bin" >> $env:GITHUB_PATH - - run: rustup component add rust-src rustc-dev llvm-tools-preview + - name: Install rustup components + run: rustup component add rust-src rustc-dev llvm-tools-preview + # Fetch dependencies in a separate step to clearly show how long each part + # of the testing takes + - name: cargo fetch + run: cargo fetch # See: https://github.com/EmbarkStudios/rust-gpu/issues/84 - if: ${{ runner.os == 'macOS' }} - run: cargo test --workspace --exclude example-runner + name: Mac build tests + run: cargo test --exclude example-runner --no-run + - if: ${{ runner.os == 'macOS' }} + name: Mac run tests + run: cargo test --exclude example-runner + - if: ${{ runner.os != 'macOS' }} + name: Build tests + run: cargo test --no-run - if: ${{ runner.os != 'macOS' }} - run: cargo test --workspace + name: Run tests + run: cargo test lint: name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev - - run: | + - name: Install native dependencies + run: sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev + - name: Install spirv-tools + run: | mkdir "${HOME}/spirv-tools" curl -fL https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/linux-clang-release/continuous/1305/20201026-063148/install.tgz | tar -xz -C "${HOME}/spirv-tools" echo "${HOME}/spirv-tools/install/bin" >> $GITHUB_PATH - - run: rustup component add rustfmt clippy rust-src rustc-dev llvm-tools-preview - - run: cargo fmt --all -- --check - - run: cargo clippy --workspace --all-targets -- -D warnings + - name: Install rustup components + run: rustup component add rustfmt clippy rust-src rustc-dev llvm-tools-preview + - name: Rustfmt + run: cargo fmt --all -- --check + - name: cargo fetch + run: cargo fetch + - name: Clippy + run: cargo clippy --all-targets -- -D warnings cargo-deny: runs-on: ubuntu-latest From f477b4c9e5f5c3045a43eecb0604e2aa82470ed5 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 09:16:21 +0100 Subject: [PATCH 25/41] Explicitly disable submodule checkout --- .github/workflows/ci.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5fc1c35c67..d67797d07f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,7 +16,12 @@ jobs: env: spirv_tools_version: "20200928" steps: + # Note that we are explicitly NOT checking out submodules, to validate + # that we haven't accidentally enabled spirv-tools native compilation + # and regressed CI times - uses: actions/checkout@v2 + with: + submodules: "false" # Ubuntu does have `brew install spirv-tools`, but it installs from # source and so takes >8 minutes. - if: ${{ runner.os == 'Linux' }} @@ -61,11 +66,17 @@ jobs: - if: ${{ runner.os != 'macOS' }} name: Run tests run: cargo test + lint: name: Lint runs-on: ubuntu-latest steps: + # Note that we are explicitly NOT checking out submodules, to validate + # that we haven't accidentally enabled spirv-tools native compilation + # and regressed CI times - uses: actions/checkout@v2 + with: + submodules: "false" - name: Install native dependencies run: sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev - name: Install spirv-tools From b21e34fa46e96781bedfbc076ee5f4a4aaac1586 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 09:16:49 +0100 Subject: [PATCH 26/41] Rustfmt --- spirv-tools-sys/build.rs | 4 +++- spirv-tools/src/binary.rs | 4 ++-- spirv-tools/src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index a67222d270..39637f7d41 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -219,7 +219,9 @@ fn val(build: &mut Build) { } fn main() { - if std::env::var("CARGO_FEATURE_USE_INSTALLED").is_ok() && std::env::var("CARGO_FEATURE_USE_COMPILED").is_err() { + if std::env::var("CARGO_FEATURE_USE_INSTALLED").is_ok() + && std::env::var("CARGO_FEATURE_USE_COMPILED").is_err() + { println!("use-installed feature on, skipping compilation of C++ code"); return; } diff --git a/spirv-tools/src/binary.rs b/spirv-tools/src/binary.rs index b9d90a2ae1..d032c132bd 100644 --- a/spirv-tools/src/binary.rs +++ b/spirv-tools/src/binary.rs @@ -69,7 +69,7 @@ impl AsRef<[u32]> for Binary { Self::OwnedU8(v) => { // If you hit a panic here it's because try_from wasn't used ;) crate::util::to_binary(&v).unwrap() - }, + } } } } @@ -83,4 +83,4 @@ impl AsRef<[u8]> for Binary { Self::OwnedU8(v) => &v, } } -} \ No newline at end of file +} diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index 41d0f4371d..efe2f87d36 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -1,6 +1,6 @@ pub mod assembler; -pub mod opt; pub mod binary; +pub mod opt; pub mod val; pub mod error; From 302f4c20424a10926f0106ba93f27f987d0bb2d1 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 10:26:35 +0100 Subject: [PATCH 27/41] Rename features for consistency and fix clippy warnings --- examples/example-runner-cpu/Cargo.toml | 1 - examples/example-runner/Cargo.toml | 8 +++++++- examples/wgpu-example-runner/Cargo.toml | 8 +++++++- rustc_codegen_spirv/Cargo.toml | 5 +++-- spirv-builder/Cargo.toml | 8 +++++++- spirv-tools-sys/Cargo.toml | 6 +++--- spirv-tools-sys/build.rs | 6 +++--- spirv-tools/Cargo.toml | 8 ++++---- spirv-tools/src/assembler.rs | 8 ++++---- spirv-tools/src/binary.rs | 12 ++++++------ spirv-tools/src/cmd.rs | 8 ++++---- spirv-tools/src/error.rs | 6 ++++-- spirv-tools/src/lib.rs | 2 +- spirv-tools/src/opt.rs | 8 ++++---- spirv-tools/src/val.rs | 8 ++++---- 15 files changed, 61 insertions(+), 41 deletions(-) diff --git a/examples/example-runner-cpu/Cargo.toml b/examples/example-runner-cpu/Cargo.toml index cc7897c435..347108adfa 100644 --- a/examples/example-runner-cpu/Cargo.toml +++ b/examples/example-runner-cpu/Cargo.toml @@ -14,4 +14,3 @@ spirv-std = { path = "../../spirv-std" } # for parallelism, not really needed though rayon = "1.5" - diff --git a/examples/example-runner/Cargo.toml b/examples/example-runner/Cargo.toml index 071c9059b9..ee4ca501aa 100644 --- a/examples/example-runner/Cargo.toml +++ b/examples/example-runner/Cargo.toml @@ -5,6 +5,12 @@ authors = ["Embark "] edition = "2018" license = "MIT OR Apache-2.0" +# See rustc_codegen_spirv/Cargo.toml for details on these features +[features] +default = ["use-compiled-tools"] +use-installed-tools = ["spirv-builder/use-installed-tools"] +use-compiled-tools = ["spirv-builder/use-compiled-tools"] + [dependencies] ash = "0.31" ash-window = "0.5" @@ -16,4 +22,4 @@ winit = "0.23.0" ash-molten = { git = "https://github.com/EmbarkStudios/ash-molten", branch = "moltenvk-1.1.0" } [build-dependencies] -spirv-builder = { path = "../../spirv-builder" } +spirv-builder = { path = "../../spirv-builder", default-features = false } diff --git a/examples/wgpu-example-runner/Cargo.toml b/examples/wgpu-example-runner/Cargo.toml index 400f8cac68..9e9f070fba 100644 --- a/examples/wgpu-example-runner/Cargo.toml +++ b/examples/wgpu-example-runner/Cargo.toml @@ -5,13 +5,19 @@ authors = ["Embark "] edition = "2018" license = "MIT OR Apache-2.0" +# See rustc_codegen_spirv/Cargo.toml for details on these features +[features] +default = ["use-compiled-tools"] +use-installed-tools = ["spirv-builder/use-installed-tools"] +use-compiled-tools = ["spirv-builder/use-compiled-tools"] + [dependencies] wgpu = "0.6.0" futures = { version = "0.3", default-features = false, features = ["std", "executor"] } winit = { version = "0.22.1", features = ["web-sys"] } [build-dependencies] -spirv-builder = { path = "../../spirv-builder" } +spirv-builder = { path = "../../spirv-builder", default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] wgpu-subscriber = "0.1.0" diff --git a/rustc_codegen_spirv/Cargo.toml b/rustc_codegen_spirv/Cargo.toml index 6c78dbe709..13fa72f1bf 100644 --- a/rustc_codegen_spirv/Cargo.toml +++ b/rustc_codegen_spirv/Cargo.toml @@ -21,10 +21,10 @@ crate-type = ["dylib"] default = ["use-compiled-tools"] # If enabled, uses spirv-tools binaries installed in PATH, instead of # compiling and linking the spirv-tools C++ code -use-installed-tools = ["spirv-tools/use-installed"] +use-installed-tools = ["spirv-tools/use-installed-tools"] # If enabled will compile and link the C++ code for the spirv tools, the compiled # version is preferred if both this and `use-installed-tools` are enabled -use-compiled-tools = ["spirv-tools/use-compiled"] +use-compiled-tools = ["spirv-tools/use-compiled-tools"] [dependencies] bimap = "0.5" @@ -36,6 +36,7 @@ topological-sort = "0.1" [dependencies.spirv-tools] version = "0.1.0" path = "../spirv-tools" +default-features = false [dev-dependencies] pretty_assertions = "0.6" diff --git a/spirv-builder/Cargo.toml b/spirv-builder/Cargo.toml index 4283d52245..4c1bd46244 100644 --- a/spirv-builder/Cargo.toml +++ b/spirv-builder/Cargo.toml @@ -5,13 +5,19 @@ authors = ["Embark "] edition = "2018" license = "MIT OR Apache-2.0" +# See rustc_codegen_spirv/Cargo.toml for details on these features +[features] +default = ["use-compiled-tools"] +use-installed-tools = ["rustc_codegen_spirv/use-installed-tools"] +use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"] + [dependencies] memchr = "2.3" raw-string = "0.3.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # See comment in lib.rs invoke_rustc for why this is here -rustc_codegen_spirv = { path = "../rustc_codegen_spirv" } +rustc_codegen_spirv = { path = "../rustc_codegen_spirv", default-features = false } [dev-dependencies] lazy_static = "1.4" diff --git a/spirv-tools-sys/Cargo.toml b/spirv-tools-sys/Cargo.toml index d6f6fd9821..3404938d57 100644 --- a/spirv-tools-sys/Cargo.toml +++ b/spirv-tools-sys/Cargo.toml @@ -10,9 +10,9 @@ license = "MIT OR Apache-2.0" # Using this feature disables the compilation in the build script, but # preserves the types so that spirv-tools can still work without needing # to keep copies of some of the basic enums etc -use-installed = [] -# Forces compilation of the C++ code, even if `use-installed` is enabled -use-compiled = [] +use-installed-tools = [] +# Forces compilation of the C++ code, even if `use-installed-tools` is enabled +use-compiled-tools = [] [build-dependencies] cc = { version = "1.0", features = ["parallel"] } diff --git a/spirv-tools-sys/build.rs b/spirv-tools-sys/build.rs index 39637f7d41..96d71289d6 100644 --- a/spirv-tools-sys/build.rs +++ b/spirv-tools-sys/build.rs @@ -219,10 +219,10 @@ fn val(build: &mut Build) { } fn main() { - if std::env::var("CARGO_FEATURE_USE_INSTALLED").is_ok() - && std::env::var("CARGO_FEATURE_USE_COMPILED").is_err() + if std::env::var("CARGO_FEATURE_USE_INSTALLED_TOOLS").is_ok() + && std::env::var("CARGO_FEATURE_USE_COMPILED_TOOLS").is_err() { - println!("use-installed feature on, skipping compilation of C++ code"); + println!("cargo:warning=use-installed-tools feature on, skipping compilation of C++ code"); return; } diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index 521c9ca2e7..a1d0558f36 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -6,11 +6,11 @@ edition = "2018" license = "MIT OR Apache-2.0" [features] -use-installed = ["spirv-tools-sys/use-installed", "memchr"] -use-compiled = ["spirv-tools-sys/use-compiled"] +use-installed-tools = ["spirv-tools-sys/use-installed-tools", "memchr"] +use-compiled-tools = ["spirv-tools-sys/use-compiled-tools"] [dependencies] -spirv-tools-sys = { path = "../spirv-tools-sys" } +spirv-tools-sys = { path = "../spirv-tools-sys", default-features = false } # Used for parsing output when running binaries memchr = { version = "2.3", optional = true } @@ -19,4 +19,4 @@ structopt = "0.3" [[example]] name = "as" -required-features = ["use-compiled"] +required-features = ["use-compiled-tools"] diff --git a/spirv-tools/src/assembler.rs b/spirv-tools/src/assembler.rs index d2a874444d..ea209007e4 100644 --- a/spirv-tools/src/assembler.rs +++ b/spirv-tools/src/assembler.rs @@ -1,7 +1,7 @@ -#[cfg(feature = "use-compiled")] +#[cfg(feature = "use-compiled-tools")] pub mod compiled; -#[cfg(feature = "use-installed")] +#[cfg(feature = "use-installed-tools")] pub mod tool; #[derive(Copy, Clone, Default)] @@ -38,12 +38,12 @@ pub trait Assembler: Default { pub fn create(te: Option) -> impl Assembler { let target_env = te.unwrap_or_default(); - #[cfg(feature = "use-compiled")] + #[cfg(feature = "use-compiled-tools")] { compiled::CompiledAssembler::with_env(target_env) } - #[cfg(all(feature = "use-installed", not(feature = "use-compiled")))] + #[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))] { tool::ToolAssembler::with_env(target_env) } diff --git a/spirv-tools/src/binary.rs b/spirv-tools/src/binary.rs index d032c132bd..34b95e30e6 100644 --- a/spirv-tools/src/binary.rs +++ b/spirv-tools/src/binary.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "use-compiled")] +#[cfg(feature = "use-compiled-tools")] pub mod external { use spirv_tools_sys::shared; @@ -39,7 +39,7 @@ pub mod external { } pub enum Binary { - #[cfg(feature = "use-compiled")] + #[cfg(feature = "use-compiled-tools")] External(self::external::ExternalBinary), OwnedU32(Vec), OwnedU8(Vec), @@ -50,10 +50,10 @@ impl std::convert::TryFrom> for Binary { fn try_from(v: Vec) -> Result { if v.len() % std::mem::size_of::() != 0 { - return Err(crate::Error { + Err(crate::Error { inner: spirv_tools_sys::shared::SpirvResult::InvalidBinary, diagnostic: None, - }); + }) } else { Ok(Binary::OwnedU8(v)) } @@ -63,7 +63,7 @@ impl std::convert::TryFrom> for Binary { impl AsRef<[u32]> for Binary { fn as_ref(&self) -> &[u32] { match self { - #[cfg(feature = "use-compiled")] + #[cfg(feature = "use-compiled-tools")] Self::External(bin) => bin.as_ref(), Self::OwnedU32(v) => &v, Self::OwnedU8(v) => { @@ -77,7 +77,7 @@ impl AsRef<[u32]> for Binary { impl AsRef<[u8]> for Binary { fn as_ref(&self) -> &[u8] { match self { - #[cfg(feature = "use-compiled")] + #[cfg(feature = "use-compiled-tools")] Self::External(bin) => bin.as_ref(), Self::OwnedU32(v) => crate::util::from_binary(&v), Self::OwnedU8(v) => &v, diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs index 9e82ffac7a..7ab896ec00 100644 --- a/spirv-tools/src/cmd.rs +++ b/spirv-tools/src/cmd.rs @@ -77,7 +77,7 @@ pub fn exec( cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); - let mut child = cmd.spawn().map_err(|e| CmdError::BinaryNotFound(e))?; + let mut child = cmd.spawn().map_err(CmdError::BinaryNotFound)?; if let Some(input) = input { use std::io::Write; @@ -87,10 +87,10 @@ pub fn exec( .take() .unwrap() .write_all(input) - .map_err(|e| CmdError::Io(e))?; + .map_err(CmdError::Io)?; } - let output = child.wait_with_output().map_err(|e| CmdError::Io(e))?; + let output = child.wait_with_output().map_err(CmdError::Io)?; let code = match output.status.code() { Some(code) => code, @@ -167,7 +167,7 @@ pub fn exec( let mut maybe_msg = true; for line in split(&output.stdout, b'\n') { if maybe_msg { - if let Some(s) = std::str::from_utf8(line).ok() { + if let Ok(s) = std::str::from_utf8(line) { if let Some(msg) = crate::error::Message::parse(s) { messages.push(msg); continue; diff --git a/spirv-tools/src/error.rs b/spirv-tools/src/error.rs index 87b6fc9529..4224bb042f 100644 --- a/spirv-tools/src/error.rs +++ b/spirv-tools/src/error.rs @@ -38,6 +38,7 @@ pub struct Diagnostic { pub is_text: bool, } +#[cfg(feature = "use-compiled-tools")] impl std::convert::TryFrom<*mut diagnostics::Diagnostic> for Diagnostic { type Error = shared::SpirvResult; @@ -101,7 +102,7 @@ pub struct Message { } impl Message { - #[cfg(feature = "use-installed")] + #[cfg(feature = "use-installed-tools")] pub(crate) fn fatal(message: String) -> Self { Self { level: MessageLevel::Fatal, @@ -113,6 +114,7 @@ impl Message { } } + #[cfg(feature = "use-compiled-tools")] pub(crate) fn from_parts( level: MessageLevel, source: *const std::os::raw::c_char, @@ -148,7 +150,7 @@ impl Message { } } - #[cfg(feature = "use-installed")] + #[cfg(feature = "use-installed-tools")] pub(crate) fn parse(s: &str) -> Option { s.find(": ") .and_then(|i| { diff --git a/spirv-tools/src/lib.rs b/spirv-tools/src/lib.rs index efe2f87d36..6b53fa921f 100644 --- a/spirv-tools/src/lib.rs +++ b/spirv-tools/src/lib.rs @@ -8,7 +8,7 @@ pub use error::{Error, SpirvResult}; pub use spirv_tools_sys::shared::TargetEnv; -#[cfg(feature = "use-installed")] +#[cfg(feature = "use-installed-tools")] pub(crate) mod cmd; pub mod util; diff --git a/spirv-tools/src/opt.rs b/spirv-tools/src/opt.rs index 4d3c679dda..07d593e870 100644 --- a/spirv-tools/src/opt.rs +++ b/spirv-tools/src/opt.rs @@ -1,6 +1,6 @@ -#[cfg(feature = "use-compiled")] +#[cfg(feature = "use-compiled-tools")] pub mod compiled; -#[cfg(feature = "use-installed")] +#[cfg(feature = "use-installed-tools")] pub mod tool; pub use spirv_tools_sys::opt::Passes; @@ -54,12 +54,12 @@ pub trait Optimizer { pub fn create(te: Option) -> impl Optimizer { let target_env = te.unwrap_or_default(); - #[cfg(feature = "use-compiled")] + #[cfg(feature = "use-compiled-tools")] { compiled::CompiledOptimizer::with_env(target_env) } - #[cfg(all(feature = "use-installed", not(feature = "use-compiled")))] + #[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))] { tool::ToolOptimizer::with_env(target_env) } diff --git a/spirv-tools/src/val.rs b/spirv-tools/src/val.rs index c2ace05fe2..2892bfdd61 100644 --- a/spirv-tools/src/val.rs +++ b/spirv-tools/src/val.rs @@ -1,6 +1,6 @@ -#[cfg(feature = "use-compiled")] +#[cfg(feature = "use-compiled-tools")] pub mod compiled; -#[cfg(feature = "use-installed")] +#[cfg(feature = "use-installed-tools")] pub mod tool; #[derive(Default, Clone)] @@ -82,12 +82,12 @@ pub trait Validator: Default { pub fn create(te: Option) -> impl Validator { let target_env = te.unwrap_or_default(); - #[cfg(feature = "use-compiled")] + #[cfg(feature = "use-compiled-tools")] { compiled::CompiledValidator::with_env(target_env) } - #[cfg(all(feature = "use-installed", not(feature = "use-compiled")))] + #[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))] { tool::ToolValidator::with_env(target_env) } From c8b3576c0eaab5ab4e06aa7d93984cae862f26fe Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 10:26:52 +0100 Subject: [PATCH 28/41] Split "core" crates from examples --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index cd6dd32345..6303afed05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "examples/wgpu-example-runner", "examples/example-shader", "examples/wgpu-example-shader", + "rustc_codegen_spirv", "spirv-builder", "spirv-std", From d0715f509b685e0012173a7dc635072b885cc230 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 10:27:08 +0100 Subject: [PATCH 29/41] Add run_clippy bash script --- .github/workflows/ci.yaml | 2 +- .github/workflows/run_clippy.sh | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100755 .github/workflows/run_clippy.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d67797d07f..408643ff60 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -91,7 +91,7 @@ jobs: - name: cargo fetch run: cargo fetch - name: Clippy - run: cargo clippy --all-targets -- -D warnings + run: .github/workflows/run_clippy.sh cargo-deny: runs-on: ubuntu-latest diff --git a/.github/workflows/run_clippy.sh b/.github/workflows/run_clippy.sh new file mode 100755 index 0000000000..25a4cea79a --- /dev/null +++ b/.github/workflows/run_clippy.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -ex + +if [[ -z "${CI}" ]]; then + FEAT="use-compiled-tools" +else + FEAT="use-installed-tools" +fi + +function clippy() { + echo ::group::"$1" + cargo clippy \ + --manifest-path "$1/Cargo.toml" \ + --no-default-features \ + --features "$FEAT" \ + --all-targets \ + -- -D warnings + echo ::endgroup:: +} + +function clippy_no_features() { + echo ::group::"$1" + cargo clippy \ + --manifest-path "$1/Cargo.toml" \ + --all-targets \ + -- -D warnings + echo ::endgroup:: +} + +# Core crates +clippy spirv-tools-sys +clippy spirv-tools +clippy rustc_codegen_spirv +clippy spirv-builder + +# Examples +clippy examples/example-runner +clippy examples/wgpu-example-runner + +clippy_no_features examples/example-runner-cpu +clippy_no_features examples/example-shader +clippy_no_features examples/wgpu-example-shader \ No newline at end of file From 500b52a554276539bda10dfcde537d1b5aff8d84 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 11:32:42 +0100 Subject: [PATCH 30/41] Add test script --- .github/workflows/ci.yaml | 17 +----- .../workflows/{run_clippy.sh => clippy.sh} | 2 +- .github/workflows/test.sh | 55 +++++++++++++++++++ 3 files changed, 59 insertions(+), 15 deletions(-) rename .github/workflows/{run_clippy.sh => clippy.sh} (99%) create mode 100755 .github/workflows/test.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 408643ff60..46c603d832 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -53,19 +53,8 @@ jobs: # of the testing takes - name: cargo fetch run: cargo fetch - # See: https://github.com/EmbarkStudios/rust-gpu/issues/84 - - if: ${{ runner.os == 'macOS' }} - name: Mac build tests - run: cargo test --exclude example-runner --no-run - - if: ${{ runner.os == 'macOS' }} - name: Mac run tests - run: cargo test --exclude example-runner - - if: ${{ runner.os != 'macOS' }} - name: Build tests - run: cargo test --no-run - - if: ${{ runner.os != 'macOS' }} - name: Run tests - run: cargo test + - name: Run tests + run: .github/workflows/test.sh lint: name: Lint @@ -91,7 +80,7 @@ jobs: - name: cargo fetch run: cargo fetch - name: Clippy - run: .github/workflows/run_clippy.sh + run: .github/workflows/clippy.sh cargo-deny: runs-on: ubuntu-latest diff --git a/.github/workflows/run_clippy.sh b/.github/workflows/clippy.sh similarity index 99% rename from .github/workflows/run_clippy.sh rename to .github/workflows/clippy.sh index 25a4cea79a..a3374a4444 100755 --- a/.github/workflows/run_clippy.sh +++ b/.github/workflows/clippy.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -ex +set -e if [[ -z "${CI}" ]]; then FEAT="use-compiled-tools" diff --git a/.github/workflows/test.sh b/.github/workflows/test.sh new file mode 100755 index 0000000000..d454245d8a --- /dev/null +++ b/.github/workflows/test.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -ex + +if [[ -z "${CI}" ]]; then + FEAT="use-compiled-tools" +else + FEAT="use-installed-tools" +fi + +os=$1 + +function cargo_test() { + echo ::group::"$1 build" + cargo test \ + --manifest-path "$1/Cargo.toml" \ + --no-default-features \ + --features "$FEAT" \ + --no-run + echo ::endgroup:: + + echo ::group::"$1 test" + cargo test \ + --manifest-path "$1/Cargo.toml" \ + --no-default-features \ + --features "$FEAT" + echo ::endgroup:: +} + +function cargo_test_no_features() { + echo ::group::"$1 build" + cargo test --manifest-path "$1/Cargo.toml" --no-run + echo ::endgroup:: + + echo ::group::"$1 test" + cargo test --manifest-path "$1/Cargo.toml" + echo ::endgroup:: +} + +# Core crates +cargo_test spirv-tools-sys +cargo_test spirv-tools +cargo_test rustc_codegen_spirv +cargo_test spirv-builder + +# Examples +# See: https://github.com/EmbarkStudios/rust-gpu/issues/84 +if [[ -z "${CI}" && "$os" != "macOS" ]]; then + cargo_test examples/example-runner +fi + +cargo_test examples/wgpu-example-runner + +cargo_test_no_features examples/example-runner-cpu +cargo_test_no_features examples/example-shader +cargo_test_no_features examples/wgpu-example-shader From 1a7068823cb315f29326ee6324c96d62f1f30ee4 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 12:09:34 +0100 Subject: [PATCH 31/41] Remove x flag --- .github/workflows/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.sh b/.github/workflows/test.sh index d454245d8a..f4d900b6bf 100755 --- a/.github/workflows/test.sh +++ b/.github/workflows/test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -ex +set -e if [[ -z "${CI}" ]]; then FEAT="use-compiled-tools" From fcf5bd2aa599f4bad93fe67fc3647f1ce58c0ddf Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 13:31:04 +0100 Subject: [PATCH 32/41] Newline --- .github/workflows/clippy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clippy.sh b/.github/workflows/clippy.sh index a3374a4444..bb23186c66 100755 --- a/.github/workflows/clippy.sh +++ b/.github/workflows/clippy.sh @@ -39,4 +39,4 @@ clippy examples/wgpu-example-runner clippy_no_features examples/example-runner-cpu clippy_no_features examples/example-shader -clippy_no_features examples/wgpu-example-shader \ No newline at end of file +clippy_no_features examples/wgpu-example-shader From ca1ab0e3e8688e114140bef7240df6cfef7e5fc3 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 15:07:22 +0100 Subject: [PATCH 33/41] Actually print out errors from running val/opt --- rustc_codegen_spirv/src/link.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 52d7c0f5a5..1c1e7bee84 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -191,8 +191,9 @@ fn do_spirv_opt(sess: &Session, spv_binary: Vec, filename: &Path) -> Vec Vec::from(binary.as_ref()), - Err(_) => { - let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized"); + Err(e) => { + let mut err = sess.struct_warn(&e.to_string()); + err.note("spirv-opt failed, leaving as unoptimized"); err.note(&format!("module {:?}", filename)); spv_binary } @@ -204,8 +205,9 @@ fn do_spirv_val(sess: &Session, spv_binary: &[u32], filename: &Path) { let validator = val::create(None); - if validator.validate(spv_binary, None).is_err() { - let mut err = sess.struct_err("error occurred during validation"); + if let Err(e) = validator.validate(spv_binary, None) { + let mut err = sess.struct_err(&e.to_string()); + err.note("spirv-val failed"); err.note(&format!("module {:?}", filename)); err.emit(); } From 94ccf07a3a7bd34b40694105aacec8b2dcb4aeab Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 15:12:04 +0100 Subject: [PATCH 34/41] Revert drive-by import merging --- rustc_codegen_spirv/src/link.rs | 47 +++++++++++++++------------------ 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/rustc_codegen_spirv/src/link.rs b/rustc_codegen_spirv/src/link.rs index 1c1e7bee84..e5a5913987 100644 --- a/rustc_codegen_spirv/src/link.rs +++ b/rustc_codegen_spirv/src/link.rs @@ -1,31 +1,26 @@ use crate::{linker, SpirvCodegenBackend, SpirvModuleBuffer, SpirvThinBuffer}; -use rustc_codegen_ssa::{ - back::{ - lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}, - write::CodegenContext, - }, - CodegenResults, -}; -use rustc_data_structures::{owning_ref::OwningRef, rustc_erase_owner, sync::MetadataRef}; +use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; +use rustc_codegen_ssa::back::write::CodegenContext; +use rustc_codegen_ssa::CodegenResults; +use rustc_data_structures::owning_ref::OwningRef; +use rustc_data_structures::rustc_erase_owner; +use rustc_data_structures::sync::MetadataRef; use rustc_errors::FatalError; -use rustc_middle::{ - bug, dep_graph::WorkProduct, middle::cstore::NativeLib, middle::dependency_format::Linkage, -}; -use rustc_session::{ - config::{CrateType, Lto, OutputFilenames, OutputType}, - output::{check_file_is_writeable, invalid_output_for_target, out_filename}, - utils::NativeLibKind, - Session, -}; -use std::{ - collections::HashSet, - env, - ffi::{CString, OsStr}, - fs::File, - io::{Read, Write}, - path::{Path, PathBuf}, - sync::Arc, -}; +use rustc_middle::bug; +use rustc_middle::dep_graph::WorkProduct; +use rustc_middle::middle::cstore::NativeLib; +use rustc_middle::middle::dependency_format::Linkage; +use rustc_session::config::{CrateType, Lto, OutputFilenames, OutputType}; +use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; +use rustc_session::utils::NativeLibKind; +use rustc_session::Session; +use std::collections::HashSet; +use std::env; +use std::ffi::{CString, OsStr}; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::sync::Arc; use tar::{Archive, Builder, Header}; pub fn link<'a>( From 938bb1d2d9d5293f07f564748df2c63a5b81a968 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 19:48:46 +0100 Subject: [PATCH 35/41] Change intro to take the changes this PR has into account --- docs/src/introduction.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/src/introduction.md b/docs/src/introduction.md index be9fccc1b3..d76395f7fe 100644 --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -1,4 +1,5 @@ # Introduction + Welcome to the Rust-GPU dev guide! This documentation is meant for documenting how to use and develop on Rust-GPU. @@ -6,21 +7,27 @@ how to use and develop on Rust-GPU. 1. Clone the repository. + ```shell + git clone --recurse-submodules https://github.com/EmbarkStudios.com/rust-gpu + ``` + 1. Install the prerequisites using the provided setup script. From the root of the project, run: MacOS, Linux: + ```shell sh setup.sh ``` Windows: - ``` + + ```shell setup.bat ``` The setup script installs nightly Rust (required for now, see [#78](https://github.com/EmbarkStudios/rust-gpu/issues/78) for tracking issue). -1. Install [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools#downloads) and add it to your PATH (for now, eventually we will automatically build and link it instead of calling executables) +1. **optional** Install [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools#downloads) and add it to your `PATH`. You can skip this step if you just want to run examples with the defaults. See [Using installed SPIRV-Tools](#using-installed-spirv-tools) if you decide to go with this option. 1. Next, look at the [examples](examples) folder. There are two projects here: [examples/example-shader](examples/example-shader) and [examples/example-runner](examples/example-runner). The example-shader project is a "GPU crate", one that will be compiled to a SPIR-V module. The example-runner project is a normal, CPU crate that uses vulkan to consume the example-shader SPIR-V module to display a shader. @@ -36,15 +43,13 @@ how to use and develop on Rust-GPU. Be aware that this project is in a very early phase - if the above doesn't work, please [file an issue](https://github.com/EmbarkStudios/rust-gpu/issues)! -## Getting started, for power users who don't want to use spirv-builder. +## Getting started, for power users who don't want to use spirv-builder If you would like to build the compiler, `rustc_codegen_spirv` is the relevant folder. Install the prerequisites, as above, then, `cd rustc_codegen_spirv && cargo build`. This produces an .so file, located at `./target/debug/librustc_codegen_spirv.so` (or `.dll`/`.dylib` depending on your platform). This file is a dynamically loaded backend for rustc - you may tell rustc to use it as a backend through the `-Z codegen-backend=...` flag. To pass this to rustc through cargo, set the environment variable `RUSTFLAGS="-Z codegen-backend=$PATH_TO_FILE"`. -Then, when building a GPU crate, we need to configure some flags when we call cargo. First, we need to build libcore -ourselves - we obviously have no SPIR-V libcore installed on our system! Use the flag `-Z build-std=core`. Then, we need -to tell rustc to generate SPIR-V instead of x86 code: `--target spirv-unknown-unknown`. +Then, when building a GPU crate, we need to configure some flags when we call cargo. First, we need to build libcore ourselves - we obviously have no SPIR-V libcore installed on our system! Use the flag `-Z build-std=core`. Then, we need to tell rustc to generate SPIR-V instead of x86 code: `--target spirv-unknown-unknown`. Overall, building your own SPIR-V crate looks like: @@ -61,3 +66,15 @@ To create a GPU crate, look at the [examples/example-shader](examples/example-sh This is all a little convoluted, hence the [spirv-builder](spirv-builder) crate handles a lot of this. +## Using installed SPIRV-Tools + +By default, all of the crates and examples in this repo will compile the `spirv-tools-sys` crate, including a lot of C++ code from [SPIRV-Tools](https://github.com/EmbarkStudios/SPIRV-Tools). If you don't want to build the C++ code because you already have [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools#downloads) installed, or just don't want to spend more time compiling, you can build/run the crate with the `use-installed-tools` feature. + +```shell +cargo run \ + --manifest-path examples/example-runner/Cargo.toml \ + --features use-installed-tools \ + --no-default-features +``` + +You should see `warning: use-installed-tools feature on, skipping compilation of C++ code` during the compilation, but otherwise the build will function just the same as if you compiled the C++ code, with the exception that it will fail if you don't have SPIRV-Tools installed correctly. From b6eef4a9cec617c5c7dd195f787ecbd4c03674b2 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 20:00:48 +0100 Subject: [PATCH 36/41] Actually run tests on Windows --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 46c603d832..ea2af002cb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -54,6 +54,7 @@ jobs: - name: cargo fetch run: cargo fetch - name: Run tests + shell: bash run: .github/workflows/test.sh lint: From be6c40478cb6898a6846246a99d32c9fa6e13c25 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 20:01:13 +0100 Subject: [PATCH 37/41] Fetch only the host target to reduce fetch times --- .github/workflows/ci.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ea2af002cb..6f064e1e8b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,7 +11,14 @@ jobs: name: Test strategy: matrix: - os: [macos-latest, ubuntu-latest, windows-latest] + os: [macOS-latest, ubuntu-latest, windows-latest] + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + - os: windows-latest + target: x86_64-pc-windows-msvc + - os: macOS-latest + target: x86_64-apple-darwin runs-on: ${{ matrix.os }} env: spirv_tools_version: "20200928" @@ -52,7 +59,7 @@ jobs: # Fetch dependencies in a separate step to clearly show how long each part # of the testing takes - name: cargo fetch - run: cargo fetch + run: cargo fetch --target ${{ matrix.target }} - name: Run tests shell: bash run: .github/workflows/test.sh From 0b0903af9f8cacce63b0902043d9aad77a4d787a Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 20:12:00 +0100 Subject: [PATCH 38/41] Add more info when a spirv tool returns a non-zero exit code --- spirv-tools/src/cmd.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs index 7ab896ec00..3598b4edf5 100644 --- a/spirv-tools/src/cmd.rs +++ b/spirv-tools/src/cmd.rs @@ -32,7 +32,7 @@ impl From for crate::error::Error { ), }, CmdError::ToolErrors { - exit_code: _, + exit_code, messages, } => { // The C API just puts the last message as the diagnostic, so just do the @@ -40,11 +40,12 @@ impl From for crate::error::Error { let diagnostic = messages .into_iter() .last() - .map(crate::error::Diagnostic::from); + .map(crate::error::Diagnostic::from) + .unwrap_or_else(|| crate::error::Diagnostic::from(format!("tool exited with code {} and no output", exit_code))); Self { inner: SpirvResult::InternalError, // this isn't really correct - diagnostic, + diagnostic: Some(diagnostic), } } } From 68ae91382658a5dd935ba7c7f87f7090dfcd319c Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 20:16:09 +0100 Subject: [PATCH 39/41] Rustfmt --- spirv-tools/src/cmd.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs index 3598b4edf5..294d96cc7c 100644 --- a/spirv-tools/src/cmd.rs +++ b/spirv-tools/src/cmd.rs @@ -41,7 +41,12 @@ impl From for crate::error::Error { .into_iter() .last() .map(crate::error::Diagnostic::from) - .unwrap_or_else(|| crate::error::Diagnostic::from(format!("tool exited with code {} and no output", exit_code))); + .unwrap_or_else(|| { + crate::error::Diagnostic::from(format!( + "tool exited with code {} and no output", + exit_code + )) + }); Self { inner: SpirvResult::InternalError, // this isn't really correct From 034ddad847081d120e5bc1e37cdef3b13370a566 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 20:40:28 +0100 Subject: [PATCH 40/41] Switch tool assembler to use files to see if it fixes windows --- Cargo.lock | 1 + spirv-tools/Cargo.toml | 3 ++- spirv-tools/src/assembler/tool.rs | 19 +++++++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd1ea53e67..448dee46b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2207,6 +2207,7 @@ dependencies = [ "memchr", "spirv-tools-sys", "structopt", + "tempfile", ] [[package]] diff --git a/spirv-tools/Cargo.toml b/spirv-tools/Cargo.toml index a1d0558f36..93eb28fae1 100644 --- a/spirv-tools/Cargo.toml +++ b/spirv-tools/Cargo.toml @@ -6,13 +6,14 @@ edition = "2018" license = "MIT OR Apache-2.0" [features] -use-installed-tools = ["spirv-tools-sys/use-installed-tools", "memchr"] +use-installed-tools = ["spirv-tools-sys/use-installed-tools", "memchr", "tempfile"] use-compiled-tools = ["spirv-tools-sys/use-compiled-tools"] [dependencies] spirv-tools-sys = { path = "../spirv-tools-sys", default-features = false } # Used for parsing output when running binaries memchr = { version = "2.3", optional = true } +tempfile = { version = "3.1", optional = true } [dev-dependencies] structopt = "0.3" diff --git a/spirv-tools/src/assembler/tool.rs b/spirv-tools/src/assembler/tool.rs index 08fc88d806..fab2ca73dc 100644 --- a/spirv-tools/src/assembler/tool.rs +++ b/spirv-tools/src/assembler/tool.rs @@ -14,6 +14,8 @@ impl Assembler for ToolAssembler { text: &str, options: super::AssemblerOptions, ) -> Result { + use crate::cmd::CmdError; + let mut cmd = std::process::Command::new("spirv-as"); cmd.arg("--target-env").arg(self.target_env.to_string()); @@ -21,13 +23,22 @@ impl Assembler for ToolAssembler { cmd.arg("--preserve-numeric-ids"); } - cmd.arg("-o").arg("-"); + let temp_dir = tempfile::tempdir().map_err(CmdError::Io)?; + let output_path = temp_dir.path().join("code.spv"); + cmd.arg("-o").arg(&output_path); + + // Input file + let input_path = temp_dir.path().join("code.txt"); + std::fs::write(&input_path, text).map_err(CmdError::Io)?; + cmd.arg(&input_path); + + let _cmd_output = + crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Ignore)?; - let cmd_output = - crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Retrieve)?; + let binary = std::fs::read(&output_path).map_err(CmdError::Io)?; use std::convert::TryFrom; - crate::binary::Binary::try_from(cmd_output.binary) + crate::binary::Binary::try_from(binary) } } From 52d1f7f2a6a5f62f8f88c33584c732a28ededdc3 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 29 Oct 2020 21:10:32 +0100 Subject: [PATCH 41/41] Use files for input and output for now until I can figure out Windows being dumb --- spirv-tools/src/assembler/tool.rs | 19 ++--------- spirv-tools/src/cmd.rs | 57 +++++++++++++------------------ spirv-tools/src/opt/tool.rs | 2 -- 3 files changed, 27 insertions(+), 51 deletions(-) diff --git a/spirv-tools/src/assembler/tool.rs b/spirv-tools/src/assembler/tool.rs index fab2ca73dc..b543d28ede 100644 --- a/spirv-tools/src/assembler/tool.rs +++ b/spirv-tools/src/assembler/tool.rs @@ -14,8 +14,6 @@ impl Assembler for ToolAssembler { text: &str, options: super::AssemblerOptions, ) -> Result { - use crate::cmd::CmdError; - let mut cmd = std::process::Command::new("spirv-as"); cmd.arg("--target-env").arg(self.target_env.to_string()); @@ -23,22 +21,11 @@ impl Assembler for ToolAssembler { cmd.arg("--preserve-numeric-ids"); } - let temp_dir = tempfile::tempdir().map_err(CmdError::Io)?; - let output_path = temp_dir.path().join("code.spv"); - cmd.arg("-o").arg(&output_path); - - // Input file - let input_path = temp_dir.path().join("code.txt"); - std::fs::write(&input_path, text).map_err(CmdError::Io)?; - cmd.arg(&input_path); - - let _cmd_output = - crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Ignore)?; - - let binary = std::fs::read(&output_path).map_err(CmdError::Io)?; + let cmd_output = + crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Retrieve)?; use std::convert::TryFrom; - crate::binary::Binary::try_from(binary) + crate::binary::Binary::try_from(cmd_output.binary) } } diff --git a/spirv-tools/src/cmd.rs b/spirv-tools/src/cmd.rs index 294d96cc7c..d90687ef23 100644 --- a/spirv-tools/src/cmd.rs +++ b/spirv-tools/src/cmd.rs @@ -77,25 +77,27 @@ pub fn exec( input: Option<&[u8]>, retrieve_output: Output, ) -> Result { - if input.is_some() { - cmd.stdin(Stdio::piped()); - } - cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); - let mut child = cmd.spawn().map_err(CmdError::BinaryNotFound)?; + // Create a temp dir for the input and/or output of the tool + let temp_dir = tempfile::tempdir().map_err(CmdError::Io)?; + + // Output + let output_path = temp_dir.path().join("output"); + if retrieve_output == Output::Retrieve { + cmd.arg("-o").arg(&output_path); + } + // Input if let Some(input) = input { - use std::io::Write; - - child - .stdin - .take() - .unwrap() - .write_all(input) - .map_err(CmdError::Io)?; + let input_path = temp_dir.path().join("input"); + std::fs::write(&input_path, input).map_err(CmdError::Io)?; + + cmd.arg(&input_path); } + let child = cmd.spawn().map_err(CmdError::BinaryNotFound)?; + let output = child.wait_with_output().map_err(CmdError::Io)?; let code = match output.status.code() { @@ -163,35 +165,24 @@ pub fn exec( Split { haystack, needle } } - let retrieve_output = retrieve_output == Output::Retrieve; + let binary = match retrieve_output { + Output::Retrieve => std::fs::read(&output_path).map_err(CmdError::Io)?, + Output::Ignore => Vec::new(), + }; // Since we are retrieving the results via stdout, but it can also contain // diagnostic messages, we need to be careful let mut messages = Vec::new(); - let mut binary = Vec::with_capacity(if retrieve_output { 1024 } else { 0 }); - let mut maybe_msg = true; for line in split(&output.stdout, b'\n') { - if maybe_msg { - if let Ok(s) = std::str::from_utf8(line) { - if let Some(msg) = crate::error::Message::parse(s) { - messages.push(msg); - continue; - } - } - } - - if retrieve_output { - // Handle case where there is a '\n' in the stream, but it's not the - // end of an output message - if !maybe_msg || messages.is_empty() && !binary.is_empty() { - binary.push(b'\n'); + if let Ok(s) = std::str::from_utf8(line) { + if let Some(msg) = crate::error::Message::parse(s) { + messages.push(msg); + continue; } - - binary.extend_from_slice(line); } - maybe_msg = false; + break; } Ok(CmdOutput { binary, messages }) diff --git a/spirv-tools/src/opt/tool.rs b/spirv-tools/src/opt/tool.rs index f779b3ced5..cf28f2a29c 100644 --- a/spirv-tools/src/opt/tool.rs +++ b/spirv-tools/src/opt/tool.rs @@ -66,8 +66,6 @@ impl Optimizer for ToolOptimizer { } } - cmd.arg("-o").arg("-"); - let input = crate::util::from_binary(input); let cmd_output = crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Retrieve)?;