diff --git a/3rdparty/spirv-tools/include/generated/build-version.inc b/3rdparty/spirv-tools/include/generated/build-version.inc index af6113d9f..d0561b53c 100644 --- a/3rdparty/spirv-tools/include/generated/build-version.inc +++ b/3rdparty/spirv-tools/include/generated/build-version.inc @@ -1 +1 @@ -"v2022.5-dev", "SPIRV-Tools v2022.5-dev 01f246880b501c751d62ad543d886e08bfa756b5" +"v2022.5-dev", "SPIRV-Tools v2022.5-dev 466c6a4e95f6c2ebd61040d6fe2f6418e45b7e20" diff --git a/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc b/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc index 88d806909..1a45cbba5 100644 --- a/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc @@ -1,79 +1,81 @@ -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_ArbitraryPrecisionFixedPointINTEL[] = {SpvCapabilityArbitraryPrecisionFixedPointINTEL}; -static const SpvCapability pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL[] = {SpvCapabilityArbitraryPrecisionFloatingPointINTEL}; -static const SpvCapability pygen_variable_caps_AsmINTEL[] = {SpvCapabilityAsmINTEL}; -static const SpvCapability pygen_variable_caps_AtomicFloat16AddEXTAtomicFloat32AddEXTAtomicFloat64AddEXT[] = {SpvCapabilityAtomicFloat16AddEXT, SpvCapabilityAtomicFloat32AddEXT, SpvCapabilityAtomicFloat64AddEXT}; -static const SpvCapability pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXT[] = {SpvCapabilityAtomicFloat16MinMaxEXT, SpvCapabilityAtomicFloat32MinMaxEXT, SpvCapabilityAtomicFloat64MinMaxEXT}; -static const SpvCapability pygen_variable_caps_BindlessTextureNV[] = {SpvCapabilityBindlessTextureNV}; -static const SpvCapability pygen_variable_caps_BlockingPipesINTEL[] = {SpvCapabilityBlockingPipesINTEL}; -static const SpvCapability pygen_variable_caps_CooperativeMatrixNV[] = {SpvCapabilityCooperativeMatrixNV}; -static const SpvCapability pygen_variable_caps_DemoteToHelperInvocation[] = {SpvCapabilityDemoteToHelperInvocation}; -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_DotProduct[] = {SpvCapabilityDotProduct}; -static const SpvCapability pygen_variable_caps_DotProductKHR[] = {SpvCapabilityDotProductKHR}; -static const SpvCapability pygen_variable_caps_ExpectAssumeKHR[] = {SpvCapabilityExpectAssumeKHR}; -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_GroupNonUniformRotateKHR[] = {SpvCapabilityGroupNonUniformRotateKHR}; -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_GroupUniformArithmeticKHR[] = {SpvCapabilityGroupUniformArithmeticKHR}; -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_LongConstantCompositeINTEL[] = {SpvCapabilityLongConstantCompositeINTEL}; -static const SpvCapability pygen_variable_caps_Matrix[] = {SpvCapabilityMatrix}; -static const SpvCapability pygen_variable_caps_MemoryAccessAliasingINTEL[] = {SpvCapabilityMemoryAccessAliasingINTEL}; -static const SpvCapability pygen_variable_caps_MeshShadingEXT[] = {SpvCapabilityMeshShadingEXT}; -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_RayQueryKHR[] = {SpvCapabilityRayQueryKHR}; -static const SpvCapability pygen_variable_caps_RayTracingKHR[] = {SpvCapabilityRayTracingKHR}; -static const SpvCapability pygen_variable_caps_RayTracingKHRRayQueryKHR[] = {SpvCapabilityRayTracingKHR, SpvCapabilityRayQueryKHR}; -static const SpvCapability pygen_variable_caps_RayTracingMotionBlurNV[] = {SpvCapabilityRayTracingMotionBlurNV}; -static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV}; -static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR}; -static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR, SpvCapabilityRayQueryKHR}; -static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader}; -static const SpvCapability pygen_variable_caps_ShaderBitInstructions[] = {SpvCapabilityShader, SpvCapabilityBitInstructions}; -static const SpvCapability pygen_variable_caps_ShaderClockKHR[] = {SpvCapabilityShaderClockKHR}; -static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency}; -static const SpvCapability pygen_variable_caps_SplitBarrierINTEL[] = {SpvCapabilitySplitBarrierINTEL}; -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_USMStorageClassesINTEL[] = {SpvCapabilityUSMStorageClassesINTEL}; -static const SpvCapability pygen_variable_caps_UnstructuredLoopControlsINTEL[] = {SpvCapabilityUnstructuredLoopControlsINTEL}; -static const SpvCapability pygen_variable_caps_VariableLengthArrayINTEL[] = {SpvCapabilityVariableLengthArrayINTEL}; -static const SpvCapability pygen_variable_caps_VectorComputeINTEL[] = {SpvCapabilityVectorComputeINTEL}; +static const spv::Capability pygen_variable_caps_Addresses[] = {spv::Capability::Addresses}; +static const spv::Capability pygen_variable_caps_AddressesPhysicalStorageBufferAddresses[] = {spv::Capability::Addresses, spv::Capability::PhysicalStorageBufferAddresses}; +static const spv::Capability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer[] = {spv::Capability::Addresses, spv::Capability::VariablePointers, spv::Capability::VariablePointersStorageBuffer}; +static const spv::Capability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses[] = {spv::Capability::Addresses, spv::Capability::VariablePointers, spv::Capability::VariablePointersStorageBuffer, spv::Capability::PhysicalStorageBufferAddresses}; +static const spv::Capability pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL[] = {spv::Capability::ArbitraryPrecisionFixedPointINTEL}; +static const spv::Capability pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL[] = {spv::Capability::ArbitraryPrecisionFloatingPointINTEL}; +static const spv::Capability pygen_variable_caps_AsmINTEL[] = {spv::Capability::AsmINTEL}; +static const spv::Capability pygen_variable_caps_AtomicFloat16AddEXTAtomicFloat32AddEXTAtomicFloat64AddEXT[] = {spv::Capability::AtomicFloat16AddEXT, spv::Capability::AtomicFloat32AddEXT, spv::Capability::AtomicFloat64AddEXT}; +static const spv::Capability pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXT[] = {spv::Capability::AtomicFloat16MinMaxEXT, spv::Capability::AtomicFloat32MinMaxEXT, spv::Capability::AtomicFloat64MinMaxEXT}; +static const spv::Capability pygen_variable_caps_BindlessTextureNV[] = {spv::Capability::BindlessTextureNV}; +static const spv::Capability pygen_variable_caps_BlockingPipesINTEL[] = {spv::Capability::BlockingPipesINTEL}; +static const spv::Capability pygen_variable_caps_CooperativeMatrixNV[] = {spv::Capability::CooperativeMatrixNV}; +static const spv::Capability pygen_variable_caps_DemoteToHelperInvocation[] = {spv::Capability::DemoteToHelperInvocation}; +static const spv::Capability pygen_variable_caps_DemoteToHelperInvocationEXT[] = {spv::Capability::DemoteToHelperInvocationEXT}; +static const spv::Capability pygen_variable_caps_DerivativeControl[] = {spv::Capability::DerivativeControl}; +static const spv::Capability pygen_variable_caps_DeviceEnqueue[] = {spv::Capability::DeviceEnqueue}; +static const spv::Capability pygen_variable_caps_DotProduct[] = {spv::Capability::DotProduct}; +static const spv::Capability pygen_variable_caps_DotProductKHR[] = {spv::Capability::DotProductKHR}; +static const spv::Capability pygen_variable_caps_ExpectAssumeKHR[] = {spv::Capability::ExpectAssumeKHR}; +static const spv::Capability pygen_variable_caps_FPGARegINTEL[] = {spv::Capability::FPGARegINTEL}; +static const spv::Capability pygen_variable_caps_FragmentMaskAMD[] = {spv::Capability::FragmentMaskAMD}; +static const spv::Capability pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT[] = {spv::Capability::FragmentShaderSampleInterlockEXT, spv::Capability::FragmentShaderPixelInterlockEXT, spv::Capability::FragmentShaderShadingRateInterlockEXT}; +static const spv::Capability pygen_variable_caps_FunctionPointersINTEL[] = {spv::Capability::FunctionPointersINTEL}; +static const spv::Capability pygen_variable_caps_Geometry[] = {spv::Capability::Geometry}; +static const spv::Capability pygen_variable_caps_GeometryStreams[] = {spv::Capability::GeometryStreams}; +static const spv::Capability pygen_variable_caps_GroupNonUniform[] = {spv::Capability::GroupNonUniform}; +static const spv::Capability pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV[] = {spv::Capability::GroupNonUniformArithmetic, spv::Capability::GroupNonUniformClustered, spv::Capability::GroupNonUniformPartitionedNV}; +static const spv::Capability pygen_variable_caps_GroupNonUniformBallot[] = {spv::Capability::GroupNonUniformBallot}; +static const spv::Capability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {spv::Capability::GroupNonUniformPartitionedNV}; +static const spv::Capability pygen_variable_caps_GroupNonUniformQuad[] = {spv::Capability::GroupNonUniformQuad}; +static const spv::Capability pygen_variable_caps_GroupNonUniformRotateKHR[] = {spv::Capability::GroupNonUniformRotateKHR}; +static const spv::Capability pygen_variable_caps_GroupNonUniformShuffle[] = {spv::Capability::GroupNonUniformShuffle}; +static const spv::Capability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {spv::Capability::GroupNonUniformShuffleRelative}; +static const spv::Capability pygen_variable_caps_GroupNonUniformVote[] = {spv::Capability::GroupNonUniformVote}; +static const spv::Capability pygen_variable_caps_GroupUniformArithmeticKHR[] = {spv::Capability::GroupUniformArithmeticKHR}; +static const spv::Capability pygen_variable_caps_Groups[] = {spv::Capability::Groups}; +static const spv::Capability pygen_variable_caps_ImageFootprintNV[] = {spv::Capability::ImageFootprintNV}; +static const spv::Capability pygen_variable_caps_ImageQuery[] = {spv::Capability::ImageQuery}; +static const spv::Capability pygen_variable_caps_IntegerFunctions2INTEL[] = {spv::Capability::IntegerFunctions2INTEL}; +static const spv::Capability pygen_variable_caps_Kernel[] = {spv::Capability::Kernel}; +static const spv::Capability pygen_variable_caps_KernelImageQuery[] = {spv::Capability::Kernel, spv::Capability::ImageQuery}; +static const spv::Capability pygen_variable_caps_LiteralSampler[] = {spv::Capability::LiteralSampler}; +static const spv::Capability pygen_variable_caps_LongConstantCompositeINTEL[] = {spv::Capability::LongConstantCompositeINTEL}; +static const spv::Capability pygen_variable_caps_Matrix[] = {spv::Capability::Matrix}; +static const spv::Capability pygen_variable_caps_MemoryAccessAliasingINTEL[] = {spv::Capability::MemoryAccessAliasingINTEL}; +static const spv::Capability pygen_variable_caps_MeshShadingEXT[] = {spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_MeshShadingNV[] = {spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_NamedBarrier[] = {spv::Capability::NamedBarrier}; +static const spv::Capability pygen_variable_caps_PipeStorage[] = {spv::Capability::PipeStorage}; +static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes}; +static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv::Capability::RayTracingMotionBlurNV}; +static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV}; +static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader}; +static const spv::Capability pygen_variable_caps_ShaderBitInstructions[] = {spv::Capability::Shader, spv::Capability::BitInstructions}; +static const spv::Capability pygen_variable_caps_ShaderClockKHR[] = {spv::Capability::ShaderClockKHR}; +static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNV[] = {spv::Capability::ShaderInvocationReorderNV}; +static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV[] = {spv::Capability::ShaderInvocationReorderNV, spv::Capability::RayTracingMotionBlurNV}; +static const spv::Capability pygen_variable_caps_SparseResidency[] = {spv::Capability::SparseResidency}; +static const spv::Capability pygen_variable_caps_SplitBarrierINTEL[] = {spv::Capability::SplitBarrierINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {spv::Capability::SubgroupAvcMotionEstimationINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {spv::Capability::SubgroupAvcMotionEstimationINTEL, spv::Capability::SubgroupAvcMotionEstimationChromaINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL[] = {spv::Capability::SubgroupAvcMotionEstimationINTEL, spv::Capability::SubgroupAvcMotionEstimationIntraINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupBallotKHR[] = {spv::Capability::SubgroupBallotKHR}; +static const spv::Capability pygen_variable_caps_SubgroupBufferBlockIOINTEL[] = {spv::Capability::SubgroupBufferBlockIOINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupDispatch[] = {spv::Capability::SubgroupDispatch}; +static const spv::Capability pygen_variable_caps_SubgroupImageBlockIOINTEL[] = {spv::Capability::SubgroupImageBlockIOINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupImageMediaBlockIOINTEL[] = {spv::Capability::SubgroupImageMediaBlockIOINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupShuffleINTEL[] = {spv::Capability::SubgroupShuffleINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupVoteKHR[] = {spv::Capability::SubgroupVoteKHR}; +static const spv::Capability pygen_variable_caps_USMStorageClassesINTEL[] = {spv::Capability::USMStorageClassesINTEL}; +static const spv::Capability pygen_variable_caps_UnstructuredLoopControlsINTEL[] = {spv::Capability::UnstructuredLoopControlsINTEL}; +static const spv::Capability pygen_variable_caps_VariableLengthArrayINTEL[] = {spv::Capability::VariableLengthArrayINTEL}; +static const spv::Capability pygen_variable_caps_VectorComputeINTEL[] = {spv::Capability::VectorComputeINTEL}; 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}; @@ -106,674 +108,707 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footpri static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned}; static const spv_opcode_desc_t kOpcodeTableEntries[] = { - {"Nop", 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), SPV_SPIRV_VERSION_WORD(1,5)}, - {"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, 2, pygen_variable_caps_ShaderBitInstructions, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"BitFieldSExtract", SpvOpBitFieldSExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"BitFieldUExtract", SpvOpBitFieldUExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"BitReverse", SpvOpBitReverse, 2, pygen_variable_caps_ShaderBitInstructions, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"BitCount", 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, SPV_SPIRV_VERSION_WORD(1,6), 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}, - {"GroupNonUniformRotateKHR", SpvOpGroupNonUniformRotateKHR, 1, pygen_variable_caps_GroupNonUniformRotateKHR, 6, {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_OPTIONAL_ID}, 1, 1, 0, nullptr, 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}, - {"TraceRayKHR", SpvOpTraceRayKHR, 1, pygen_variable_caps_RayTracingKHR, 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, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"ExecuteCallableKHR", SpvOpExecuteCallableKHR, 1, pygen_variable_caps_RayTracingKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"ConvertUToAccelerationStructureKHR", SpvOpConvertUToAccelerationStructureKHR, 2, pygen_variable_caps_RayTracingKHRRayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, - {"IgnoreIntersectionKHR", SpvOpIgnoreIntersectionKHR, 1, pygen_variable_caps_RayTracingKHR, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"TerminateRayKHR", SpvOpTerminateRayKHR, 1, pygen_variable_caps_RayTracingKHR, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"SDot", SpvOpSDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SDotKHR", SpvOpSDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"UDot", SpvOpUDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"UDotKHR", SpvOpUDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SUDot", SpvOpSUDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SUDotKHR", SpvOpSUDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SDotAccSat", SpvOpSDotAccSat, 1, pygen_variable_caps_DotProduct, 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_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SDotAccSatKHR", SpvOpSDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 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_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"UDotAccSat", SpvOpUDotAccSat, 1, pygen_variable_caps_DotProduct, 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_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"UDotAccSatKHR", SpvOpUDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 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_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SUDotAccSat", SpvOpSUDotAccSat, 1, pygen_variable_caps_DotProduct, 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_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"SUDotAccSatKHR", SpvOpSUDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 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_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"TypeRayQueryKHR", SpvOpTypeRayQueryKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, - {"RayQueryInitializeKHR", SpvOpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryKHR, 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_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, - {"RayQueryGenerateIntersectionKHR", SpvOpRayQueryGenerateIntersectionKHR, 1, pygen_variable_caps_RayQueryKHR, 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_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, - {"RayQueryProceedKHR", SpvOpRayQueryProceedKHR, 1, pygen_variable_caps_RayQueryKHR, 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_RayQueryKHR, 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}, - {"EmitMeshTasksEXT", SpvOpEmitMeshTasksEXT, 1, pygen_variable_caps_MeshShadingEXT, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"SetMeshOutputsEXT", SpvOpSetMeshOutputsEXT, 1, pygen_variable_caps_MeshShadingEXT, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 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_RayTracingNVRayTracingKHR, 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_RayTracingNVRayTracingKHR, 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}, - {"IgnoreIntersectionNV", SpvOpIgnoreIntersectionNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"TerminateRayNV", SpvOpTerminateRayNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"TraceNV", SpvOpTraceNV, 1, pygen_variable_caps_RayTracingNV, 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, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, - {"TraceMotionNV", SpvOpTraceMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu}, - {"TraceRayMotionNV", SpvOpTraceRayMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu}, - {"TypeAccelerationStructureKHR", SpvOpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 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_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, - {"ExecuteCallableNV", SpvOpExecuteCallableNV, 1, pygen_variable_caps_RayTracingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_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}, - {"DemoteToHelperInvocation", SpvOpDemoteToHelperInvocation, 1, pygen_variable_caps_DemoteToHelperInvocation, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, - {"DemoteToHelperInvocationEXT", SpvOpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 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}, - {"ConvertUToImageNV", SpvOpConvertUToImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ConvertUToSamplerNV", SpvOpConvertUToSamplerNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ConvertImageToUNV", SpvOpConvertImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ConvertSamplerToUNV", SpvOpConvertSamplerToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ConvertUToSampledImageNV", SpvOpConvertUToSampledImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ConvertSampledImageToUNV", SpvOpConvertSampledImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"SamplerImageAddressingModeNV", SpvOpSamplerImageAddressingModeNV, 1, pygen_variable_caps_BindlessTextureNV, 1, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, 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}, - {"ConstantFunctionPointerINTEL", SpvOpConstantFunctionPointerINTEL, 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}, - {"AsmTargetINTEL", SpvOpAsmTargetINTEL, 1, pygen_variable_caps_AsmINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"AsmINTEL", SpvOpAsmINTEL, 1, pygen_variable_caps_AsmINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"AsmCallINTEL", SpvOpAsmCallINTEL, 1, pygen_variable_caps_AsmINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"AtomicFMinEXT", SpvOpAtomicFMinEXT, 3, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXT, 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, 0xffffffffu, 0xffffffffu}, - {"AtomicFMaxEXT", SpvOpAtomicFMaxEXT, 3, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXT, 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, 0xffffffffu, 0xffffffffu}, - {"AssumeTrueKHR", SpvOpAssumeTrueKHR, 1, pygen_variable_caps_ExpectAssumeKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_expect_assume, 0xffffffffu, 0xffffffffu}, - {"ExpectKHR", SpvOpExpectKHR, 1, pygen_variable_caps_ExpectAssumeKHR, 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_expect_assume, 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}, - {"VariableLengthArrayINTEL", SpvOpVariableLengthArrayINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"SaveMemoryINTEL", SpvOpSaveMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"RestoreMemoryINTEL", SpvOpRestoreMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatSinCosPiINTEL", SpvOpArbitraryFloatSinCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatCastINTEL", SpvOpArbitraryFloatCastINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatCastFromIntINTEL", SpvOpArbitraryFloatCastFromIntINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatCastToIntINTEL", SpvOpArbitraryFloatCastToIntINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatAddINTEL", SpvOpArbitraryFloatAddINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatSubINTEL", SpvOpArbitraryFloatSubINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatMulINTEL", SpvOpArbitraryFloatMulINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatDivINTEL", SpvOpArbitraryFloatDivINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatGTINTEL", SpvOpArbitraryFloatGTINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatGEINTEL", SpvOpArbitraryFloatGEINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatLTINTEL", SpvOpArbitraryFloatLTINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatLEINTEL", SpvOpArbitraryFloatLEINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatEQINTEL", SpvOpArbitraryFloatEQINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatRecipINTEL", SpvOpArbitraryFloatRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatRSqrtINTEL", SpvOpArbitraryFloatRSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatCbrtINTEL", SpvOpArbitraryFloatCbrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatHypotINTEL", SpvOpArbitraryFloatHypotINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatSqrtINTEL", SpvOpArbitraryFloatSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatLogINTEL", SpvOpArbitraryFloatLogINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatLog2INTEL", SpvOpArbitraryFloatLog2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatLog10INTEL", SpvOpArbitraryFloatLog10INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatLog1pINTEL", SpvOpArbitraryFloatLog1pINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatExpINTEL", SpvOpArbitraryFloatExpINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatExp2INTEL", SpvOpArbitraryFloatExp2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatExp10INTEL", SpvOpArbitraryFloatExp10INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatExpm1INTEL", SpvOpArbitraryFloatExpm1INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatSinINTEL", SpvOpArbitraryFloatSinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatCosINTEL", SpvOpArbitraryFloatCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatSinCosINTEL", SpvOpArbitraryFloatSinCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatSinPiINTEL", SpvOpArbitraryFloatSinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatCosPiINTEL", SpvOpArbitraryFloatCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatASinINTEL", SpvOpArbitraryFloatASinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatASinPiINTEL", SpvOpArbitraryFloatASinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatACosINTEL", SpvOpArbitraryFloatACosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatACosPiINTEL", SpvOpArbitraryFloatACosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatATanINTEL", SpvOpArbitraryFloatATanINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatATanPiINTEL", SpvOpArbitraryFloatATanPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatATan2INTEL", SpvOpArbitraryFloatATan2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatPowINTEL", SpvOpArbitraryFloatPowINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatPowRINTEL", SpvOpArbitraryFloatPowRINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ArbitraryFloatPowNINTEL", SpvOpArbitraryFloatPowNINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 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}, - {"AliasDomainDeclINTEL", SpvOpAliasDomainDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, - {"AliasScopeDeclINTEL", SpvOpAliasScopeDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, - {"AliasScopeListDeclINTEL", SpvOpAliasScopeListDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, - {"FixedSqrtINTEL", SpvOpFixedSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedRecipINTEL", SpvOpFixedRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedRsqrtINTEL", SpvOpFixedRsqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedSinINTEL", SpvOpFixedSinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedCosINTEL", SpvOpFixedCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedSinCosINTEL", SpvOpFixedSinCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedSinPiINTEL", SpvOpFixedSinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedCosPiINTEL", SpvOpFixedCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedSinCosPiINTEL", SpvOpFixedSinCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedLogINTEL", SpvOpFixedLogINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"FixedExpINTEL", SpvOpFixedExpINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"PtrCastToCrossWorkgroupINTEL", SpvOpPtrCastToCrossWorkgroupINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"CrossWorkgroupCastToPtrINTEL", SpvOpCrossWorkgroupCastToPtrINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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_RayQueryKHR, 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, 3, pygen_variable_caps_AtomicFloat16AddEXTAtomicFloat32AddEXTAtomicFloat64AddEXT, 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}, - {"TypeBufferSurfaceINTEL", SpvOpTypeBufferSurfaceINTEL, 1, pygen_variable_caps_VectorComputeINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"TypeStructContinuedINTEL", SpvOpTypeStructContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ConstantCompositeContinuedINTEL", SpvOpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"SpecConstantCompositeContinuedINTEL", SpvOpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ControlBarrierArriveINTEL", SpvOpControlBarrierArriveINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"ControlBarrierWaitINTEL", SpvOpControlBarrierWaitINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, - {"GroupIMulKHR", SpvOpGroupIMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupFMulKHR", SpvOpGroupFMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupBitwiseAndKHR", SpvOpGroupBitwiseAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupBitwiseOrKHR", SpvOpGroupBitwiseOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupBitwiseXorKHR", SpvOpGroupBitwiseXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupLogicalAndKHR", SpvOpGroupLogicalAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupLogicalOrKHR", SpvOpGroupLogicalOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, - {"GroupLogicalXorKHR", SpvOpGroupLogicalXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu} + {"Nop", spv::Op::OpNop, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Undef", spv::Op::OpUndef, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SourceContinued", spv::Op::OpSourceContinued, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Source", spv::Op::OpSource, 0, nullptr, 4, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SourceExtension", spv::Op::OpSourceExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Name", spv::Op::OpName, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MemberName", spv::Op::OpMemberName, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"String", spv::Op::OpString, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Line", spv::Op::OpLine, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Extension", spv::Op::OpExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ExtInstImport", spv::Op::OpExtInstImport, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ExtInst", spv::Op::OpExtInst, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MemoryModel", spv::Op::OpMemoryModel, 0, nullptr, 2, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, SPV_OPERAND_TYPE_MEMORY_MODEL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EntryPoint", spv::Op::OpEntryPoint, 0, nullptr, 4, {SPV_OPERAND_TYPE_EXECUTION_MODEL, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ExecutionMode", spv::Op::OpExecutionMode, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Capability", spv::Op::OpCapability, 0, nullptr, 1, {SPV_OPERAND_TYPE_CAPABILITY}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeVoid", spv::Op::OpTypeVoid, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeBool", spv::Op::OpTypeBool, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeInt", spv::Op::OpTypeInt, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeFloat", spv::Op::OpTypeFloat, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeVector", spv::Op::OpTypeVector, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeMatrix", spv::Op::OpTypeMatrix, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeImage", spv::Op::OpTypeImage, 0, nullptr, 9, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeSampler", spv::Op::OpTypeSampler, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeSampledImage", spv::Op::OpTypeSampledImage, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeArray", spv::Op::OpTypeArray, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeRuntimeArray", spv::Op::OpTypeRuntimeArray, 1, pygen_variable_caps_Shader, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeStruct", spv::Op::OpTypeStruct, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeOpaque", spv::Op::OpTypeOpaque, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypePointer", spv::Op::OpTypePointer, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeFunction", spv::Op::OpTypeFunction, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeEvent", spv::Op::OpTypeEvent, 1, pygen_variable_caps_Kernel, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeDeviceEvent", spv::Op::OpTypeDeviceEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeReserveId", spv::Op::OpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeQueue", spv::Op::OpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypePipe", spv::Op::OpTypePipe, 1, pygen_variable_caps_Pipes, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"TypeForwardPointer", spv::Op::OpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstantTrue", spv::Op::OpConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstantFalse", spv::Op::OpConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Constant", spv::Op::OpConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstantComposite", spv::Op::OpConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstantSampler", spv::Op::OpConstantSampler, 1, pygen_variable_caps_LiteralSampler, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConstantNull", spv::Op::OpConstantNull, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpecConstantTrue", spv::Op::OpSpecConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpecConstantFalse", spv::Op::OpSpecConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpecConstant", spv::Op::OpSpecConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpecConstantComposite", spv::Op::OpSpecConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SpecConstantOp", spv::Op::OpSpecConstantOp, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Function", spv::Op::OpFunction, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_FUNCTION_CONTROL, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FunctionParameter", spv::Op::OpFunctionParameter, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FunctionEnd", spv::Op::OpFunctionEnd, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FunctionCall", spv::Op::OpFunctionCall, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Variable", spv::Op::OpVariable, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageTexelPointer", spv::Op::OpImageTexelPointer, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Load", spv::Op::OpLoad, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Store", spv::Op::OpStore, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CopyMemory", spv::Op::OpCopyMemory, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CopyMemorySized", spv::Op::OpCopyMemorySized, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AccessChain", spv::Op::OpAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InBoundsAccessChain", spv::Op::OpInBoundsAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PtrAccessChain", spv::Op::OpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ArrayLength", spv::Op::OpArrayLength, 1, pygen_variable_caps_Shader, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GenericPtrMemSemantics", spv::Op::OpGenericPtrMemSemantics, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"InBoundsPtrAccessChain", spv::Op::OpInBoundsPtrAccessChain, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Decorate", spv::Op::OpDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MemberDecorate", spv::Op::OpMemberDecorate, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DecorationGroup", spv::Op::OpDecorationGroup, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupDecorate", spv::Op::OpGroupDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupMemberDecorate", spv::Op::OpGroupMemberDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VectorExtractDynamic", spv::Op::OpVectorExtractDynamic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VectorInsertDynamic", spv::Op::OpVectorInsertDynamic, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VectorShuffle", spv::Op::OpVectorShuffle, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CompositeConstruct", spv::Op::OpCompositeConstruct, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CompositeExtract", spv::Op::OpCompositeExtract, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CompositeInsert", spv::Op::OpCompositeInsert, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CopyObject", spv::Op::OpCopyObject, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Transpose", spv::Op::OpTranspose, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SampledImage", spv::Op::OpSampledImage, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleImplicitLod", spv::Op::OpImageSampleImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleExplicitLod", spv::Op::OpImageSampleExplicitLod, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleDrefImplicitLod", spv::Op::OpImageSampleDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleDrefExplicitLod", spv::Op::OpImageSampleDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleProjImplicitLod", spv::Op::OpImageSampleProjImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleProjExplicitLod", spv::Op::OpImageSampleProjExplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleProjDrefImplicitLod", spv::Op::OpImageSampleProjDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSampleProjDrefExplicitLod", spv::Op::OpImageSampleProjDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageFetch", spv::Op::OpImageFetch, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageGather", spv::Op::OpImageGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageDrefGather", spv::Op::OpImageDrefGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageRead", spv::Op::OpImageRead, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageWrite", spv::Op::OpImageWrite, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Image", spv::Op::OpImage, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQueryFormat", spv::Op::OpImageQueryFormat, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQueryOrder", spv::Op::OpImageQueryOrder, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQuerySizeLod", spv::Op::OpImageQuerySizeLod, 2, pygen_variable_caps_KernelImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQuerySize", spv::Op::OpImageQuerySize, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQueryLod", spv::Op::OpImageQueryLod, 1, pygen_variable_caps_ImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQueryLevels", spv::Op::OpImageQueryLevels, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageQuerySamples", spv::Op::OpImageQuerySamples, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConvertFToU", spv::Op::OpConvertFToU, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConvertFToS", spv::Op::OpConvertFToS, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConvertSToF", spv::Op::OpConvertSToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConvertUToF", spv::Op::OpConvertUToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UConvert", spv::Op::OpUConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SConvert", spv::Op::OpSConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FConvert", spv::Op::OpFConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"QuantizeToF16", spv::Op::OpQuantizeToF16, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConvertPtrToU", spv::Op::OpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SatConvertSToU", spv::Op::OpSatConvertSToU, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SatConvertUToS", spv::Op::OpSatConvertUToS, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ConvertUToPtr", spv::Op::OpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PtrCastToGeneric", spv::Op::OpPtrCastToGeneric, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GenericCastToPtr", spv::Op::OpGenericCastToPtr, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GenericCastToPtrExplicit", spv::Op::OpGenericCastToPtrExplicit, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Bitcast", spv::Op::OpBitcast, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SNegate", spv::Op::OpSNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FNegate", spv::Op::OpFNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IAdd", spv::Op::OpIAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FAdd", spv::Op::OpFAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ISub", spv::Op::OpISub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FSub", spv::Op::OpFSub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IMul", spv::Op::OpIMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FMul", spv::Op::OpFMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UDiv", spv::Op::OpUDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SDiv", spv::Op::OpSDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FDiv", spv::Op::OpFDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UMod", spv::Op::OpUMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SRem", spv::Op::OpSRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SMod", spv::Op::OpSMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FRem", spv::Op::OpFRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FMod", spv::Op::OpFMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VectorTimesScalar", spv::Op::OpVectorTimesScalar, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MatrixTimesScalar", spv::Op::OpMatrixTimesScalar, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VectorTimesMatrix", spv::Op::OpVectorTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MatrixTimesVector", spv::Op::OpMatrixTimesVector, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MatrixTimesMatrix", spv::Op::OpMatrixTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"OuterProduct", spv::Op::OpOuterProduct, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Dot", spv::Op::OpDot, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IAddCarry", spv::Op::OpIAddCarry, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ISubBorrow", spv::Op::OpISubBorrow, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UMulExtended", spv::Op::OpUMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SMulExtended", spv::Op::OpSMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Any", spv::Op::OpAny, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"All", spv::Op::OpAll, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IsNan", spv::Op::OpIsNan, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IsInf", spv::Op::OpIsInf, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IsFinite", spv::Op::OpIsFinite, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IsNormal", spv::Op::OpIsNormal, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignBitSet", spv::Op::OpSignBitSet, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LessOrGreater", spv::Op::OpLessOrGreater, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), SPV_SPIRV_VERSION_WORD(1,5)}, + {"Ordered", spv::Op::OpOrdered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unordered", spv::Op::OpUnordered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LogicalEqual", spv::Op::OpLogicalEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LogicalNotEqual", spv::Op::OpLogicalNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LogicalOr", spv::Op::OpLogicalOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LogicalAnd", spv::Op::OpLogicalAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LogicalNot", spv::Op::OpLogicalNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Select", spv::Op::OpSelect, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IEqual", spv::Op::OpIEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"INotEqual", spv::Op::OpINotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UGreaterThan", spv::Op::OpUGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SGreaterThan", spv::Op::OpSGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UGreaterThanEqual", spv::Op::OpUGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SGreaterThanEqual", spv::Op::OpSGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ULessThan", spv::Op::OpULessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SLessThan", spv::Op::OpSLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ULessThanEqual", spv::Op::OpULessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SLessThanEqual", spv::Op::OpSLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FOrdEqual", spv::Op::OpFOrdEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FUnordEqual", spv::Op::OpFUnordEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FOrdNotEqual", spv::Op::OpFOrdNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FUnordNotEqual", spv::Op::OpFUnordNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FOrdLessThan", spv::Op::OpFOrdLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FUnordLessThan", spv::Op::OpFUnordLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FOrdGreaterThan", spv::Op::OpFOrdGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FUnordGreaterThan", spv::Op::OpFUnordGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FOrdLessThanEqual", spv::Op::OpFOrdLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FUnordLessThanEqual", spv::Op::OpFUnordLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FOrdGreaterThanEqual", spv::Op::OpFOrdGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FUnordGreaterThanEqual", spv::Op::OpFUnordGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ShiftRightLogical", spv::Op::OpShiftRightLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ShiftRightArithmetic", spv::Op::OpShiftRightArithmetic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ShiftLeftLogical", spv::Op::OpShiftLeftLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitwiseOr", spv::Op::OpBitwiseOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitwiseXor", spv::Op::OpBitwiseXor, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitwiseAnd", spv::Op::OpBitwiseAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Not", spv::Op::OpNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitFieldInsert", spv::Op::OpBitFieldInsert, 2, pygen_variable_caps_ShaderBitInstructions, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitFieldSExtract", spv::Op::OpBitFieldSExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitFieldUExtract", spv::Op::OpBitFieldUExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitReverse", spv::Op::OpBitReverse, 2, pygen_variable_caps_ShaderBitInstructions, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitCount", spv::Op::OpBitCount, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DPdx", spv::Op::OpDPdx, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DPdy", spv::Op::OpDPdy, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Fwidth", spv::Op::OpFwidth, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DPdxFine", spv::Op::OpDPdxFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DPdyFine", spv::Op::OpDPdyFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FwidthFine", spv::Op::OpFwidthFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DPdxCoarse", spv::Op::OpDPdxCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"DPdyCoarse", spv::Op::OpDPdyCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FwidthCoarse", spv::Op::OpFwidthCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EmitVertex", spv::Op::OpEmitVertex, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EndPrimitive", spv::Op::OpEndPrimitive, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EmitStreamVertex", spv::Op::OpEmitStreamVertex, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EndStreamPrimitive", spv::Op::OpEndStreamPrimitive, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ControlBarrier", spv::Op::OpControlBarrier, 0, nullptr, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"MemoryBarrier", spv::Op::OpMemoryBarrier, 0, nullptr, 2, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicLoad", spv::Op::OpAtomicLoad, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicStore", spv::Op::OpAtomicStore, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicExchange", spv::Op::OpAtomicExchange, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicCompareExchange", spv::Op::OpAtomicCompareExchange, 0, nullptr, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicCompareExchangeWeak", spv::Op::OpAtomicCompareExchangeWeak, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), SPV_SPIRV_VERSION_WORD(1,3)}, + {"AtomicIIncrement", spv::Op::OpAtomicIIncrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicIDecrement", spv::Op::OpAtomicIDecrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicIAdd", spv::Op::OpAtomicIAdd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicISub", spv::Op::OpAtomicISub, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicSMin", spv::Op::OpAtomicSMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicUMin", spv::Op::OpAtomicUMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicSMax", spv::Op::OpAtomicSMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicUMax", spv::Op::OpAtomicUMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicAnd", spv::Op::OpAtomicAnd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicOr", spv::Op::OpAtomicOr, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicXor", spv::Op::OpAtomicXor, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Phi", spv::Op::OpPhi, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LoopMerge", spv::Op::OpLoopMerge, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LOOP_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SelectionMerge", spv::Op::OpSelectionMerge, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SELECTION_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Label", spv::Op::OpLabel, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Branch", spv::Op::OpBranch, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BranchConditional", spv::Op::OpBranchConditional, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Switch", spv::Op::OpSwitch, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Kill", spv::Op::OpKill, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Return", spv::Op::OpReturn, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReturnValue", spv::Op::OpReturnValue, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unreachable", spv::Op::OpUnreachable, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LifetimeStart", spv::Op::OpLifetimeStart, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"LifetimeStop", spv::Op::OpLifetimeStop, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupAsyncCopy", spv::Op::OpGroupAsyncCopy, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupWaitEvents", spv::Op::OpGroupWaitEvents, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupAll", spv::Op::OpGroupAll, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupAny", spv::Op::OpGroupAny, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupBroadcast", spv::Op::OpGroupBroadcast, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupIAdd", spv::Op::OpGroupIAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupFAdd", spv::Op::OpGroupFAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupFMin", spv::Op::OpGroupFMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupUMin", spv::Op::OpGroupUMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupSMin", spv::Op::OpGroupSMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupFMax", spv::Op::OpGroupFMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupUMax", spv::Op::OpGroupUMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupSMax", spv::Op::OpGroupSMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReadPipe", spv::Op::OpReadPipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"WritePipe", spv::Op::OpWritePipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReservedReadPipe", spv::Op::OpReservedReadPipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReservedWritePipe", spv::Op::OpReservedWritePipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReserveReadPipePackets", spv::Op::OpReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReserveWritePipePackets", spv::Op::OpReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CommitReadPipe", spv::Op::OpCommitReadPipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CommitWritePipe", spv::Op::OpCommitWritePipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IsValidReserveId", spv::Op::OpIsValidReserveId, 1, pygen_variable_caps_Pipes, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetNumPipePackets", spv::Op::OpGetNumPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetMaxPipePackets", spv::Op::OpGetMaxPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupReserveReadPipePackets", spv::Op::OpGroupReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupReserveWritePipePackets", spv::Op::OpGroupReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupCommitReadPipe", spv::Op::OpGroupCommitReadPipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GroupCommitWritePipe", spv::Op::OpGroupCommitWritePipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EnqueueMarker", spv::Op::OpEnqueueMarker, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"EnqueueKernel", spv::Op::OpEnqueueKernel, 1, pygen_variable_caps_DeviceEnqueue, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetKernelNDrangeSubGroupCount", spv::Op::OpGetKernelNDrangeSubGroupCount, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetKernelNDrangeMaxSubGroupSize", spv::Op::OpGetKernelNDrangeMaxSubGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetKernelWorkGroupSize", spv::Op::OpGetKernelWorkGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetKernelPreferredWorkGroupSizeMultiple", spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RetainEvent", spv::Op::OpRetainEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ReleaseEvent", spv::Op::OpReleaseEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CreateUserEvent", spv::Op::OpCreateUserEvent, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"IsValidEvent", spv::Op::OpIsValidEvent, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SetUserEventStatus", spv::Op::OpSetUserEventStatus, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"CaptureEventProfilingInfo", spv::Op::OpCaptureEventProfilingInfo, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"GetDefaultQueue", spv::Op::OpGetDefaultQueue, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BuildNDRange", spv::Op::OpBuildNDRange, 1, pygen_variable_caps_DeviceEnqueue, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseSampleImplicitLod", spv::Op::OpImageSparseSampleImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseSampleExplicitLod", spv::Op::OpImageSparseSampleExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseSampleDrefImplicitLod", spv::Op::OpImageSparseSampleDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseSampleDrefExplicitLod", spv::Op::OpImageSparseSampleDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseSampleProjImplicitLod", spv::Op::OpImageSparseSampleProjImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseSampleProjExplicitLod", spv::Op::OpImageSparseSampleProjExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseSampleProjDrefImplicitLod", spv::Op::OpImageSparseSampleProjDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseSampleProjDrefExplicitLod", spv::Op::OpImageSparseSampleProjDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseFetch", spv::Op::OpImageSparseFetch, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseGather", spv::Op::OpImageSparseGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseDrefGather", spv::Op::OpImageSparseDrefGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseTexelsResident", spv::Op::OpImageSparseTexelsResident, 1, pygen_variable_caps_SparseResidency, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"NoLine", spv::Op::OpNoLine, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicFlagTestAndSet", spv::Op::OpAtomicFlagTestAndSet, 1, pygen_variable_caps_Kernel, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicFlagClear", spv::Op::OpAtomicFlagClear, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImageSparseRead", spv::Op::OpImageSparseRead, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SizeOf", spv::Op::OpSizeOf, 1, pygen_variable_caps_Addresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"TypePipeStorage", spv::Op::OpTypePipeStorage, 1, pygen_variable_caps_PipeStorage, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ConstantPipeStorage", spv::Op::OpConstantPipeStorage, 1, pygen_variable_caps_PipeStorage, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"CreatePipeFromPipeStorage", spv::Op::OpCreatePipeFromPipeStorage, 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", spv::Op::OpGetKernelLocalSizeForSubgroupCount, 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", spv::Op::OpGetKernelMaxNumSubgroups, 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", spv::Op::OpTypeNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"NamedBarrierInitialize", spv::Op::OpNamedBarrierInitialize, 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", spv::Op::OpMemoryNamedBarrier, 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", spv::Op::OpModuleProcessed, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ExecutionModeId", spv::Op::OpExecutionModeId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"DecorateId", spv::Op::OpDecorateId, 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", spv::Op::OpGroupNonUniformElect, 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", spv::Op::OpGroupNonUniformAll, 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", spv::Op::OpGroupNonUniformAny, 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", spv::Op::OpGroupNonUniformAllEqual, 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", spv::Op::OpGroupNonUniformBroadcast, 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", spv::Op::OpGroupNonUniformBroadcastFirst, 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", spv::Op::OpGroupNonUniformBallot, 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", spv::Op::OpGroupNonUniformInverseBallot, 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", spv::Op::OpGroupNonUniformBallotBitExtract, 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", spv::Op::OpGroupNonUniformBallotBitCount, 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", spv::Op::OpGroupNonUniformBallotFindLSB, 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", spv::Op::OpGroupNonUniformBallotFindMSB, 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", spv::Op::OpGroupNonUniformShuffle, 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", spv::Op::OpGroupNonUniformShuffleXor, 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", spv::Op::OpGroupNonUniformShuffleUp, 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", spv::Op::OpGroupNonUniformShuffleDown, 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", spv::Op::OpGroupNonUniformIAdd, 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", spv::Op::OpGroupNonUniformFAdd, 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", spv::Op::OpGroupNonUniformIMul, 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", spv::Op::OpGroupNonUniformFMul, 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", spv::Op::OpGroupNonUniformSMin, 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", spv::Op::OpGroupNonUniformUMin, 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", spv::Op::OpGroupNonUniformFMin, 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", spv::Op::OpGroupNonUniformSMax, 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", spv::Op::OpGroupNonUniformUMax, 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", spv::Op::OpGroupNonUniformFMax, 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", spv::Op::OpGroupNonUniformBitwiseAnd, 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", spv::Op::OpGroupNonUniformBitwiseOr, 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", spv::Op::OpGroupNonUniformBitwiseXor, 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", spv::Op::OpGroupNonUniformLogicalAnd, 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", spv::Op::OpGroupNonUniformLogicalOr, 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", spv::Op::OpGroupNonUniformLogicalXor, 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", spv::Op::OpGroupNonUniformQuadBroadcast, 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", spv::Op::OpGroupNonUniformQuadSwap, 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", spv::Op::OpCopyLogical, 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", spv::Op::OpPtrEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_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", spv::Op::OpPtrNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_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", spv::Op::OpPtrDiff, 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", spv::Op::OpTerminateInvocation, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_terminate_invocation, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SubgroupBallotKHR", spv::Op::OpSubgroupBallotKHR, 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", spv::Op::OpSubgroupFirstInvocationKHR, 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", spv::Op::OpSubgroupAllKHR, 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", spv::Op::OpSubgroupAnyKHR, 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", spv::Op::OpSubgroupAllEqualKHR, 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}, + {"GroupNonUniformRotateKHR", spv::Op::OpGroupNonUniformRotateKHR, 1, pygen_variable_caps_GroupNonUniformRotateKHR, 6, {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_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupReadInvocationKHR", spv::Op::OpSubgroupReadInvocationKHR, 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}, + {"TraceRayKHR", spv::Op::OpTraceRayKHR, 1, pygen_variable_caps_RayTracingKHR, 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, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ExecuteCallableKHR", spv::Op::OpExecuteCallableKHR, 1, pygen_variable_caps_RayTracingKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ConvertUToAccelerationStructureKHR", spv::Op::OpConvertUToAccelerationStructureKHR, 2, pygen_variable_caps_RayTracingKHRRayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"IgnoreIntersectionKHR", spv::Op::OpIgnoreIntersectionKHR, 1, pygen_variable_caps_RayTracingKHR, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TerminateRayKHR", spv::Op::OpTerminateRayKHR, 1, pygen_variable_caps_RayTracingKHR, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"SDot", spv::Op::OpSDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SDotKHR", spv::Op::OpSDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDot", spv::Op::OpUDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDotKHR", spv::Op::OpUDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDot", spv::Op::OpSUDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDotKHR", spv::Op::OpSUDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SDotAccSat", spv::Op::OpSDotAccSat, 1, pygen_variable_caps_DotProduct, 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_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SDotAccSatKHR", spv::Op::OpSDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 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_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDotAccSat", spv::Op::OpUDotAccSat, 1, pygen_variable_caps_DotProduct, 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_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDotAccSatKHR", spv::Op::OpUDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 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_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDotAccSat", spv::Op::OpSUDotAccSat, 1, pygen_variable_caps_DotProduct, 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_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDotAccSatKHR", spv::Op::OpSUDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 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_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"TypeRayQueryKHR", spv::Op::OpTypeRayQueryKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryInitializeKHR", spv::Op::OpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryTerminateKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGenerateIntersectionKHR", spv::Op::OpRayQueryGenerateIntersectionKHR, 1, pygen_variable_caps_RayQueryKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryConfirmIntersectionKHR", spv::Op::OpRayQueryConfirmIntersectionKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryProceedKHR", spv::Op::OpRayQueryProceedKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionTypeKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpGroupIAddNonUniformAMD, 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", spv::Op::OpGroupFAddNonUniformAMD, 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", spv::Op::OpGroupFMinNonUniformAMD, 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", spv::Op::OpGroupUMinNonUniformAMD, 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", spv::Op::OpGroupSMinNonUniformAMD, 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", spv::Op::OpGroupFMaxNonUniformAMD, 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", spv::Op::OpGroupUMaxNonUniformAMD, 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", spv::Op::OpGroupSMaxNonUniformAMD, 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", spv::Op::OpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu}, + {"FragmentFetchAMD", spv::Op::OpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu}, + {"ReadClockKHR", spv::Op::OpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_clock, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitMotionNV", spv::Op::OpHitObjectRecordHitMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 14, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitWithIndexMotionNV", spv::Op::OpHitObjectRecordHitWithIndexMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordMissMotionNV", spv::Op::OpHitObjectRecordMissMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 7, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetWorldToObjectNV", spv::Op::OpHitObjectGetWorldToObjectNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetObjectToWorldNV", spv::Op::OpHitObjectGetObjectToWorldNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetObjectRayDirectionNV", spv::Op::OpHitObjectGetObjectRayDirectionNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetObjectRayOriginNV", spv::Op::OpHitObjectGetObjectRayOriginNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectTraceRayMotionNV", spv::Op::OpHitObjectTraceRayMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetShaderRecordBufferHandleNV", spv::Op::OpHitObjectGetShaderRecordBufferHandleNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetShaderBindingTableRecordIndexNV", spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordEmptyNV", spv::Op::OpHitObjectRecordEmptyNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectTraceRayNV", spv::Op::OpHitObjectTraceRayNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitNV", spv::Op::OpHitObjectRecordHitNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitWithIndexNV", spv::Op::OpHitObjectRecordHitWithIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordMissNV", spv::Op::OpHitObjectRecordMissNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 6, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectExecuteShaderNV", spv::Op::OpHitObjectExecuteShaderNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetCurrentTimeNV", spv::Op::OpHitObjectGetCurrentTimeNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetAttributesNV", spv::Op::OpHitObjectGetAttributesNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetHitKindNV", spv::Op::OpHitObjectGetHitKindNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetPrimitiveIndexNV", spv::Op::OpHitObjectGetPrimitiveIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetGeometryIndexNV", spv::Op::OpHitObjectGetGeometryIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetInstanceIdNV", spv::Op::OpHitObjectGetInstanceIdNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetInstanceCustomIndexNV", spv::Op::OpHitObjectGetInstanceCustomIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetWorldRayDirectionNV", spv::Op::OpHitObjectGetWorldRayDirectionNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetWorldRayOriginNV", spv::Op::OpHitObjectGetWorldRayOriginNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetRayTMaxNV", spv::Op::OpHitObjectGetRayTMaxNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetRayTMinNV", spv::Op::OpHitObjectGetRayTMinNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectIsEmptyNV", spv::Op::OpHitObjectIsEmptyNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectIsHitNV", spv::Op::OpHitObjectIsHitNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectIsMissNV", spv::Op::OpHitObjectIsMissNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReorderThreadWithHitObjectNV", spv::Op::OpReorderThreadWithHitObjectNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReorderThreadWithHintNV", spv::Op::OpReorderThreadWithHintNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeHitObjectNV", spv::Op::OpTypeHitObjectNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSampleFootprintNV", spv::Op::OpImageSampleFootprintNV, 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}, + {"EmitMeshTasksEXT", spv::Op::OpEmitMeshTasksEXT, 1, pygen_variable_caps_MeshShadingEXT, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SetMeshOutputsEXT", spv::Op::OpSetMeshOutputsEXT, 1, pygen_variable_caps_MeshShadingEXT, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformPartitionNV", spv::Op::OpGroupNonUniformPartitionNV, 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", spv::Op::OpWritePackedPrimitiveIndices4x8NV, 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", spv::Op::OpReportIntersectionKHR, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 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", spv::Op::OpReportIntersectionNV, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 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}, + {"IgnoreIntersectionNV", spv::Op::OpIgnoreIntersectionNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TerminateRayNV", spv::Op::OpTerminateRayNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TraceNV", spv::Op::OpTraceNV, 1, pygen_variable_caps_RayTracingNV, 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, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TraceMotionNV", spv::Op::OpTraceMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu}, + {"TraceRayMotionNV", spv::Op::OpTraceRayMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu}, + {"TypeAccelerationStructureKHR", spv::Op::OpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 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", spv::Op::OpTypeAccelerationStructureNV, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"ExecuteCallableNV", spv::Op::OpExecuteCallableNV, 1, pygen_variable_caps_RayTracingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TypeCooperativeMatrixNV", spv::Op::OpTypeCooperativeMatrixNV, 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", spv::Op::OpCooperativeMatrixLoadNV, 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", spv::Op::OpCooperativeMatrixStoreNV, 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", spv::Op::OpCooperativeMatrixMulAddNV, 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", spv::Op::OpCooperativeMatrixLengthNV, 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", spv::Op::OpBeginInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu}, + {"EndInvocationInterlockEXT", spv::Op::OpEndInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu}, + {"DemoteToHelperInvocation", spv::Op::OpDemoteToHelperInvocation, 1, pygen_variable_caps_DemoteToHelperInvocation, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DemoteToHelperInvocationEXT", spv::Op::OpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"IsHelperInvocationEXT", spv::Op::OpIsHelperInvocationEXT, 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}, + {"ConvertUToImageNV", spv::Op::OpConvertUToImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertUToSamplerNV", spv::Op::OpConvertUToSamplerNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertImageToUNV", spv::Op::OpConvertImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertSamplerToUNV", spv::Op::OpConvertSamplerToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertUToSampledImageNV", spv::Op::OpConvertUToSampledImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertSampledImageToUNV", spv::Op::OpConvertSampledImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SamplerImageAddressingModeNV", spv::Op::OpSamplerImageAddressingModeNV, 1, pygen_variable_caps_BindlessTextureNV, 1, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleINTEL", spv::Op::OpSubgroupShuffleINTEL, 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", spv::Op::OpSubgroupShuffleDownINTEL, 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", spv::Op::OpSubgroupShuffleUpINTEL, 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", spv::Op::OpSubgroupShuffleXorINTEL, 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", spv::Op::OpSubgroupBlockReadINTEL, 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", spv::Op::OpSubgroupBlockWriteINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockReadINTEL", spv::Op::OpSubgroupImageBlockReadINTEL, 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", spv::Op::OpSubgroupImageBlockWriteINTEL, 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", spv::Op::OpSubgroupImageMediaBlockReadINTEL, 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", spv::Op::OpSubgroupImageMediaBlockWriteINTEL, 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", spv::Op::OpUCountLeadingZerosINTEL, 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", spv::Op::OpUCountTrailingZerosINTEL, 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", spv::Op::OpAbsISubINTEL, 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", spv::Op::OpAbsUSubINTEL, 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", spv::Op::OpIAddSatINTEL, 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", spv::Op::OpUAddSatINTEL, 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", spv::Op::OpIAverageINTEL, 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", spv::Op::OpUAverageINTEL, 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", spv::Op::OpIAverageRoundedINTEL, 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", spv::Op::OpUAverageRoundedINTEL, 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", spv::Op::OpISubSatINTEL, 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", spv::Op::OpUSubSatINTEL, 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", spv::Op::OpIMul32x16INTEL, 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", spv::Op::OpUMul32x16INTEL, 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}, + {"ConstantFunctionPointerINTEL", spv::Op::OpConstantFunctionPointerINTEL, 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", spv::Op::OpFunctionPointerCallINTEL, 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}, + {"AsmTargetINTEL", spv::Op::OpAsmTargetINTEL, 1, pygen_variable_caps_AsmINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AsmINTEL", spv::Op::OpAsmINTEL, 1, pygen_variable_caps_AsmINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AsmCallINTEL", spv::Op::OpAsmCallINTEL, 1, pygen_variable_caps_AsmINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AtomicFMinEXT", spv::Op::OpAtomicFMinEXT, 3, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXT, 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, 0xffffffffu, 0xffffffffu}, + {"AtomicFMaxEXT", spv::Op::OpAtomicFMaxEXT, 3, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXT, 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, 0xffffffffu, 0xffffffffu}, + {"AssumeTrueKHR", spv::Op::OpAssumeTrueKHR, 1, pygen_variable_caps_ExpectAssumeKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_expect_assume, 0xffffffffu, 0xffffffffu}, + {"ExpectKHR", spv::Op::OpExpectKHR, 1, pygen_variable_caps_ExpectAssumeKHR, 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_expect_assume, 0xffffffffu, 0xffffffffu}, + {"DecorateString", spv::Op::OpDecorateString, 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", spv::Op::OpDecorateStringGOOGLE, 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", spv::Op::OpMemberDecorateString, 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", spv::Op::OpMemberDecorateStringGOOGLE, 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", spv::Op::OpVmeImageINTEL, 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", spv::Op::OpTypeVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImePayloadINTEL", spv::Op::OpTypeAvcImePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcRefPayloadINTEL", spv::Op::OpTypeAvcRefPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcSicPayloadINTEL", spv::Op::OpTypeAvcSicPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcMcePayloadINTEL", spv::Op::OpTypeAvcMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcMceResultINTEL", spv::Op::OpTypeAvcMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultINTEL", spv::Op::OpTypeAvcImeResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultSingleReferenceStreamoutINTEL", spv::Op::OpTypeAvcImeResultSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultDualReferenceStreamoutINTEL", spv::Op::OpTypeAvcImeResultDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeSingleReferenceStreaminINTEL", spv::Op::OpTypeAvcImeSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeDualReferenceStreaminINTEL", spv::Op::OpTypeAvcImeDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcRefResultINTEL", spv::Op::OpTypeAvcRefResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcSicResultINTEL", spv::Op::OpTypeAvcSicResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceSetInterShapePenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", spv::Op::OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", spv::Op::OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetMotionVectorCostFunctionINTEL", spv::Op::OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, 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", spv::Op::OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetAcOnlyHaarINTEL", spv::Op::OpSubgroupAvcMceSetAcOnlyHaarINTEL, 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", spv::Op::OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, 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", spv::Op::OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, 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", spv::Op::OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, 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", spv::Op::OpSubgroupAvcMceConvertToImePayloadINTEL, 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", spv::Op::OpSubgroupAvcMceConvertToImeResultINTEL, 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", spv::Op::OpSubgroupAvcMceConvertToRefPayloadINTEL, 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", spv::Op::OpSubgroupAvcMceConvertToRefResultINTEL, 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", spv::Op::OpSubgroupAvcMceConvertToSicPayloadINTEL, 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", spv::Op::OpSubgroupAvcMceConvertToSicResultINTEL, 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", spv::Op::OpSubgroupAvcMceGetMotionVectorsINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterDistortionsINTEL, 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", spv::Op::OpSubgroupAvcMceGetBestInterDistortionsINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterMajorShapeINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterMinorShapeINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterDirectionsINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterMotionVectorCountINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterReferenceIdsINTEL, 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", spv::Op::OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, 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", spv::Op::OpSubgroupAvcImeInitializeINTEL, 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", spv::Op::OpSubgroupAvcImeSetSingleReferenceINTEL, 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", spv::Op::OpSubgroupAvcImeSetDualReferenceINTEL, 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", spv::Op::OpSubgroupAvcImeRefWindowSizeINTEL, 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", spv::Op::OpSubgroupAvcImeAdjustRefOffsetINTEL, 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", spv::Op::OpSubgroupAvcImeConvertToMcePayloadINTEL, 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", spv::Op::OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, 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", spv::Op::OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, 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", spv::Op::OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, 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", spv::Op::OpSubgroupAvcImeSetWeightedSadINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, 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", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, 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", spv::Op::OpSubgroupAvcImeConvertToMceResultINTEL, 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", spv::Op::OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, 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", spv::Op::OpSubgroupAvcImeGetDualReferenceStreaminINTEL, 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", spv::Op::OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, 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", spv::Op::OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, 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", spv::Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, 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", spv::Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, 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", spv::Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, 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", spv::Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, 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", spv::Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, 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", spv::Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, 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", spv::Op::OpSubgroupAvcImeGetBorderReachedINTEL, 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", spv::Op::OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, 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", spv::Op::OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, 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", spv::Op::OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, 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", spv::Op::OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, 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", spv::Op::OpSubgroupAvcFmeInitializeINTEL, 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", spv::Op::OpSubgroupAvcBmeInitializeINTEL, 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", spv::Op::OpSubgroupAvcRefConvertToMcePayloadINTEL, 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", spv::Op::OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, 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", spv::Op::OpSubgroupAvcRefSetBilinearFilterEnableINTEL, 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", spv::Op::OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, 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", spv::Op::OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, 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", spv::Op::OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, 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", spv::Op::OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, 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", spv::Op::OpSubgroupAvcRefConvertToMceResultINTEL, 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", spv::Op::OpSubgroupAvcSicInitializeINTEL, 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", spv::Op::OpSubgroupAvcSicConfigureSkcINTEL, 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", spv::Op::OpSubgroupAvcSicConfigureIpeLumaINTEL, 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", spv::Op::OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, 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", spv::Op::OpSubgroupAvcSicGetMotionVectorMaskINTEL, 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", spv::Op::OpSubgroupAvcSicConvertToMcePayloadINTEL, 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", spv::Op::OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, 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", spv::Op::OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, 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", spv::Op::OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, 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", spv::Op::OpSubgroupAvcSicSetBilinearFilterEnableINTEL, 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", spv::Op::OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, 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", spv::Op::OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, 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", spv::Op::OpSubgroupAvcSicEvaluateIpeINTEL, 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", spv::Op::OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, 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", spv::Op::OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, 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", spv::Op::OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, 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", spv::Op::OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, 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", spv::Op::OpSubgroupAvcSicConvertToMceResultINTEL, 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", spv::Op::OpSubgroupAvcSicGetIpeLumaShapeINTEL, 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", spv::Op::OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, 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", spv::Op::OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, 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", spv::Op::OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, 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", spv::Op::OpSubgroupAvcSicGetIpeChromaModeINTEL, 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", spv::Op::OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 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", spv::Op::OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 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", spv::Op::OpSubgroupAvcSicGetInterRawSadsINTEL, 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}, + {"VariableLengthArrayINTEL", spv::Op::OpVariableLengthArrayINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SaveMemoryINTEL", spv::Op::OpSaveMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"RestoreMemoryINTEL", spv::Op::OpRestoreMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinCosPiINTEL", spv::Op::OpArbitraryFloatSinCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCastINTEL", spv::Op::OpArbitraryFloatCastINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCastFromIntINTEL", spv::Op::OpArbitraryFloatCastFromIntINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCastToIntINTEL", spv::Op::OpArbitraryFloatCastToIntINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatAddINTEL", spv::Op::OpArbitraryFloatAddINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSubINTEL", spv::Op::OpArbitraryFloatSubINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatMulINTEL", spv::Op::OpArbitraryFloatMulINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatDivINTEL", spv::Op::OpArbitraryFloatDivINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatGTINTEL", spv::Op::OpArbitraryFloatGTINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatGEINTEL", spv::Op::OpArbitraryFloatGEINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLTINTEL", spv::Op::OpArbitraryFloatLTINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLEINTEL", spv::Op::OpArbitraryFloatLEINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatEQINTEL", spv::Op::OpArbitraryFloatEQINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatRecipINTEL", spv::Op::OpArbitraryFloatRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatRSqrtINTEL", spv::Op::OpArbitraryFloatRSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCbrtINTEL", spv::Op::OpArbitraryFloatCbrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatHypotINTEL", spv::Op::OpArbitraryFloatHypotINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSqrtINTEL", spv::Op::OpArbitraryFloatSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLogINTEL", spv::Op::OpArbitraryFloatLogINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLog2INTEL", spv::Op::OpArbitraryFloatLog2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLog10INTEL", spv::Op::OpArbitraryFloatLog10INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLog1pINTEL", spv::Op::OpArbitraryFloatLog1pINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExpINTEL", spv::Op::OpArbitraryFloatExpINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExp2INTEL", spv::Op::OpArbitraryFloatExp2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExp10INTEL", spv::Op::OpArbitraryFloatExp10INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExpm1INTEL", spv::Op::OpArbitraryFloatExpm1INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinINTEL", spv::Op::OpArbitraryFloatSinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCosINTEL", spv::Op::OpArbitraryFloatCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinCosINTEL", spv::Op::OpArbitraryFloatSinCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinPiINTEL", spv::Op::OpArbitraryFloatSinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCosPiINTEL", spv::Op::OpArbitraryFloatCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatASinINTEL", spv::Op::OpArbitraryFloatASinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatASinPiINTEL", spv::Op::OpArbitraryFloatASinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatACosINTEL", spv::Op::OpArbitraryFloatACosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatACosPiINTEL", spv::Op::OpArbitraryFloatACosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatATanINTEL", spv::Op::OpArbitraryFloatATanINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatATanPiINTEL", spv::Op::OpArbitraryFloatATanPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatATan2INTEL", spv::Op::OpArbitraryFloatATan2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatPowINTEL", spv::Op::OpArbitraryFloatPowINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatPowRINTEL", spv::Op::OpArbitraryFloatPowRINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatPowNINTEL", spv::Op::OpArbitraryFloatPowNINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"LoopControlINTEL", spv::Op::OpLoopControlINTEL, 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}, + {"AliasDomainDeclINTEL", spv::Op::OpAliasDomainDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, + {"AliasScopeDeclINTEL", spv::Op::OpAliasScopeDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, + {"AliasScopeListDeclINTEL", spv::Op::OpAliasScopeListDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, + {"FixedSqrtINTEL", spv::Op::OpFixedSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedRecipINTEL", spv::Op::OpFixedRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedRsqrtINTEL", spv::Op::OpFixedRsqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinINTEL", spv::Op::OpFixedSinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedCosINTEL", spv::Op::OpFixedCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinCosINTEL", spv::Op::OpFixedSinCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinPiINTEL", spv::Op::OpFixedSinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedCosPiINTEL", spv::Op::OpFixedCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinCosPiINTEL", spv::Op::OpFixedSinCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedLogINTEL", spv::Op::OpFixedLogINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedExpINTEL", spv::Op::OpFixedExpINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"PtrCastToCrossWorkgroupINTEL", spv::Op::OpPtrCastToCrossWorkgroupINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CrossWorkgroupCastToPtrINTEL", spv::Op::OpCrossWorkgroupCastToPtrINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReadPipeBlockingINTEL", spv::Op::OpReadPipeBlockingINTEL, 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", spv::Op::OpWritePipeBlockingINTEL, 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", spv::Op::OpFPGARegINTEL, 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", spv::Op::OpRayQueryGetRayTMinKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetRayFlagsKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionTKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionInstanceIdKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionBarycentricsKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionFrontFaceKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetWorldRayDirectionKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetWorldRayOriginKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR, 1, pygen_variable_caps_RayQueryKHR, 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", spv::Op::OpAtomicFAddEXT, 3, pygen_variable_caps_AtomicFloat16AddEXTAtomicFloat32AddEXTAtomicFloat64AddEXT, 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}, + {"TypeBufferSurfaceINTEL", spv::Op::OpTypeBufferSurfaceINTEL, 1, pygen_variable_caps_VectorComputeINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeStructContinuedINTEL", spv::Op::OpTypeStructContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConstantCompositeContinuedINTEL", spv::Op::OpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SpecConstantCompositeContinuedINTEL", spv::Op::OpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ControlBarrierArriveINTEL", spv::Op::OpControlBarrierArriveINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ControlBarrierWaitINTEL", spv::Op::OpControlBarrierWaitINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupIMulKHR", spv::Op::OpGroupIMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupFMulKHR", spv::Op::OpGroupFMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupBitwiseAndKHR", spv::Op::OpGroupBitwiseAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupBitwiseOrKHR", spv::Op::OpGroupBitwiseOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupBitwiseXorKHR", spv::Op::OpGroupBitwiseXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupLogicalAndKHR", spv::Op::OpGroupLogicalAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupLogicalOrKHR", spv::Op::OpGroupLogicalOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu}, + {"GroupLogicalXorKHR", spv::Op::OpGroupLogicalXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0xffffffffu, 0xffffffffu} }; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc index 4e60e7cc0..967dbb6a3 100644 --- a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc +++ b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc @@ -78,6 +78,10 @@ const char* ExtensionToString(Extension extension) { return "SPV_INTEL_fpga_buffer_location"; case Extension::kSPV_INTEL_fpga_cluster_attributes: return "SPV_INTEL_fpga_cluster_attributes"; + case Extension::kSPV_INTEL_fpga_dsp_control: + return "SPV_INTEL_fpga_dsp_control"; + case Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes: + return "SPV_INTEL_fpga_invocation_pipelining_attributes"; case Extension::kSPV_INTEL_fpga_loop_controls: return "SPV_INTEL_fpga_loop_controls"; case Extension::kSPV_INTEL_fpga_memory_accesses: @@ -104,6 +108,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_INTEL_memory_access_aliasing"; case Extension::kSPV_INTEL_optnone: return "SPV_INTEL_optnone"; + case Extension::kSPV_INTEL_runtime_aligned: + return "SPV_INTEL_runtime_aligned"; case Extension::kSPV_INTEL_shader_integer_functions2: return "SPV_INTEL_shader_integer_functions2"; case Extension::kSPV_INTEL_split_barrier: @@ -202,6 +208,8 @@ const char* ExtensionToString(Extension extension) { 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_invocation_reorder: + return "SPV_NV_shader_invocation_reorder"; case Extension::kSPV_NV_shader_sm_builtins: return "SPV_NV_shader_sm_builtins"; case Extension::kSPV_NV_shader_subgroup_partitioned: @@ -221,8 +229,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_early_and_late_fragment_tests", "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_ARM_core_builtins", "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_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "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_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "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_cull_mask", "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_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "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_ray_tracing_motion_blur", "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_early_and_late_fragment_tests, 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_ARM_core_builtins, 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_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, 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_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, 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_cull_mask, 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_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, 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_ray_tracing_motion_blur, 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_early_and_late_fragment_tests", "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_ARM_core_builtins", "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_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "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_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "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_cull_mask", "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_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "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_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "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_early_and_late_fragment_tests, 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_ARM_core_builtins, 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_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, 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_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, 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_cull_mask, 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_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, 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_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, 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( @@ -236,414 +244,422 @@ const char* ExtensionToString(Extension extension) { } -const char* CapabilityToString(SpvCapability capability) { +const char* CapabilityToString(spv::Capability capability) { switch (capability) { - case SpvCapabilityMatrix: + case spv::Capability::Matrix: return "Matrix"; - case SpvCapabilityShader: + case spv::Capability::Shader: return "Shader"; - case SpvCapabilityGeometry: + case spv::Capability::Geometry: return "Geometry"; - case SpvCapabilityTessellation: + case spv::Capability::Tessellation: return "Tessellation"; - case SpvCapabilityAddresses: + case spv::Capability::Addresses: return "Addresses"; - case SpvCapabilityLinkage: + case spv::Capability::Linkage: return "Linkage"; - case SpvCapabilityKernel: + case spv::Capability::Kernel: return "Kernel"; - case SpvCapabilityVector16: + case spv::Capability::Vector16: return "Vector16"; - case SpvCapabilityFloat16Buffer: + case spv::Capability::Float16Buffer: return "Float16Buffer"; - case SpvCapabilityFloat16: + case spv::Capability::Float16: return "Float16"; - case SpvCapabilityFloat64: + case spv::Capability::Float64: return "Float64"; - case SpvCapabilityInt64: + case spv::Capability::Int64: return "Int64"; - case SpvCapabilityInt64Atomics: + case spv::Capability::Int64Atomics: return "Int64Atomics"; - case SpvCapabilityImageBasic: + case spv::Capability::ImageBasic: return "ImageBasic"; - case SpvCapabilityImageReadWrite: + case spv::Capability::ImageReadWrite: return "ImageReadWrite"; - case SpvCapabilityImageMipmap: + case spv::Capability::ImageMipmap: return "ImageMipmap"; - case SpvCapabilityPipes: + case spv::Capability::Pipes: return "Pipes"; - case SpvCapabilityGroups: + case spv::Capability::Groups: return "Groups"; - case SpvCapabilityDeviceEnqueue: + case spv::Capability::DeviceEnqueue: return "DeviceEnqueue"; - case SpvCapabilityLiteralSampler: + case spv::Capability::LiteralSampler: return "LiteralSampler"; - case SpvCapabilityAtomicStorage: + case spv::Capability::AtomicStorage: return "AtomicStorage"; - case SpvCapabilityInt16: + case spv::Capability::Int16: return "Int16"; - case SpvCapabilityTessellationPointSize: + case spv::Capability::TessellationPointSize: return "TessellationPointSize"; - case SpvCapabilityGeometryPointSize: + case spv::Capability::GeometryPointSize: return "GeometryPointSize"; - case SpvCapabilityImageGatherExtended: + case spv::Capability::ImageGatherExtended: return "ImageGatherExtended"; - case SpvCapabilityStorageImageMultisample: + case spv::Capability::StorageImageMultisample: return "StorageImageMultisample"; - case SpvCapabilityUniformBufferArrayDynamicIndexing: + case spv::Capability::UniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; - case SpvCapabilitySampledImageArrayDynamicIndexing: + case spv::Capability::SampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; - case SpvCapabilityStorageBufferArrayDynamicIndexing: + case spv::Capability::StorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; - case SpvCapabilityStorageImageArrayDynamicIndexing: + case spv::Capability::StorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; - case SpvCapabilityClipDistance: + case spv::Capability::ClipDistance: return "ClipDistance"; - case SpvCapabilityCullDistance: + case spv::Capability::CullDistance: return "CullDistance"; - case SpvCapabilityImageCubeArray: + case spv::Capability::ImageCubeArray: return "ImageCubeArray"; - case SpvCapabilitySampleRateShading: + case spv::Capability::SampleRateShading: return "SampleRateShading"; - case SpvCapabilityImageRect: + case spv::Capability::ImageRect: return "ImageRect"; - case SpvCapabilitySampledRect: + case spv::Capability::SampledRect: return "SampledRect"; - case SpvCapabilityGenericPointer: + case spv::Capability::GenericPointer: return "GenericPointer"; - case SpvCapabilityInt8: + case spv::Capability::Int8: return "Int8"; - case SpvCapabilityInputAttachment: + case spv::Capability::InputAttachment: return "InputAttachment"; - case SpvCapabilitySparseResidency: + case spv::Capability::SparseResidency: return "SparseResidency"; - case SpvCapabilityMinLod: + case spv::Capability::MinLod: return "MinLod"; - case SpvCapabilitySampled1D: + case spv::Capability::Sampled1D: return "Sampled1D"; - case SpvCapabilityImage1D: + case spv::Capability::Image1D: return "Image1D"; - case SpvCapabilitySampledCubeArray: + case spv::Capability::SampledCubeArray: return "SampledCubeArray"; - case SpvCapabilitySampledBuffer: + case spv::Capability::SampledBuffer: return "SampledBuffer"; - case SpvCapabilityImageBuffer: + case spv::Capability::ImageBuffer: return "ImageBuffer"; - case SpvCapabilityImageMSArray: + case spv::Capability::ImageMSArray: return "ImageMSArray"; - case SpvCapabilityStorageImageExtendedFormats: + case spv::Capability::StorageImageExtendedFormats: return "StorageImageExtendedFormats"; - case SpvCapabilityImageQuery: + case spv::Capability::ImageQuery: return "ImageQuery"; - case SpvCapabilityDerivativeControl: + case spv::Capability::DerivativeControl: return "DerivativeControl"; - case SpvCapabilityInterpolationFunction: + case spv::Capability::InterpolationFunction: return "InterpolationFunction"; - case SpvCapabilityTransformFeedback: + case spv::Capability::TransformFeedback: return "TransformFeedback"; - case SpvCapabilityGeometryStreams: + case spv::Capability::GeometryStreams: return "GeometryStreams"; - case SpvCapabilityStorageImageReadWithoutFormat: + case spv::Capability::StorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; - case SpvCapabilityStorageImageWriteWithoutFormat: + case spv::Capability::StorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; - case SpvCapabilityMultiViewport: + case spv::Capability::MultiViewport: return "MultiViewport"; - case SpvCapabilitySubgroupDispatch: + case spv::Capability::SubgroupDispatch: return "SubgroupDispatch"; - case SpvCapabilityNamedBarrier: + case spv::Capability::NamedBarrier: return "NamedBarrier"; - case SpvCapabilityPipeStorage: + case spv::Capability::PipeStorage: return "PipeStorage"; - case SpvCapabilityGroupNonUniform: + case spv::Capability::GroupNonUniform: return "GroupNonUniform"; - case SpvCapabilityGroupNonUniformVote: + case spv::Capability::GroupNonUniformVote: return "GroupNonUniformVote"; - case SpvCapabilityGroupNonUniformArithmetic: + case spv::Capability::GroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; - case SpvCapabilityGroupNonUniformBallot: + case spv::Capability::GroupNonUniformBallot: return "GroupNonUniformBallot"; - case SpvCapabilityGroupNonUniformShuffle: + case spv::Capability::GroupNonUniformShuffle: return "GroupNonUniformShuffle"; - case SpvCapabilityGroupNonUniformShuffleRelative: + case spv::Capability::GroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; - case SpvCapabilityGroupNonUniformClustered: + case spv::Capability::GroupNonUniformClustered: return "GroupNonUniformClustered"; - case SpvCapabilityGroupNonUniformQuad: + case spv::Capability::GroupNonUniformQuad: return "GroupNonUniformQuad"; - case SpvCapabilityShaderLayer: + case spv::Capability::ShaderLayer: return "ShaderLayer"; - case SpvCapabilityShaderViewportIndex: + case spv::Capability::ShaderViewportIndex: return "ShaderViewportIndex"; - case SpvCapabilityUniformDecoration: + case spv::Capability::UniformDecoration: return "UniformDecoration"; - case SpvCapabilityCoreBuiltinsARM: + case spv::Capability::CoreBuiltinsARM: return "CoreBuiltinsARM"; - case SpvCapabilityFragmentShadingRateKHR: + case spv::Capability::FragmentShadingRateKHR: return "FragmentShadingRateKHR"; - case SpvCapabilitySubgroupBallotKHR: + case spv::Capability::SubgroupBallotKHR: return "SubgroupBallotKHR"; - case SpvCapabilityDrawParameters: + case spv::Capability::DrawParameters: return "DrawParameters"; - case SpvCapabilityWorkgroupMemoryExplicitLayoutKHR: + case spv::Capability::WorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; - case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: + case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; - case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: + case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; - case SpvCapabilitySubgroupVoteKHR: + case spv::Capability::SubgroupVoteKHR: return "SubgroupVoteKHR"; - case SpvCapabilityStorageBuffer16BitAccess: + case spv::Capability::StorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; - case SpvCapabilityUniformAndStorageBuffer16BitAccess: + case spv::Capability::UniformAndStorageBuffer16BitAccess: return "UniformAndStorageBuffer16BitAccess"; - case SpvCapabilityStoragePushConstant16: + case spv::Capability::StoragePushConstant16: return "StoragePushConstant16"; - case SpvCapabilityStorageInputOutput16: + case spv::Capability::StorageInputOutput16: return "StorageInputOutput16"; - case SpvCapabilityDeviceGroup: + case spv::Capability::DeviceGroup: return "DeviceGroup"; - case SpvCapabilityMultiView: + case spv::Capability::MultiView: return "MultiView"; - case SpvCapabilityVariablePointersStorageBuffer: + case spv::Capability::VariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; - case SpvCapabilityVariablePointers: + case spv::Capability::VariablePointers: return "VariablePointers"; - case SpvCapabilityAtomicStorageOps: + case spv::Capability::AtomicStorageOps: return "AtomicStorageOps"; - case SpvCapabilitySampleMaskPostDepthCoverage: + case spv::Capability::SampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; - case SpvCapabilityStorageBuffer8BitAccess: + case spv::Capability::StorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; - case SpvCapabilityUniformAndStorageBuffer8BitAccess: + case spv::Capability::UniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; - case SpvCapabilityStoragePushConstant8: + case spv::Capability::StoragePushConstant8: return "StoragePushConstant8"; - case SpvCapabilityDenormPreserve: + case spv::Capability::DenormPreserve: return "DenormPreserve"; - case SpvCapabilityDenormFlushToZero: + case spv::Capability::DenormFlushToZero: return "DenormFlushToZero"; - case SpvCapabilitySignedZeroInfNanPreserve: + case spv::Capability::SignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; - case SpvCapabilityRoundingModeRTE: + case spv::Capability::RoundingModeRTE: return "RoundingModeRTE"; - case SpvCapabilityRoundingModeRTZ: + case spv::Capability::RoundingModeRTZ: return "RoundingModeRTZ"; - case SpvCapabilityRayQueryProvisionalKHR: + case spv::Capability::RayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; - case SpvCapabilityRayQueryKHR: + case spv::Capability::RayQueryKHR: return "RayQueryKHR"; - case SpvCapabilityRayTraversalPrimitiveCullingKHR: + case spv::Capability::RayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; - case SpvCapabilityRayTracingKHR: + case spv::Capability::RayTracingKHR: return "RayTracingKHR"; - case SpvCapabilityFloat16ImageAMD: + case spv::Capability::Float16ImageAMD: return "Float16ImageAMD"; - case SpvCapabilityImageGatherBiasLodAMD: + case spv::Capability::ImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; - case SpvCapabilityFragmentMaskAMD: + case spv::Capability::FragmentMaskAMD: return "FragmentMaskAMD"; - case SpvCapabilityStencilExportEXT: + case spv::Capability::StencilExportEXT: return "StencilExportEXT"; - case SpvCapabilityImageReadWriteLodAMD: + case spv::Capability::ImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; - case SpvCapabilityInt64ImageEXT: + case spv::Capability::Int64ImageEXT: return "Int64ImageEXT"; - case SpvCapabilityShaderClockKHR: + case spv::Capability::ShaderClockKHR: return "ShaderClockKHR"; - case SpvCapabilitySampleMaskOverrideCoverageNV: + case spv::Capability::SampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; - case SpvCapabilityGeometryShaderPassthroughNV: + case spv::Capability::GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; - case SpvCapabilityShaderViewportIndexLayerEXT: + case spv::Capability::ShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; - case SpvCapabilityShaderViewportMaskNV: + case spv::Capability::ShaderViewportMaskNV: return "ShaderViewportMaskNV"; - case SpvCapabilityShaderStereoViewNV: + case spv::Capability::ShaderStereoViewNV: return "ShaderStereoViewNV"; - case SpvCapabilityPerViewAttributesNV: + case spv::Capability::PerViewAttributesNV: return "PerViewAttributesNV"; - case SpvCapabilityFragmentFullyCoveredEXT: + case spv::Capability::FragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; - case SpvCapabilityMeshShadingNV: + case spv::Capability::MeshShadingNV: return "MeshShadingNV"; - case SpvCapabilityImageFootprintNV: + case spv::Capability::ImageFootprintNV: return "ImageFootprintNV"; - case SpvCapabilityMeshShadingEXT: + case spv::Capability::MeshShadingEXT: return "MeshShadingEXT"; - case SpvCapabilityFragmentBarycentricKHR: + case spv::Capability::FragmentBarycentricKHR: return "FragmentBarycentricKHR"; - case SpvCapabilityComputeDerivativeGroupQuadsNV: + case spv::Capability::ComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; - case SpvCapabilityFragmentDensityEXT: + case spv::Capability::FragmentDensityEXT: return "FragmentDensityEXT"; - case SpvCapabilityGroupNonUniformPartitionedNV: + case spv::Capability::GroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; - case SpvCapabilityShaderNonUniform: + case spv::Capability::ShaderNonUniform: return "ShaderNonUniform"; - case SpvCapabilityRuntimeDescriptorArray: + case spv::Capability::RuntimeDescriptorArray: return "RuntimeDescriptorArray"; - case SpvCapabilityInputAttachmentArrayDynamicIndexing: + case spv::Capability::InputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; - case SpvCapabilityUniformTexelBufferArrayDynamicIndexing: + case spv::Capability::UniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; - case SpvCapabilityStorageTexelBufferArrayDynamicIndexing: + case spv::Capability::StorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; - case SpvCapabilityUniformBufferArrayNonUniformIndexing: + case spv::Capability::UniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; - case SpvCapabilitySampledImageArrayNonUniformIndexing: + case spv::Capability::SampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; - case SpvCapabilityStorageBufferArrayNonUniformIndexing: + case spv::Capability::StorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; - case SpvCapabilityStorageImageArrayNonUniformIndexing: + case spv::Capability::StorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; - case SpvCapabilityInputAttachmentArrayNonUniformIndexing: + case spv::Capability::InputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; - case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing: + case spv::Capability::UniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; - case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing: + case spv::Capability::StorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; - case SpvCapabilityRayTracingNV: + case spv::Capability::RayTracingNV: return "RayTracingNV"; - case SpvCapabilityRayTracingMotionBlurNV: + case spv::Capability::RayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; - case SpvCapabilityVulkanMemoryModel: + case spv::Capability::VulkanMemoryModel: return "VulkanMemoryModel"; - case SpvCapabilityVulkanMemoryModelDeviceScope: + case spv::Capability::VulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; - case SpvCapabilityPhysicalStorageBufferAddresses: + case spv::Capability::PhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; - case SpvCapabilityComputeDerivativeGroupLinearNV: + case spv::Capability::ComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; - case SpvCapabilityRayTracingProvisionalKHR: + case spv::Capability::RayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; - case SpvCapabilityCooperativeMatrixNV: + case spv::Capability::CooperativeMatrixNV: return "CooperativeMatrixNV"; - case SpvCapabilityFragmentShaderSampleInterlockEXT: + case spv::Capability::FragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; - case SpvCapabilityFragmentShaderShadingRateInterlockEXT: + case spv::Capability::FragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; - case SpvCapabilityShaderSMBuiltinsNV: + case spv::Capability::ShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; - case SpvCapabilityFragmentShaderPixelInterlockEXT: + case spv::Capability::FragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; - case SpvCapabilityDemoteToHelperInvocation: + case spv::Capability::DemoteToHelperInvocation: return "DemoteToHelperInvocation"; - case SpvCapabilityRayTracingOpacityMicromapEXT: + case spv::Capability::RayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; - case SpvCapabilityBindlessTextureNV: + case spv::Capability::ShaderInvocationReorderNV: + return "ShaderInvocationReorderNV"; + case spv::Capability::BindlessTextureNV: return "BindlessTextureNV"; - case SpvCapabilitySubgroupShuffleINTEL: + case spv::Capability::SubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; - case SpvCapabilitySubgroupBufferBlockIOINTEL: + case spv::Capability::SubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; - case SpvCapabilitySubgroupImageBlockIOINTEL: + case spv::Capability::SubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; - case SpvCapabilitySubgroupImageMediaBlockIOINTEL: + case spv::Capability::SubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; - case SpvCapabilityRoundToInfinityINTEL: + case spv::Capability::RoundToInfinityINTEL: return "RoundToInfinityINTEL"; - case SpvCapabilityFloatingPointModeINTEL: + case spv::Capability::FloatingPointModeINTEL: return "FloatingPointModeINTEL"; - case SpvCapabilityIntegerFunctions2INTEL: + case spv::Capability::IntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; - case SpvCapabilityFunctionPointersINTEL: + case spv::Capability::FunctionPointersINTEL: return "FunctionPointersINTEL"; - case SpvCapabilityIndirectReferencesINTEL: + case spv::Capability::IndirectReferencesINTEL: return "IndirectReferencesINTEL"; - case SpvCapabilityAsmINTEL: + case spv::Capability::AsmINTEL: return "AsmINTEL"; - case SpvCapabilityAtomicFloat32MinMaxEXT: + case spv::Capability::AtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; - case SpvCapabilityAtomicFloat64MinMaxEXT: + case spv::Capability::AtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; - case SpvCapabilityAtomicFloat16MinMaxEXT: + case spv::Capability::AtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; - case SpvCapabilityVectorComputeINTEL: + case spv::Capability::VectorComputeINTEL: return "VectorComputeINTEL"; - case SpvCapabilityVectorAnyINTEL: + case spv::Capability::VectorAnyINTEL: return "VectorAnyINTEL"; - case SpvCapabilityExpectAssumeKHR: + case spv::Capability::ExpectAssumeKHR: return "ExpectAssumeKHR"; - case SpvCapabilitySubgroupAvcMotionEstimationINTEL: + case spv::Capability::SubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; - case SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL: + case spv::Capability::SubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; - case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL: + case spv::Capability::SubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; - case SpvCapabilityVariableLengthArrayINTEL: + case spv::Capability::VariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; - case SpvCapabilityFunctionFloatControlINTEL: + case spv::Capability::FunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; - case SpvCapabilityFPGAMemoryAttributesINTEL: + case spv::Capability::FPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; - case SpvCapabilityFPFastMathModeINTEL: + case spv::Capability::FPFastMathModeINTEL: return "FPFastMathModeINTEL"; - case SpvCapabilityArbitraryPrecisionIntegersINTEL: + case spv::Capability::ArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; - case SpvCapabilityArbitraryPrecisionFloatingPointINTEL: + case spv::Capability::ArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; - case SpvCapabilityUnstructuredLoopControlsINTEL: + case spv::Capability::UnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; - case SpvCapabilityFPGALoopControlsINTEL: + case spv::Capability::FPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; - case SpvCapabilityKernelAttributesINTEL: + case spv::Capability::KernelAttributesINTEL: return "KernelAttributesINTEL"; - case SpvCapabilityFPGAKernelAttributesINTEL: + case spv::Capability::FPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; - case SpvCapabilityFPGAMemoryAccessesINTEL: + case spv::Capability::FPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; - case SpvCapabilityFPGAClusterAttributesINTEL: + case spv::Capability::FPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; - case SpvCapabilityLoopFuseINTEL: + case spv::Capability::LoopFuseINTEL: return "LoopFuseINTEL"; - case SpvCapabilityMemoryAccessAliasingINTEL: + case spv::Capability::FPGADSPControlINTEL: + return "FPGADSPControlINTEL"; + case spv::Capability::MemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; - case SpvCapabilityFPGABufferLocationINTEL: + case spv::Capability::FPGAInvocationPipeliningAttributesINTEL: + return "FPGAInvocationPipeliningAttributesINTEL"; + case spv::Capability::FPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; - case SpvCapabilityArbitraryPrecisionFixedPointINTEL: + case spv::Capability::ArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; - case SpvCapabilityUSMStorageClassesINTEL: + case spv::Capability::USMStorageClassesINTEL: return "USMStorageClassesINTEL"; - case SpvCapabilityIOPipesINTEL: + case spv::Capability::RuntimeAlignedAttributeINTEL: + return "RuntimeAlignedAttributeINTEL"; + case spv::Capability::IOPipesINTEL: return "IOPipesINTEL"; - case SpvCapabilityBlockingPipesINTEL: + case spv::Capability::BlockingPipesINTEL: return "BlockingPipesINTEL"; - case SpvCapabilityFPGARegINTEL: + case spv::Capability::FPGARegINTEL: return "FPGARegINTEL"; - case SpvCapabilityDotProductInputAll: + case spv::Capability::DotProductInputAll: return "DotProductInputAll"; - case SpvCapabilityDotProductInput4x8Bit: + case spv::Capability::DotProductInput4x8Bit: return "DotProductInput4x8Bit"; - case SpvCapabilityDotProductInput4x8BitPacked: + case spv::Capability::DotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; - case SpvCapabilityDotProduct: + case spv::Capability::DotProduct: return "DotProduct"; - case SpvCapabilityRayCullMaskKHR: + case spv::Capability::RayCullMaskKHR: return "RayCullMaskKHR"; - case SpvCapabilityBitInstructions: + case spv::Capability::BitInstructions: return "BitInstructions"; - case SpvCapabilityGroupNonUniformRotateKHR: + case spv::Capability::GroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; - case SpvCapabilityAtomicFloat32AddEXT: + case spv::Capability::AtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; - case SpvCapabilityAtomicFloat64AddEXT: + case spv::Capability::AtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; - case SpvCapabilityLongConstantCompositeINTEL: + case spv::Capability::LongConstantCompositeINTEL: return "LongConstantCompositeINTEL"; - case SpvCapabilityOptNoneINTEL: + case spv::Capability::OptNoneINTEL: return "OptNoneINTEL"; - case SpvCapabilityAtomicFloat16AddEXT: + case spv::Capability::AtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; - case SpvCapabilityDebugInfoModuleINTEL: + case spv::Capability::DebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; - case SpvCapabilitySplitBarrierINTEL: + case spv::Capability::SplitBarrierINTEL: return "SplitBarrierINTEL"; - case SpvCapabilityGroupUniformArithmeticKHR: + case spv::Capability::GroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; - case SpvCapabilityMax: - assert(0 && "Attempting to convert SpvCapabilityMax to string"); + case spv::Capability::Max: + assert(0 && "Attempting to convert spv::Capability::Max to string"); return ""; } diff --git a/3rdparty/spirv-tools/include/generated/extension_enum.inc b/3rdparty/spirv-tools/include/generated/extension_enum.inc index 5597f09a6..cc785937c 100644 --- a/3rdparty/spirv-tools/include/generated/extension_enum.inc +++ b/3rdparty/spirv-tools/include/generated/extension_enum.inc @@ -37,6 +37,8 @@ kSPV_INTEL_float_controls2, kSPV_INTEL_fp_fast_math_mode, kSPV_INTEL_fpga_buffer_location, kSPV_INTEL_fpga_cluster_attributes, +kSPV_INTEL_fpga_dsp_control, +kSPV_INTEL_fpga_invocation_pipelining_attributes, kSPV_INTEL_fpga_loop_controls, kSPV_INTEL_fpga_memory_accesses, kSPV_INTEL_fpga_memory_attributes, @@ -50,6 +52,7 @@ kSPV_INTEL_loop_fuse, kSPV_INTEL_media_block_io, kSPV_INTEL_memory_access_aliasing, kSPV_INTEL_optnone, +kSPV_INTEL_runtime_aligned, kSPV_INTEL_shader_integer_functions2, kSPV_INTEL_split_barrier, kSPV_INTEL_subgroups, @@ -99,6 +102,7 @@ kSPV_NV_ray_tracing, kSPV_NV_ray_tracing_motion_blur, kSPV_NV_sample_mask_override_coverage, kSPV_NV_shader_image_footprint, +kSPV_NV_shader_invocation_reorder, kSPV_NV_shader_sm_builtins, kSPV_NV_shader_subgroup_partitioned, kSPV_NV_shading_rate, diff --git a/3rdparty/spirv-tools/include/generated/generators.inc b/3rdparty/spirv-tools/include/generated/generators.inc index a0ff5fefb..c8178b404 100644 --- a/3rdparty/spirv-tools/include/generated/generators.inc +++ b/3rdparty/spirv-tools/include/generated/generators.inc @@ -33,4 +33,5 @@ {32, "TornadoVM", "SPIRV Beehive Toolkit", "TornadoVM SPIRV Beehive Toolkit"}, {33, "DragonJoker", "ShaderWriter", "DragonJoker ShaderWriter"}, {34, "Rayan Hatout", "SPIRVSmith", "Rayan Hatout SPIRVSmith"}, -{35, "Saarland University", "Shady", "Saarland University Shady"}, \ No newline at end of file +{35, "Saarland University", "Shady", "Saarland University Shady"}, +{36, "Taichi Graphics", "Taichi", "Taichi Graphics Taichi"}, \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc b/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc index 7d3866d80..89fe94805 100644 --- a/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc +++ b/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc @@ -1,5 +1,5 @@ -static const SpvCapability pygen_variable_caps_Float64[] = {SpvCapabilityFloat64}; -static const SpvCapability pygen_variable_caps_InterpolationFunction[] = {SpvCapabilityInterpolationFunction}; +static const spv::Capability pygen_variable_caps_Float64[] = {spv::Capability::Float64}; +static const spv::Capability pygen_variable_caps_InterpolationFunction[] = {spv::Capability::InterpolationFunction}; static const spv_ext_inst_desc_t glsl_entries[] = { {"Round", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, diff --git a/3rdparty/spirv-tools/include/generated/nonsemantic.clspvreflection.insts.inc b/3rdparty/spirv-tools/include/generated/nonsemantic.clspvreflection.insts.inc index c3e38dd4c..f774297d2 100644 --- a/3rdparty/spirv-tools/include/generated/nonsemantic.clspvreflection.insts.inc +++ b/3rdparty/spirv-tools/include/generated/nonsemantic.clspvreflection.insts.inc @@ -1,7 +1,7 @@ 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}}, + {"Kernel", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_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}}, @@ -35,5 +35,10 @@ static const spv_ext_inst_desc_t nonsemantic_clspvreflection_entries[] = { {"ImageArgumentInfoChannelOrderUniform", 32, 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_NONE}}, {"ImageArgumentInfoChannelDataTypeUniform", 33, 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_NONE}}, {"ArgumentStorageTexelBuffer", 34, 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}}, - {"ArgumentUniformTexelBuffer", 35, 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}} + {"ArgumentUniformTexelBuffer", 35, 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}}, + {"ConstantDataPointerPushConstant", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ProgramScopeVariablePointerPushConstant", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PrintfInfo", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PrintfBufferStorageBuffer", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PrintfBufferPointerPushConstant", 40, 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/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc index 543a6e99f..b6d9c6b7a 100644 --- a/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc @@ -1,129 +1,133 @@ -static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddresses}; -static const SpvCapability pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL[] = {SpvCapabilityArbitraryPrecisionFixedPointINTEL}; -static const SpvCapability pygen_variable_caps_AsmINTEL[] = {SpvCapabilityAsmINTEL}; -static const SpvCapability pygen_variable_caps_AtomicStorage[] = {SpvCapabilityAtomicStorage}; -static const SpvCapability pygen_variable_caps_BindlessTextureNV[] = {SpvCapabilityBindlessTextureNV}; -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_CoreBuiltinsARM[] = {SpvCapabilityCoreBuiltinsARM}; -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_DrawParametersMeshShadingNVMeshShadingEXT[] = {SpvCapabilityDrawParameters, SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -static const SpvCapability pygen_variable_caps_FPFastMathModeINTEL[] = {SpvCapabilityFPFastMathModeINTEL}; -static const SpvCapability pygen_variable_caps_FPGABufferLocationINTEL[] = {SpvCapabilityFPGABufferLocationINTEL}; -static const SpvCapability pygen_variable_caps_FPGAClusterAttributesINTEL[] = {SpvCapabilityFPGAClusterAttributesINTEL}; -static const SpvCapability pygen_variable_caps_FPGAKernelAttributesINTEL[] = {SpvCapabilityFPGAKernelAttributesINTEL}; -static const SpvCapability pygen_variable_caps_FPGALoopControlsINTEL[] = {SpvCapabilityFPGALoopControlsINTEL}; -static const SpvCapability pygen_variable_caps_FPGAMemoryAccessesINTEL[] = {SpvCapabilityFPGAMemoryAccessesINTEL}; -static const SpvCapability pygen_variable_caps_FPGAMemoryAttributesINTEL[] = {SpvCapabilityFPGAMemoryAttributesINTEL}; -static const SpvCapability pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR[] = {SpvCapabilityFragmentBarycentricNV, SpvCapabilityFragmentBarycentricKHR}; -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_FragmentShadingRateKHR[] = {SpvCapabilityFragmentShadingRateKHR}; -static const SpvCapability pygen_variable_caps_FunctionFloatControlINTEL[] = {SpvCapabilityFunctionFloatControlINTEL}; -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_GeometryMeshShadingNVMeshShadingEXT[] = {SpvCapabilityGeometry, SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -static const SpvCapability pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT[] = {SpvCapabilityGeometry, SpvCapabilityShaderLayer, SpvCapabilityShaderViewportIndexLayerEXT, SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -static const SpvCapability pygen_variable_caps_GeometryTessellation[] = {SpvCapabilityGeometry, SpvCapabilityTessellation}; -static const SpvCapability pygen_variable_caps_GeometryTessellationMeshShadingNVMeshShadingEXT[] = {SpvCapabilityGeometry, SpvCapabilityTessellation, SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -static const SpvCapability pygen_variable_caps_GeometryTessellationRayTracingNVRayTracingKHRMeshShadingNVMeshShadingEXT[] = {SpvCapabilityGeometry, SpvCapabilityTessellation, SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR, SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -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_IOPipesINTEL[] = {SpvCapabilityIOPipesINTEL}; -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_Int64ImageEXT[] = {SpvCapabilityInt64ImageEXT}; -static const SpvCapability pygen_variable_caps_Int8[] = {SpvCapabilityInt8}; -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_LoopFuseINTEL[] = {SpvCapabilityLoopFuseINTEL}; -static const SpvCapability pygen_variable_caps_Matrix[] = {SpvCapabilityMatrix}; -static const SpvCapability pygen_variable_caps_MemoryAccessAliasingINTEL[] = {SpvCapabilityMemoryAccessAliasingINTEL}; -static const SpvCapability pygen_variable_caps_MeshShadingEXT[] = {SpvCapabilityMeshShadingEXT}; -static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityMeshShadingNV}; -static const SpvCapability pygen_variable_caps_MeshShadingNVMeshShadingEXT[] = {SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -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_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT[] = {SpvCapabilityMultiViewport, SpvCapabilityShaderViewportIndex, SpvCapabilityShaderViewportIndexLayerEXT, SpvCapabilityMeshShadingNV, SpvCapabilityMeshShadingEXT}; -static const SpvCapability pygen_variable_caps_OptNoneINTEL[] = {SpvCapabilityOptNoneINTEL}; -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_RayCullMaskKHR[] = {SpvCapabilityRayCullMaskKHR}; -static const SpvCapability pygen_variable_caps_RayQueryKHR[] = {SpvCapabilityRayQueryKHR}; -static const SpvCapability pygen_variable_caps_RayQueryKHRRayTracingKHR[] = {SpvCapabilityRayQueryKHR, SpvCapabilityRayTracingKHR}; -static const SpvCapability pygen_variable_caps_RayTracingKHR[] = {SpvCapabilityRayTracingKHR}; -static const SpvCapability pygen_variable_caps_RayTracingMotionBlurNV[] = {SpvCapabilityRayTracingMotionBlurNV}; -static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV}; -static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR}; -static const SpvCapability pygen_variable_caps_RayTracingOpacityMicromapEXT[] = {SpvCapabilityRayTracingOpacityMicromapEXT}; -static const SpvCapability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {SpvCapabilityRayTraversalPrimitiveCullingKHR}; -static const SpvCapability pygen_variable_caps_RoundToInfinityINTEL[] = {SpvCapabilityRoundToInfinityINTEL}; -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_ShaderUniformDecoration[] = {SpvCapabilityShader, SpvCapabilityUniformDecoration}; -static const SpvCapability pygen_variable_caps_ShaderVectorComputeINTEL[] = {SpvCapabilityShader, SpvCapabilityVectorComputeINTEL}; -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_USMStorageClassesINTEL[] = {SpvCapabilityUSMStorageClassesINTEL}; -static const SpvCapability pygen_variable_caps_VariablePointersStorageBuffer[] = {SpvCapabilityVariablePointersStorageBuffer}; -static const SpvCapability pygen_variable_caps_VectorAnyINTEL[] = {SpvCapabilityVectorAnyINTEL}; -static const SpvCapability pygen_variable_caps_VectorComputeINTEL[] = {SpvCapabilityVectorComputeINTEL}; -static const SpvCapability pygen_variable_caps_VulkanMemoryModel[] = {SpvCapabilityVulkanMemoryModel}; -static const SpvCapability pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR[] = {SpvCapabilityWorkgroupMemoryExplicitLayoutKHR}; +static const spv::Capability pygen_variable_caps_Addresses[] = {spv::Capability::Addresses}; +static const spv::Capability pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL[] = {spv::Capability::ArbitraryPrecisionFixedPointINTEL}; +static const spv::Capability pygen_variable_caps_AsmINTEL[] = {spv::Capability::AsmINTEL}; +static const spv::Capability pygen_variable_caps_AtomicStorage[] = {spv::Capability::AtomicStorage}; +static const spv::Capability pygen_variable_caps_BindlessTextureNV[] = {spv::Capability::BindlessTextureNV}; +static const spv::Capability pygen_variable_caps_ClipDistance[] = {spv::Capability::ClipDistance}; +static const spv::Capability pygen_variable_caps_ComputeDerivativeGroupLinearNV[] = {spv::Capability::ComputeDerivativeGroupLinearNV}; +static const spv::Capability pygen_variable_caps_ComputeDerivativeGroupQuadsNV[] = {spv::Capability::ComputeDerivativeGroupQuadsNV}; +static const spv::Capability pygen_variable_caps_CoreBuiltinsARM[] = {spv::Capability::CoreBuiltinsARM}; +static const spv::Capability pygen_variable_caps_CullDistance[] = {spv::Capability::CullDistance}; +static const spv::Capability pygen_variable_caps_DenormFlushToZero[] = {spv::Capability::DenormFlushToZero}; +static const spv::Capability pygen_variable_caps_DenormPreserve[] = {spv::Capability::DenormPreserve}; +static const spv::Capability pygen_variable_caps_DeviceEnqueue[] = {spv::Capability::DeviceEnqueue}; +static const spv::Capability pygen_variable_caps_DeviceGroup[] = {spv::Capability::DeviceGroup}; +static const spv::Capability pygen_variable_caps_DrawParameters[] = {spv::Capability::DrawParameters}; +static const spv::Capability pygen_variable_caps_DrawParametersMeshShadingNVMeshShadingEXT[] = {spv::Capability::DrawParameters, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_FPFastMathModeINTEL[] = {spv::Capability::FPFastMathModeINTEL}; +static const spv::Capability pygen_variable_caps_FPGABufferLocationINTEL[] = {spv::Capability::FPGABufferLocationINTEL}; +static const spv::Capability pygen_variable_caps_FPGAClusterAttributesINTEL[] = {spv::Capability::FPGAClusterAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPGADSPControlINTEL[] = {spv::Capability::FPGADSPControlINTEL}; +static const spv::Capability pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL[] = {spv::Capability::FPGAInvocationPipeliningAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPGAKernelAttributesINTEL[] = {spv::Capability::FPGAKernelAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPGALoopControlsINTEL[] = {spv::Capability::FPGALoopControlsINTEL}; +static const spv::Capability pygen_variable_caps_FPGAMemoryAccessesINTEL[] = {spv::Capability::FPGAMemoryAccessesINTEL}; +static const spv::Capability pygen_variable_caps_FPGAMemoryAttributesINTEL[] = {spv::Capability::FPGAMemoryAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR[] = {spv::Capability::FragmentBarycentricNV, spv::Capability::FragmentBarycentricKHR}; +static const spv::Capability pygen_variable_caps_FragmentDensityEXTShadingRateNV[] = {spv::Capability::FragmentDensityEXT, spv::Capability::ShadingRateNV}; +static const spv::Capability pygen_variable_caps_FragmentFullyCoveredEXT[] = {spv::Capability::FragmentFullyCoveredEXT}; +static const spv::Capability pygen_variable_caps_FragmentShaderPixelInterlockEXT[] = {spv::Capability::FragmentShaderPixelInterlockEXT}; +static const spv::Capability pygen_variable_caps_FragmentShaderSampleInterlockEXT[] = {spv::Capability::FragmentShaderSampleInterlockEXT}; +static const spv::Capability pygen_variable_caps_FragmentShaderShadingRateInterlockEXT[] = {spv::Capability::FragmentShaderShadingRateInterlockEXT}; +static const spv::Capability pygen_variable_caps_FragmentShadingRateKHR[] = {spv::Capability::FragmentShadingRateKHR}; +static const spv::Capability pygen_variable_caps_FunctionFloatControlINTEL[] = {spv::Capability::FunctionFloatControlINTEL}; +static const spv::Capability pygen_variable_caps_FunctionPointersINTEL[] = {spv::Capability::FunctionPointersINTEL}; +static const spv::Capability pygen_variable_caps_GenericPointer[] = {spv::Capability::GenericPointer}; +static const spv::Capability pygen_variable_caps_Geometry[] = {spv::Capability::Geometry}; +static const spv::Capability pygen_variable_caps_GeometryMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::ShaderLayer, spv::Capability::ShaderViewportIndexLayerEXT, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryTessellation[] = {spv::Capability::Geometry, spv::Capability::Tessellation}; +static const spv::Capability pygen_variable_caps_GeometryTessellationMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::Tessellation, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryTessellationRayTracingNVRayTracingKHRMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::Tessellation, spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryShaderPassthroughNV[] = {spv::Capability::GeometryShaderPassthroughNV}; +static const spv::Capability pygen_variable_caps_GeometryStreams[] = {spv::Capability::GeometryStreams}; +static const spv::Capability pygen_variable_caps_GroupNonUniform[] = {spv::Capability::GroupNonUniform}; +static const spv::Capability pygen_variable_caps_GroupNonUniformClustered[] = {spv::Capability::GroupNonUniformClustered}; +static const spv::Capability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {spv::Capability::GroupNonUniformPartitionedNV}; +static const spv::Capability pygen_variable_caps_IOPipesINTEL[] = {spv::Capability::IOPipesINTEL}; +static const spv::Capability pygen_variable_caps_ImageBasic[] = {spv::Capability::ImageBasic}; +static const spv::Capability pygen_variable_caps_ImageBuffer[] = {spv::Capability::ImageBuffer}; +static const spv::Capability pygen_variable_caps_ImageBufferShaderNonUniform[] = {spv::Capability::ImageBuffer, spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_ImageGatherExtended[] = {spv::Capability::ImageGatherExtended}; +static const spv::Capability pygen_variable_caps_IndirectReferencesINTEL[] = {spv::Capability::IndirectReferencesINTEL}; +static const spv::Capability pygen_variable_caps_InputAttachment[] = {spv::Capability::InputAttachment}; +static const spv::Capability pygen_variable_caps_InputAttachmentShaderNonUniform[] = {spv::Capability::InputAttachment, spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_Int64[] = {spv::Capability::Int64}; +static const spv::Capability pygen_variable_caps_Int64ImageEXT[] = {spv::Capability::Int64ImageEXT}; +static const spv::Capability pygen_variable_caps_Int8[] = {spv::Capability::Int8}; +static const spv::Capability pygen_variable_caps_Kernel[] = {spv::Capability::Kernel}; +static const spv::Capability pygen_variable_caps_KernelGroupNonUniform[] = {spv::Capability::Kernel, spv::Capability::GroupNonUniform}; +static const spv::Capability pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR[] = {spv::Capability::Kernel, spv::Capability::GroupNonUniform, spv::Capability::SubgroupBallotKHR}; +static const spv::Capability pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot[] = {spv::Capability::Kernel, spv::Capability::GroupNonUniformArithmetic, spv::Capability::GroupNonUniformBallot}; +static const spv::Capability pygen_variable_caps_KernelAttributesINTEL[] = {spv::Capability::KernelAttributesINTEL}; +static const spv::Capability pygen_variable_caps_Linkage[] = {spv::Capability::Linkage}; +static const spv::Capability pygen_variable_caps_LoopFuseINTEL[] = {spv::Capability::LoopFuseINTEL}; +static const spv::Capability pygen_variable_caps_Matrix[] = {spv::Capability::Matrix}; +static const spv::Capability pygen_variable_caps_MemoryAccessAliasingINTEL[] = {spv::Capability::MemoryAccessAliasingINTEL}; +static const spv::Capability pygen_variable_caps_MeshShadingEXT[] = {spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_MeshShadingNV[] = {spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_MeshShadingNVMeshShadingEXT[] = {spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_MinLod[] = {spv::Capability::MinLod}; +static const spv::Capability pygen_variable_caps_MultiView[] = {spv::Capability::MultiView}; +static const spv::Capability pygen_variable_caps_MultiViewport[] = {spv::Capability::MultiViewport}; +static const spv::Capability pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT[] = {spv::Capability::MultiViewport, spv::Capability::ShaderViewportIndex, spv::Capability::ShaderViewportIndexLayerEXT, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_OptNoneINTEL[] = {spv::Capability::OptNoneINTEL}; +static const spv::Capability pygen_variable_caps_PerViewAttributesNVMeshShadingNV[] = {spv::Capability::PerViewAttributesNV, spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {spv::Capability::PhysicalStorageBufferAddresses}; +static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes}; +static const spv::Capability pygen_variable_caps_RayCullMaskKHR[] = {spv::Capability::RayCullMaskKHR}; +static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_RayQueryKHRRayTracingKHR[] = {spv::Capability::RayQueryKHR, spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv::Capability::RayTracingMotionBlurNV}; +static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV}; +static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingOpacityMicromapEXT[] = {spv::Capability::RayTracingOpacityMicromapEXT}; +static const spv::Capability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {spv::Capability::RayTraversalPrimitiveCullingKHR}; +static const spv::Capability pygen_variable_caps_RoundToInfinityINTEL[] = {spv::Capability::RoundToInfinityINTEL}; +static const spv::Capability pygen_variable_caps_RoundingModeRTE[] = {spv::Capability::RoundingModeRTE}; +static const spv::Capability pygen_variable_caps_RoundingModeRTZ[] = {spv::Capability::RoundingModeRTZ}; +static const spv::Capability pygen_variable_caps_RuntimeAlignedAttributeINTEL[] = {spv::Capability::RuntimeAlignedAttributeINTEL}; +static const spv::Capability pygen_variable_caps_SampleMaskOverrideCoverageNV[] = {spv::Capability::SampleMaskOverrideCoverageNV}; +static const spv::Capability pygen_variable_caps_SampleMaskPostDepthCoverage[] = {spv::Capability::SampleMaskPostDepthCoverage}; +static const spv::Capability pygen_variable_caps_SampleRateShading[] = {spv::Capability::SampleRateShading}; +static const spv::Capability pygen_variable_caps_Sampled1D[] = {spv::Capability::Sampled1D}; +static const spv::Capability pygen_variable_caps_Sampled1DImage1D[] = {spv::Capability::Sampled1D, spv::Capability::Image1D}; +static const spv::Capability pygen_variable_caps_SampledBuffer[] = {spv::Capability::SampledBuffer}; +static const spv::Capability pygen_variable_caps_SampledBufferImageBuffer[] = {spv::Capability::SampledBuffer, spv::Capability::ImageBuffer}; +static const spv::Capability pygen_variable_caps_SampledBufferShaderNonUniform[] = {spv::Capability::SampledBuffer, spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_SampledCubeArray[] = {spv::Capability::SampledCubeArray}; +static const spv::Capability pygen_variable_caps_SampledRect[] = {spv::Capability::SampledRect}; +static const spv::Capability pygen_variable_caps_SampledRectImageRect[] = {spv::Capability::SampledRect, spv::Capability::ImageRect}; +static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader}; +static const spv::Capability pygen_variable_caps_ShaderImageCubeArray[] = {spv::Capability::Shader, spv::Capability::ImageCubeArray}; +static const spv::Capability pygen_variable_caps_ShaderKernel[] = {spv::Capability::Shader, spv::Capability::Kernel}; +static const spv::Capability pygen_variable_caps_ShaderKernelImageMSArray[] = {spv::Capability::Shader, spv::Capability::Kernel, spv::Capability::ImageMSArray}; +static const spv::Capability pygen_variable_caps_ShaderUniformDecoration[] = {spv::Capability::Shader, spv::Capability::UniformDecoration}; +static const spv::Capability pygen_variable_caps_ShaderVectorComputeINTEL[] = {spv::Capability::Shader, spv::Capability::VectorComputeINTEL}; +static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNV[] = {spv::Capability::ShaderInvocationReorderNV}; +static const spv::Capability pygen_variable_caps_ShaderNonUniform[] = {spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_ShaderSMBuiltinsNV[] = {spv::Capability::ShaderSMBuiltinsNV}; +static const spv::Capability pygen_variable_caps_ShaderStereoViewNV[] = {spv::Capability::ShaderStereoViewNV}; +static const spv::Capability pygen_variable_caps_ShaderViewportIndexLayerNV[] = {spv::Capability::ShaderViewportIndexLayerNV}; +static const spv::Capability pygen_variable_caps_ShaderViewportMaskNV[] = {spv::Capability::ShaderViewportMaskNV}; +static const spv::Capability pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV[] = {spv::Capability::ShaderViewportMaskNV, spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_ShadingRateNVFragmentDensityEXT[] = {spv::Capability::ShadingRateNV, spv::Capability::FragmentDensityEXT}; +static const spv::Capability pygen_variable_caps_SignedZeroInfNanPreserve[] = {spv::Capability::SignedZeroInfNanPreserve}; +static const spv::Capability pygen_variable_caps_StencilExportEXT[] = {spv::Capability::StencilExportEXT}; +static const spv::Capability pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16[] = {spv::Capability::StorageBuffer16BitAccess, spv::Capability::StorageUniformBufferBlock16}; +static const spv::Capability pygen_variable_caps_StorageBuffer8BitAccess[] = {spv::Capability::StorageBuffer8BitAccess}; +static const spv::Capability pygen_variable_caps_StorageImageExtendedFormats[] = {spv::Capability::StorageImageExtendedFormats}; +static const spv::Capability pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot[] = {spv::Capability::SubgroupBallotKHR, spv::Capability::GroupNonUniformBallot}; +static const spv::Capability pygen_variable_caps_SubgroupDispatch[] = {spv::Capability::SubgroupDispatch}; +static const spv::Capability pygen_variable_caps_Tessellation[] = {spv::Capability::Tessellation}; +static const spv::Capability pygen_variable_caps_TransformFeedback[] = {spv::Capability::TransformFeedback}; +static const spv::Capability pygen_variable_caps_USMStorageClassesINTEL[] = {spv::Capability::USMStorageClassesINTEL}; +static const spv::Capability pygen_variable_caps_VariablePointersStorageBuffer[] = {spv::Capability::VariablePointersStorageBuffer}; +static const spv::Capability pygen_variable_caps_VectorAnyINTEL[] = {spv::Capability::VectorAnyINTEL}; +static const spv::Capability pygen_variable_caps_VectorComputeINTEL[] = {spv::Capability::VectorComputeINTEL}; +static const spv::Capability pygen_variable_caps_VulkanMemoryModel[] = {spv::Capability::VulkanMemoryModel}; +static const spv::Capability pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR[] = {spv::Capability::WorkgroupMemoryExplicitLayoutKHR}; 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}; @@ -162,6 +166,8 @@ static const spvtools::Extension pygen_variable_exts_SPV_INTEL_float_controls2[] static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fp_fast_math_mode[] = {spvtools::Extension::kSPV_INTEL_fp_fast_math_mode}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_buffer_location[] = {spvtools::Extension::kSPV_INTEL_fpga_buffer_location}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_cluster_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_dsp_control[] = {spvtools::Extension::kSPV_INTEL_fpga_dsp_control}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_invocation_pipelining_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes}; 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_accesses[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_accesses}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_memory_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_attributes}; @@ -175,6 +181,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_INTEL_loop_fuse[] = {sp 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_memory_access_aliasing[] = {spvtools::Extension::kSPV_INTEL_memory_access_aliasing}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_optnone[] = {spvtools::Extension::kSPV_INTEL_optnone}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_runtime_aligned[] = {spvtools::Extension::kSPV_INTEL_runtime_aligned}; 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_split_barrier[] = {spvtools::Extension::kSPV_INTEL_split_barrier}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroups[] = {spvtools::Extension::kSPV_INTEL_subgroups}; @@ -224,6 +231,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spv static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing_motion_blur[] = {spvtools::Extension::kSPV_NV_ray_tracing_motion_blur}; 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_invocation_reorder[] = {spvtools::Extension::kSPV_NV_shader_invocation_reorder}; 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}; @@ -281,14 +289,16 @@ static const spv_operand_desc_t pygen_variable_LoopControlEntries[] = { {"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}, - {"NoFusionINTEL", 0x800000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} + {"InitiationIntervalINTEL", 0x10000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxConcurrencyINTEL", 0x20000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"DependencyArrayINTEL", 0x40000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PipelineEnableINTEL", 0x80000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"LoopCoalesceINTEL", 0x100000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxInterleavingINTEL", 0x200000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SpeculatedIterationsINTEL", 0x400000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"NoFusionINTEL", 0x800000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"LoopCountINTEL", 0x1000000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxReinvocationDelayINTEL", 0x2000000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_FunctionControlEntries[] = { @@ -495,6 +505,7 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = { {"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}, {"SchedulerTargetFmaxMhzINTEL", 5903, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"StreamingInterfaceINTEL", 6154, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"NamedBarrierCountINTEL", 6417, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} }; @@ -526,6 +537,7 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { {"ShaderRecordBufferKHR", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 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}, + {"HitObjectAttributeNV", 5385, 1, pygen_variable_caps_ShaderInvocationReorderNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"TaskPayloadWorkgroupEXT", 5402, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, {"CodeSectionINTEL", 5605, 1, pygen_variable_caps_FunctionPointersINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, {"DeviceOnlyINTEL", 5936, 1, pygen_variable_caps_USMStorageClassesINTEL, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu}, @@ -698,7 +710,8 @@ static const spv_operand_desc_t pygen_variable_FunctionParameterAttributeEntries {"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} + {"NoReadWrite", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RuntimeAlignedINTEL", 5940, 1, pygen_variable_caps_RuntimeAlignedAttributeINTEL, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { @@ -768,6 +781,7 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { {"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}, + {"HitObjectShaderRecordBufferNV", 5386, 1, pygen_variable_caps_ShaderInvocationReorderNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"BindlessSamplerNV", 5398, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"BindlessImageNV", 5399, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"BoundSamplerNV", 5400, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, @@ -806,8 +820,12 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { {"PrefetchINTEL", 5902, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"StallEnableINTEL", 5905, 1, pygen_variable_caps_FPGAClusterAttributesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"FuseLoopsInFunctionINTEL", 5907, 1, pygen_variable_caps_LoopFuseINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MathOpDSPModeINTEL", 5909, 1, pygen_variable_caps_FPGADSPControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"AliasScopeINTEL", 5914, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, {"NoAliasINTEL", 5915, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"InitiationIntervalINTEL", 5917, 1, pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxConcurrencyINTEL", 5918, 1, pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PipelineEnableINTEL", 5919, 1, pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"BufferLocationINTEL", 5921, 1, pygen_variable_caps_FPGABufferLocationINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"IOPipeStorageINTEL", 5944, 1, pygen_variable_caps_IOPipesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"FunctionFloatingPointModeINTEL", 6080, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FPOPERATION_MODE}, 0xffffffffu, 0xffffffffu}, @@ -1146,6 +1164,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"DemoteToHelperInvocation", 5379, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, {"DemoteToHelperInvocationEXT", 5379, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, {"RayTracingOpacityMicromapEXT", 5381, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 1, pygen_variable_exts_SPV_EXT_opacity_micromap, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderInvocationReorderNV", 5383, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_shader_invocation_reorder, {}, 0xffffffffu, 0xffffffffu}, {"BindlessTextureNV", 5390, 0, nullptr, 1, pygen_variable_exts_SPV_NV_bindless_texture, {}, 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}, @@ -1179,10 +1198,13 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"FPGAMemoryAccessesINTEL", 5898, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_accesses, {}, 0xffffffffu, 0xffffffffu}, {"FPGAClusterAttributesINTEL", 5904, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes, {}, 0xffffffffu, 0xffffffffu}, {"LoopFuseINTEL", 5906, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_loop_fuse, {}, 0xffffffffu, 0xffffffffu}, + {"FPGADSPControlINTEL", 5908, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_dsp_control, {}, 0xffffffffu, 0xffffffffu}, {"MemoryAccessAliasingINTEL", 5910, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAInvocationPipeliningAttributesINTEL", 5916, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_invocation_pipelining_attributes, {}, 0xffffffffu, 0xffffffffu}, {"FPGABufferLocationINTEL", 5920, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_buffer_location, {}, 0xffffffffu, 0xffffffffu}, {"ArbitraryPrecisionFixedPointINTEL", 5922, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_arbitrary_precision_fixed_point, {}, 0xffffffffu, 0xffffffffu}, {"USMStorageClassesINTEL", 5935, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu}, + {"RuntimeAlignedAttributeINTEL", 5939, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_runtime_aligned, {}, 0xffffffffu, 0xffffffffu}, {"IOPipesINTEL", 5943, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_io_pipes, {}, 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}, diff --git a/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp b/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp index a19491fd3..a75561b50 100644 --- a/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp +++ b/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp @@ -36,16 +36,25 @@ namespace spvtools { // generated by InstrumentPass::GenDebugStreamWrite. This method is utilized // by InstBindlessCheckPass, InstBuffAddrCheckPass, and InstDebugPrintfPass. // -// The first member of the debug output buffer contains the next available word +// The 1st member of the debug output buffer contains a set of flags +// controlling the behavior of instrumentation code. +static const int kDebugOutputFlagsOffset = 0; + +// Values stored at kDebugOutputFlagsOffset +enum kInstFlags : unsigned int { + kInstBufferOOBEnable = 0x1, +}; + +// The 2nd member of the debug output buffer contains the next available word // in the data stream to be written. Shaders will atomically read and update // this value so as not to overwrite each others records. This value must be // initialized to zero -static const int kDebugOutputSizeOffset = 0; +static const int kDebugOutputSizeOffset = 1; -// The second member of the output buffer is the start of the stream of records +// The 3rd member of the output buffer is the start of the stream of records // written by the instrumented shaders. Each record represents a validation // error. The format of the records is documented below. -static const int kDebugOutputDataOffset = 1; +static const int kDebugOutputDataOffset = 2; // Common Stream Record Offsets // diff --git a/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp b/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp index 949735608..aa6a614ea 100644 --- a/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp +++ b/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -520,8 +521,12 @@ Optimizer::PassToken CreateDeadInsertElimPass(); // interface are considered live and are not eliminated. This mode is needed // by GPU-Assisted validation instrumentation, where a change in the interface // is not allowed. -Optimizer::PassToken CreateAggressiveDCEPass(); -Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface); +// +// If |remove_outputs| is true, allow outputs to be removed from the interface. +// This is only safe if the caller knows that there is no corresponding input +// variable in the following shader. It is false by default. +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface = false, + bool remove_outputs = false); // Creates a remove-unused-interface-variables pass. // Removes variables referenced on the |OpEntryPoint| instruction that are not @@ -887,12 +892,59 @@ Optimizer::PassToken CreateAmdExtToKhrPass(); Optimizer::PassToken CreateInterpolateFixupPass(); // Removes unused components from composite input variables. Current -// implementation just removes trailing unused components from input arrays. -// The pass performs best after maximizing dead code removal. A subsequent dead -// code elimination pass would be beneficial in removing newly unused component -// types. +// implementation just removes trailing unused components from input arrays +// and structs. The pass performs best after maximizing dead code removal. +// A subsequent dead code elimination pass would be beneficial in removing +// newly unused component types. +// +// WARNING: This pass can only be safely applied standalone to vertex shaders +// as it can otherwise cause interface incompatibilities with the preceding +// shader in the pipeline. If applied to non-vertex shaders, the user should +// follow by applying EliminateDeadOutputStores and +// EliminateDeadOutputComponents to the preceding shader. Optimizer::PassToken CreateEliminateDeadInputComponentsPass(); +// Removes unused components from composite output variables. Current +// implementation just removes trailing unused components from output arrays +// and structs. The pass performs best after eliminating dead output stores. +// A subsequent dead code elimination pass would be beneficial in removing +// newly unused component types. Currently only supports vertex and fragment +// shaders. +// +// WARNING: This pass cannot be safely applied standalone as it can cause +// interface incompatibility with the following shader in the pipeline. The +// user should first apply EliminateDeadInputComponents to the following +// shader, then apply EliminateDeadOutputStores to this shader. +Optimizer::PassToken CreateEliminateDeadOutputComponentsPass(); + +// Removes unused components from composite input variables. This safe +// version will not cause interface incompatibilities since it only changes +// vertex shaders. The current implementation just removes trailing unused +// components from input structs and input arrays. The pass performs best +// after maximizing dead code removal. A subsequent dead code elimination +// pass would be beneficial in removing newly unused component types. +Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass(); + +// Analyzes shader and populates |live_locs| and |live_builtins|. Best results +// will be obtained if shader has all dead code eliminated first. |live_locs| +// and |live_builtins| are subsequently used when calling +// CreateEliminateDeadOutputStoresPass on the preceding shader. Currently only +// supports tesc, tese, geom, and frag shaders. +Optimizer::PassToken CreateAnalyzeLiveInputPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins); + +// Removes stores to output locations not listed in |live_locs| or +// |live_builtins|. Best results are obtained if constant propagation is +// performed first. A subsequent call to ADCE will eliminate any dead code +// created by the removal of the stores. A subsequent call to +// CreateEliminateDeadOutputComponentsPass will eliminate any dead output +// components created by the elimination of the stores. Currently only supports +// vert, tesc, tese, and geom shaders. +Optimizer::PassToken CreateEliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins); + // Creates a convert-to-sampled-image pass to convert images and/or // samplers with given pairs of descriptor set and binding to sampled image. // If a pair of an image and a sampler have the same pair of descriptor set and diff --git a/3rdparty/spirv-tools/source/assembly_grammar.cpp b/3rdparty/spirv-tools/source/assembly_grammar.cpp index 4f5942ab4..6df823e30 100644 --- a/3rdparty/spirv-tools/source/assembly_grammar.cpp +++ b/3rdparty/spirv-tools/source/assembly_grammar.cpp @@ -78,16 +78,16 @@ spv_result_t spvTextParseMaskOperand(spv_target_env env, // Associates an opcode with its name. struct SpecConstantOpcodeEntry { - SpvOp opcode; + spv::Op opcode; const char* name; }; // All the opcodes allowed as the operation for OpSpecConstantOp. -// The name does not have the usual "Op" prefix. For example opcode SpvOpIAdd -// is associated with the name "IAdd". +// The name does not have the usual "Op" prefix. For example opcode +// spv::Op::IAdd is associated with the name "IAdd". // // clang-format off -#define CASE(NAME) { SpvOp##NAME, #NAME } +#define CASE(NAME) { spv::Op::Op##NAME, #NAME } const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = { // Conversion CASE(SConvert), @@ -173,7 +173,7 @@ bool AssemblyGrammar::isValid() const { } CapabilitySet AssemblyGrammar::filterCapsAgainstTargetEnv( - const SpvCapability* cap_array, uint32_t count) const { + const spv::Capability* cap_array, uint32_t count) const { CapabilitySet cap_set; for (uint32_t i = 0; i < count; ++i) { spv_operand_desc cap_desc = {}; @@ -194,7 +194,7 @@ spv_result_t AssemblyGrammar::lookupOpcode(const char* name, return spvOpcodeTableNameLookup(target_env_, opcodeTable_, name, desc); } -spv_result_t AssemblyGrammar::lookupOpcode(SpvOp opcode, +spv_result_t AssemblyGrammar::lookupOpcode(spv::Op opcode, spv_opcode_desc* desc) const { return spvOpcodeTableValueLookup(target_env_, opcodeTable_, opcode, desc); } @@ -214,7 +214,7 @@ spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type, } spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name, - SpvOp* opcode) const { + spv::Op* opcode) const { const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes; const auto* found = std::find_if(kOpSpecConstantOpcodes, last, @@ -226,7 +226,7 @@ spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name, return SPV_SUCCESS; } -spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(SpvOp opcode) const { +spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(spv::Op opcode) const { const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes; const auto* found = std::find_if(kOpSpecConstantOpcodes, last, diff --git a/3rdparty/spirv-tools/source/assembly_grammar.h b/3rdparty/spirv-tools/source/assembly_grammar.h index 17c2bd3ba..36fdd08a6 100644 --- a/3rdparty/spirv-tools/source/assembly_grammar.h +++ b/3rdparty/spirv-tools/source/assembly_grammar.h @@ -41,7 +41,7 @@ class AssemblyGrammar { // Removes capabilities not available in the current target environment and // returns the rest. - CapabilitySet filterCapsAgainstTargetEnv(const SpvCapability* cap_array, + CapabilitySet filterCapsAgainstTargetEnv(const spv::Capability* cap_array, uint32_t count) const; // Fills in the desc parameter with the information about the opcode @@ -52,7 +52,7 @@ class AssemblyGrammar { // Fills in the desc parameter with the information about the opcode // of the valid. Returns SPV_SUCCESS if the opcode was found, and // SPV_ERROR_INVALID_LOOKUP if the opcode does not exist. - spv_result_t lookupOpcode(SpvOp opcode, spv_opcode_desc* desc) const; + spv_result_t lookupOpcode(spv::Op opcode, spv_opcode_desc* desc) const; // Fills in the desc parameter with the information about the given // operand. Returns SPV_SUCCESS if the operand was found, and @@ -82,11 +82,12 @@ class AssemblyGrammar { // the integer add opcode for OpSpecConstantOp. On success, returns // SPV_SUCCESS and sends the discovered operation code through the opcode // parameter. On failure, returns SPV_ERROR_INVALID_LOOKUP. - spv_result_t lookupSpecConstantOpcode(const char* name, SpvOp* opcode) const; + spv_result_t lookupSpecConstantOpcode(const char* name, + spv::Op* opcode) const; // Returns SPV_SUCCESS if the given opcode is valid as the opcode operand // to OpSpecConstantOp. - spv_result_t lookupSpecConstantOpcode(SpvOp opcode) const; + spv_result_t lookupSpecConstantOpcode(spv::Op opcode) const; // Parses a mask expression string for the given operand type. // diff --git a/3rdparty/spirv-tools/source/binary.cpp b/3rdparty/spirv-tools/source/binary.cpp index 24d32f8c4..beb56be7b 100644 --- a/3rdparty/spirv-tools/source/binary.cpp +++ b/3rdparty/spirv-tools/source/binary.cpp @@ -156,7 +156,7 @@ class Parser { // Issues a diagnostic describing an exhaustion of input condition when // trying to decode an instruction operand, and returns // SPV_ERROR_INVALID_BINARY. - spv_result_t exhaustedInputDiagnostic(size_t inst_offset, SpvOp opcode, + spv_result_t exhaustedInputDiagnostic(size_t inst_offset, spv::Op opcode, spv_operand_type_t type) { return diagnostic() << "End of input reached while decoding Op" << spvOpcodeString(opcode) << " starting at word " @@ -318,7 +318,7 @@ spv_result_t Parser::parseInstruction() { << inst_word_count; } spv_opcode_desc opcode_desc; - if (grammar_.lookupOpcode(static_cast(inst.opcode), &opcode_desc)) + if (grammar_.lookupOpcode(static_cast(inst.opcode), &opcode_desc)) return diagnostic() << "Invalid opcode: " << inst.opcode; // Advance past the opcode word. But remember the of the start @@ -418,7 +418,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, std::vector* words, std::vector* operands, spv_operand_pattern_t* expected_operands) { - const SpvOp opcode = static_cast(inst->opcode); + const spv::Op opcode = static_cast(inst->opcode); // We'll fill in this result as we go along. spv_parsed_operand_t parsed_operand; parsed_operand.offset = uint16_t(_.word_index - inst_offset); @@ -473,7 +473,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0"; parsed_operand.type = SPV_OPERAND_TYPE_ID; - if (opcode == SpvOpExtInst && parsed_operand.offset == 3) { + if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) { // The current word is the extended instruction set Id. // Set the extended instruction set type for the current instruction. auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word); @@ -494,7 +494,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, break; case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { - assert(SpvOpExtInst == opcode); + assert(spv::Op::OpExtInst == opcode); assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE); spv_ext_inst_desc ext_inst; if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) == @@ -516,14 +516,14 @@ spv_result_t Parser::parseOperand(size_t inst_offset, } break; case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { - assert(SpvOpSpecConstantOp == opcode); - if (word > static_cast(SpvOp::SpvOpMax) || - grammar_.lookupSpecConstantOpcode(SpvOp(word))) { + assert(spv::Op::OpSpecConstantOp == opcode); + if (word > static_cast(spv::Op::Max) || + grammar_.lookupSpecConstantOpcode(spv::Op(word))) { return diagnostic() << "Invalid " << spvOperandTypeStr(type) << ": " << word; } spv_opcode_desc opcode_entry = nullptr; - if (grammar_.lookupOpcode(SpvOp(word), &opcode_entry)) { + if (grammar_.lookupOpcode(spv::Op(word), &opcode_entry)) { return diagnostic(SPV_ERROR_INTERNAL) << "OpSpecConstant opcode table out of sync"; } @@ -549,7 +549,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER; - if (opcode == SpvOpSwitch) { + if (opcode == spv::Op::OpSwitch) { // The literal operands have the same type as the value // referenced by the selector Id. const uint32_t selector_id = peekAt(inst_offset + 1); @@ -575,7 +575,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset, << " is not a scalar integer"; } } else { - assert(opcode == SpvOpConstant || opcode == SpvOpSpecConstant); + assert(opcode == spv::Op::OpConstant || + opcode == spv::Op::OpSpecConstant); // The literal number type is determined by the type Id for the // constant. assert(inst->type_id); @@ -607,7 +608,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, parsed_operand.num_words = uint16_t(string_num_words); parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_STRING; - if (SpvOpExtInstImport == opcode) { + if (spv::Op::OpExtInstImport == opcode) { // Record the extended instruction type for the ID for this import. // There is only one string literal argument to OpExtInstImport, // so it's sufficient to guard this just on the opcode. @@ -789,14 +790,14 @@ spv_result_t Parser::setNumericTypeInfoForType( void Parser::recordNumberType(size_t inst_offset, const spv_parsed_instruction_t* inst) { - const SpvOp opcode = static_cast(inst->opcode); + const spv::Op opcode = static_cast(inst->opcode); if (spvOpcodeGeneratesType(opcode)) { NumberType info = {SPV_NUMBER_NONE, 0}; - if (SpvOpTypeInt == opcode) { + if (spv::Op::OpTypeInt == opcode) { const bool is_signed = peekAt(inst_offset + 3) != 0; info.type = is_signed ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT; info.bit_width = peekAt(inst_offset + 2); - } else if (SpvOpTypeFloat == opcode) { + } else if (spv::Op::OpTypeFloat == opcode) { info.type = SPV_NUMBER_FLOATING; info.bit_width = peekAt(inst_offset + 2); } diff --git a/3rdparty/spirv-tools/source/diff/diff.cpp b/3rdparty/spirv-tools/source/diff/diff.cpp index 7ed41de58..6daed321d 100644 --- a/3rdparty/spirv-tools/source/diff/diff.cpp +++ b/3rdparty/spirv-tools/source/diff/diff.cpp @@ -44,8 +44,8 @@ using IdGroup = std::vector; // different implementations produce identical results. using IdGroupMapByName = std::map; using IdGroupMapByTypeId = std::map; -using IdGroupMapByOp = std::map; -using IdGroupMapByStorageClass = std::map; +using IdGroupMapByOp = std::map; +using IdGroupMapByStorageClass = std::map; // A set of potential id mappings that haven't been resolved yet. Any id in src // may map in any id in dst. Note that ids are added in the same order as they @@ -301,10 +301,10 @@ class Differ { // Get various properties from an id. These Helper functions are passed to // `GroupIds` and `GroupIdsAndMatch` below (as the `get_group` argument). uint32_t GroupIdsHelperGetTypeId(const IdInstructions& id_to, uint32_t id); - SpvStorageClass GroupIdsHelperGetTypePointerStorageClass( + spv::StorageClass GroupIdsHelperGetTypePointerStorageClass( const IdInstructions& id_to, uint32_t id); - SpvOp GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, - uint32_t id); + spv::Op GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, + uint32_t id); // Given a list of ids, groups them based on some value. The `get_group` // function extracts a piece of information corresponding to each id, and the @@ -414,8 +414,8 @@ class Differ { // Helper functions to retrieve information pertaining to an id const opt::Instruction* GetInst(const IdInstructions& id_to, uint32_t id); uint32_t GetConstantUint(const IdInstructions& id_to, uint32_t constant_id); - SpvExecutionModel GetExecutionModel(const opt::Module* module, - uint32_t entry_point_id); + spv::ExecutionModel GetExecutionModel(const opt::Module* module, + uint32_t entry_point_id); bool HasName(const IdInstructions& id_to, uint32_t id); // Get the OpName associated with an id std::string GetName(const IdInstructions& id_to, uint32_t id, bool* has_name); @@ -424,20 +424,21 @@ class Differ { // string, and this improves diff between SPIR-V from those tools and others. std::string GetSanitizedName(const IdInstructions& id_to, uint32_t id); uint32_t GetVarTypeId(const IdInstructions& id_to, uint32_t var_id, - SpvStorageClass* storage_class); + spv::StorageClass* storage_class); bool GetDecorationValue(const IdInstructions& id_to, uint32_t id, - SpvDecoration decoration, uint32_t* decoration_value); + spv::Decoration decoration, + uint32_t* decoration_value); const opt::Instruction* GetForwardPointerInst(const IdInstructions& id_to, uint32_t id); bool IsIntType(const IdInstructions& id_to, uint32_t type_id); bool IsFloatType(const IdInstructions& id_to, uint32_t type_id); bool IsConstantUint(const IdInstructions& id_to, uint32_t id); bool IsVariable(const IdInstructions& id_to, uint32_t pointer_id); - bool IsOp(const IdInstructions& id_to, uint32_t id, SpvOp opcode); + bool IsOp(const IdInstructions& id_to, uint32_t id, spv::Op opcode); bool IsPerVertexType(const IdInstructions& id_to, uint32_t type_id); bool IsPerVertexVariable(const IdInstructions& id_to, uint32_t type_id); - SpvStorageClass GetPerVertexStorageClass(const opt::Module* module, - uint32_t type_id); + spv::StorageClass GetPerVertexStorageClass(const opt::Module* module, + uint32_t type_id); spv_ext_inst_type_t GetExtInstType(const IdInstructions& id_to, uint32_t set_id); spv_number_kind_t GetNumberKind(const IdInstructions& id_to, @@ -561,19 +562,19 @@ void IdInstructions::MapIdsToInfos( uint32_t id_operand = 0; switch (inst.opcode()) { - case SpvOpName: + case spv::Op::OpName: info_map = &name_map_; break; - case SpvOpMemberName: + case spv::Op::OpMemberName: info_map = &name_map_; break; - case SpvOpDecorate: + case spv::Op::OpDecorate: info_map = &decoration_map_; break; - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: info_map = &decoration_map_; break; - case SpvOpTypeForwardPointer: { + case spv::Op::OpTypeForwardPointer: { uint32_t id = inst.GetSingleWordOperand(0); assert(id != 0); @@ -731,10 +732,10 @@ int Differ::ComparePreambleInstructions(const opt::Instruction* a, // Instead of comparing OpExecutionMode entry point ids as ids, compare them // through their corresponding execution model. This simplifies traversing // the sorted list of instructions between src and dst modules. - if (a->opcode() == SpvOpExecutionMode) { - const SpvExecutionModel src_model = + if (a->opcode() == spv::Op::OpExecutionMode) { + const spv::ExecutionModel src_model = GetExecutionModel(src_inst_module, a->GetSingleWordOperand(0)); - const SpvExecutionModel dst_model = + const spv::ExecutionModel dst_model = GetExecutionModel(dst_inst_module, b->GetSingleWordOperand(0)); if (src_model < dst_model) { @@ -818,17 +819,17 @@ uint32_t Differ::GroupIdsHelperGetTypeId(const IdInstructions& id_to, return GetInst(id_to, id)->type_id(); } -SpvStorageClass Differ::GroupIdsHelperGetTypePointerStorageClass( +spv::StorageClass Differ::GroupIdsHelperGetTypePointerStorageClass( const IdInstructions& id_to, uint32_t id) { const opt::Instruction* inst = GetInst(id_to, id); - assert(inst && inst->opcode() == SpvOpTypePointer); - return SpvStorageClass(inst->GetSingleWordInOperand(0)); + assert(inst && inst->opcode() == spv::Op::OpTypePointer); + return spv::StorageClass(inst->GetSingleWordInOperand(0)); } -SpvOp Differ::GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, - uint32_t id) { +spv::Op Differ::GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, + uint32_t id) { const opt::Instruction* inst = GetInst(id_to, id); - assert(inst && inst->opcode() == SpvOpTypePointer); + assert(inst && inst->opcode() == spv::Op::OpTypePointer); const uint32_t type_id = inst->GetSingleWordInOperand(1); const opt::Instruction* type_inst = GetInst(id_to, type_id); @@ -1020,7 +1021,7 @@ bool Differ::DoInstructionsMatchFuzzy(const opt::Instruction* src_inst, } // For external instructions, make sure the set and opcode of the external // instruction matches too. - if (src_inst->opcode() == SpvOpExtInst) { + if (src_inst->opcode() == spv::Op::OpExtInst) { if (!DoOperandsMatch(src_inst, dst_inst, 0, 2)) { return false; } @@ -1064,26 +1065,26 @@ bool Differ::DoDebugAndAnnotationInstructionsMatch( } switch (src_inst->opcode()) { - case SpvOpString: - case SpvOpSourceExtension: - case SpvOpModuleProcessed: + case spv::Op::OpString: + case spv::Op::OpSourceExtension: + case spv::Op::OpModuleProcessed: return DoesOperandMatch(src_inst->GetOperand(0), dst_inst->GetOperand(0)); - case SpvOpSource: + case spv::Op::OpSource: return DoOperandsMatch(src_inst, dst_inst, 0, 2); - case SpvOpSourceContinued: + case spv::Op::OpSourceContinued: return true; - case SpvOpName: + case spv::Op::OpName: return DoOperandsMatch(src_inst, dst_inst, 0, 1); - case SpvOpMemberName: + case spv::Op::OpMemberName: return DoOperandsMatch(src_inst, dst_inst, 0, 2); - case SpvOpDecorate: + case spv::Op::OpDecorate: return DoOperandsMatch(src_inst, dst_inst, 0, 2); - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: return DoOperandsMatch(src_inst, dst_inst, 0, 3); - case SpvOpExtInst: - case SpvOpDecorationGroup: - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: + case spv::Op::OpExtInst: + case spv::Op::OpDecorationGroup: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: return false; default: return false; @@ -1095,9 +1096,9 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id, // Variables must match by their built-in decorations. uint32_t src_built_in_decoration = 0, dst_built_in_decoration = 0; const bool src_is_built_in = GetDecorationValue( - src_id_to_, src_id, SpvDecorationBuiltIn, &src_built_in_decoration); + src_id_to_, src_id, spv::Decoration::BuiltIn, &src_built_in_decoration); const bool dst_is_built_in = GetDecorationValue( - dst_id_to_, dst_id, SpvDecorationBuiltIn, &dst_built_in_decoration); + dst_id_to_, dst_id, spv::Decoration::BuiltIn, &dst_built_in_decoration); if (src_is_built_in != dst_is_built_in) { return false; @@ -1107,7 +1108,7 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id, } // Check their types and storage classes. - SpvStorageClass src_storage_class, dst_storage_class; + spv::StorageClass src_storage_class, dst_storage_class; const uint32_t src_type_id = GetVarTypeId(src_id_to_, src_id, &src_storage_class); const uint32_t dst_type_id = @@ -1127,12 +1128,14 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id, // Allow one of the two to be Private while the other is Input or // Output, this allows matching in/out variables that have been turned // global as part of linking two stages (as done in ANGLE). - const bool src_is_io = src_storage_class == SpvStorageClassInput || - src_storage_class == SpvStorageClassOutput; - const bool dst_is_io = dst_storage_class == SpvStorageClassInput || - dst_storage_class == SpvStorageClassOutput; - const bool src_is_private = src_storage_class == SpvStorageClassPrivate; - const bool dst_is_private = dst_storage_class == SpvStorageClassPrivate; + const bool src_is_io = src_storage_class == spv::StorageClass::Input || + src_storage_class == spv::StorageClass::Output; + const bool dst_is_io = dst_storage_class == spv::StorageClass::Input || + dst_storage_class == spv::StorageClass::Output; + const bool src_is_private = + src_storage_class == spv::StorageClass::Private; + const bool dst_is_private = + dst_storage_class == spv::StorageClass::Private; if (!((src_is_io && dst_is_private) || (src_is_private && dst_is_io))) { return false; @@ -1277,16 +1280,16 @@ bool Differ::MatchOpSpecConstant(const opt::Instruction* src_inst, // Otherwise, match them by SpecId. uint32_t src_spec_id, dst_spec_id; - if (GetDecorationValue(src_id_to_, src_id, SpvDecorationSpecId, + if (GetDecorationValue(src_id_to_, src_id, spv::Decoration::SpecId, &src_spec_id) && - GetDecorationValue(dst_id_to_, dst_id, SpvDecorationSpecId, + GetDecorationValue(dst_id_to_, dst_id, spv::Decoration::SpecId, &dst_spec_id)) { return src_spec_id == dst_spec_id; } // There is no SpecId decoration, while not practical, still valid. // SpecConstantOp don't have SpecId and can be matched by operands - if (src_inst->opcode() == SpvOpSpecConstantOp) { + if (src_inst->opcode() == spv::Op::OpSpecConstantOp) { if (src_inst->NumInOperandWords() == dst_inst->NumInOperandWords()) { return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); @@ -1327,13 +1330,13 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst, // built-in decorations. uint32_t src_built_in_decoration; const bool src_is_built_in = GetDecorationValue( - src_id_to_, src_id, SpvDecorationBuiltIn, &src_built_in_decoration); + src_id_to_, src_id, spv::Decoration::BuiltIn, &src_built_in_decoration); if (src_is_built_in && AreVariablesMatchable(src_id, dst_id, flexibility)) { return true; } - SpvStorageClass src_storage_class, dst_storage_class; + spv::StorageClass src_storage_class, dst_storage_class; GetVarTypeId(src_id_to_, src_id, &src_storage_class); GetVarTypeId(dst_id_to_, dst_id, &dst_storage_class); @@ -1348,13 +1351,13 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst, uint32_t src_binding = 0, dst_binding = 0; const bool src_has_set = GetDecorationValue( - src_id_to_, src_id, SpvDecorationDescriptorSet, &src_set); + src_id_to_, src_id, spv::Decoration::DescriptorSet, &src_set); const bool dst_has_set = GetDecorationValue( - dst_id_to_, dst_id, SpvDecorationDescriptorSet, &dst_set); - const bool src_has_binding = - GetDecorationValue(src_id_to_, src_id, SpvDecorationBinding, &src_set); - const bool dst_has_binding = - GetDecorationValue(dst_id_to_, dst_id, SpvDecorationBinding, &dst_set); + dst_id_to_, dst_id, spv::Decoration::DescriptorSet, &dst_set); + const bool src_has_binding = GetDecorationValue( + src_id_to_, src_id, spv::Decoration::Binding, &src_set); + const bool dst_has_binding = GetDecorationValue( + dst_id_to_, dst_id, spv::Decoration::Binding, &dst_set); if (src_has_set && dst_has_set && src_has_binding && dst_has_binding) { return src_set == dst_set && src_binding == dst_binding; @@ -1367,9 +1370,9 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst, uint32_t src_location, dst_location; const bool src_has_location = GetDecorationValue( - src_id_to_, src_id, SpvDecorationLocation, &src_location); + src_id_to_, src_id, spv::Decoration::Location, &src_location); const bool dst_has_location = GetDecorationValue( - dst_id_to_, dst_id, SpvDecorationLocation, &dst_location); + dst_id_to_, dst_id, spv::Decoration::Location, &dst_location); if (src_has_location && dst_has_location) { return src_location == dst_location; @@ -1384,25 +1387,25 @@ bool Differ::MatchPerVertexType(uint32_t src_type_id, uint32_t dst_type_id) { // For gl_PerVertex, find the type pointer of this type (array) and make sure // the storage classes of src and dst match; geometry and tessellation shaders // have two instances of gl_PerVertex. - SpvStorageClass src_storage_class = + spv::StorageClass src_storage_class = GetPerVertexStorageClass(src_, src_type_id); - SpvStorageClass dst_storage_class = + spv::StorageClass dst_storage_class = GetPerVertexStorageClass(dst_, dst_type_id); - assert(src_storage_class == SpvStorageClassInput || - src_storage_class == SpvStorageClassOutput); - assert(dst_storage_class == SpvStorageClassInput || - dst_storage_class == SpvStorageClassOutput); + assert(src_storage_class == spv::StorageClass::Input || + src_storage_class == spv::StorageClass::Output); + assert(dst_storage_class == spv::StorageClass::Input || + dst_storage_class == spv::StorageClass::Output); return src_storage_class == dst_storage_class; } bool Differ::MatchPerVertexVariable(const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - SpvStorageClass src_storage_class = - SpvStorageClass(src_inst->GetSingleWordInOperand(0)); - SpvStorageClass dst_storage_class = - SpvStorageClass(dst_inst->GetSingleWordInOperand(0)); + spv::StorageClass src_storage_class = + spv::StorageClass(src_inst->GetSingleWordInOperand(0)); + spv::StorageClass dst_storage_class = + spv::StorageClass(dst_inst->GetSingleWordInOperand(0)); return src_storage_class == dst_storage_class; } @@ -1479,7 +1482,7 @@ InstructionList Differ::GetFunctionHeader(const opt::Function& function) { InstructionList body; function.WhileEachInst( [&body](const opt::Instruction* inst) { - if (inst->opcode() == SpvOpLabel) { + if (inst->opcode() == spv::Op::OpLabel) { return false; } body.push_back(inst); @@ -1694,12 +1697,12 @@ void Differ::MatchVariablesUsedByMatchedInstructions( default: // TODO: match functions based on OpFunctionCall? break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: - case SpvOpLoad: - case SpvOpStore: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + case spv::Op::OpLoad: + case spv::Op::OpStore: const uint32_t src_pointer_id = src_inst->GetSingleWordInOperand(0); const uint32_t dst_pointer_id = dst_inst->GetSingleWordInOperand(0); if (IsVariable(src_id_to_, src_pointer_id) && @@ -1727,23 +1730,24 @@ const opt::Instruction* Differ::GetInst(const IdInstructions& id_to, uint32_t Differ::GetConstantUint(const IdInstructions& id_to, uint32_t constant_id) { const opt::Instruction* constant_inst = GetInst(id_to, constant_id); - assert(constant_inst->opcode() == SpvOpConstant); - assert(GetInst(id_to, constant_inst->type_id())->opcode() == SpvOpTypeInt); + assert(constant_inst->opcode() == spv::Op::OpConstant); + assert(GetInst(id_to, constant_inst->type_id())->opcode() == + spv::Op::OpTypeInt); return constant_inst->GetSingleWordInOperand(0); } -SpvExecutionModel Differ::GetExecutionModel(const opt::Module* module, - uint32_t entry_point_id) { +spv::ExecutionModel Differ::GetExecutionModel(const opt::Module* module, + uint32_t entry_point_id) { for (const opt::Instruction& inst : module->entry_points()) { - assert(inst.opcode() == SpvOpEntryPoint); + assert(inst.opcode() == spv::Op::OpEntryPoint); if (inst.GetSingleWordOperand(1) == entry_point_id) { - return SpvExecutionModel(inst.GetSingleWordOperand(0)); + return spv::ExecutionModel(inst.GetSingleWordOperand(0)); } } assert(false && "Unreachable"); - return SpvExecutionModel(0xFFF); + return spv::ExecutionModel(0xFFF); } bool Differ::HasName(const IdInstructions& id_to, uint32_t id) { @@ -1751,7 +1755,7 @@ bool Differ::HasName(const IdInstructions& id_to, uint32_t id) { assert(id < id_to.name_map_.size()); for (const opt::Instruction* inst : id_to.name_map_[id]) { - if (inst->opcode() == SpvOpName) { + if (inst->opcode() == spv::Op::OpName) { return true; } } @@ -1765,7 +1769,7 @@ std::string Differ::GetName(const IdInstructions& id_to, uint32_t id, assert(id < id_to.name_map_.size()); for (const opt::Instruction* inst : id_to.name_map_[id]) { - if (inst->opcode() == SpvOpName) { + if (inst->opcode() == spv::Op::OpName) { *has_name = true; return inst->GetOperand(1).AsString(); } @@ -1788,11 +1792,11 @@ std::string Differ::GetSanitizedName(const IdInstructions& id_to, uint32_t id) { } uint32_t Differ::GetVarTypeId(const IdInstructions& id_to, uint32_t var_id, - SpvStorageClass* storage_class) { + spv::StorageClass* storage_class) { const opt::Instruction* var_inst = GetInst(id_to, var_id); - assert(var_inst->opcode() == SpvOpVariable); + assert(var_inst->opcode() == spv::Op::OpVariable); - *storage_class = SpvStorageClass(var_inst->GetSingleWordInOperand(0)); + *storage_class = spv::StorageClass(var_inst->GetSingleWordInOperand(0)); // Get the type pointer from the variable. const uint32_t type_pointer_id = var_inst->type_id(); @@ -1803,15 +1807,15 @@ uint32_t Differ::GetVarTypeId(const IdInstructions& id_to, uint32_t var_id, } bool Differ::GetDecorationValue(const IdInstructions& id_to, uint32_t id, - SpvDecoration decoration, + spv::Decoration decoration, uint32_t* decoration_value) { assert(id != 0); assert(id < id_to.decoration_map_.size()); for (const opt::Instruction* inst : id_to.decoration_map_[id]) { - if (inst->opcode() == SpvOpDecorate && + if (inst->opcode() == spv::Op::OpDecorate && inst->GetSingleWordOperand(0) == id && - inst->GetSingleWordOperand(1) == decoration) { + spv::Decoration(inst->GetSingleWordOperand(1)) == decoration) { *decoration_value = inst->GetSingleWordOperand(2); return true; } @@ -1828,28 +1832,28 @@ const opt::Instruction* Differ::GetForwardPointerInst( } bool Differ::IsIntType(const IdInstructions& id_to, uint32_t type_id) { - return IsOp(id_to, type_id, SpvOpTypeInt); + return IsOp(id_to, type_id, spv::Op::OpTypeInt); } bool Differ::IsFloatType(const IdInstructions& id_to, uint32_t type_id) { - return IsOp(id_to, type_id, SpvOpTypeFloat); + return IsOp(id_to, type_id, spv::Op::OpTypeFloat); } bool Differ::IsConstantUint(const IdInstructions& id_to, uint32_t id) { const opt::Instruction* constant_inst = GetInst(id_to, id); - if (constant_inst->opcode() != SpvOpConstant) { + if (constant_inst->opcode() != spv::Op::OpConstant) { return false; } const opt::Instruction* type_inst = GetInst(id_to, constant_inst->type_id()); - return type_inst->opcode() == SpvOpTypeInt; + return type_inst->opcode() == spv::Op::OpTypeInt; } bool Differ::IsVariable(const IdInstructions& id_to, uint32_t pointer_id) { - return IsOp(id_to, pointer_id, SpvOpVariable); + return IsOp(id_to, pointer_id, spv::Op::OpVariable); } -bool Differ::IsOp(const IdInstructions& id_to, uint32_t id, SpvOp op) { +bool Differ::IsOp(const IdInstructions& id_to, uint32_t id, spv::Op op) { return GetInst(id_to, id)->opcode() == op; } @@ -1858,17 +1862,18 @@ bool Differ::IsPerVertexType(const IdInstructions& id_to, uint32_t type_id) { assert(type_id < id_to.decoration_map_.size()); for (const opt::Instruction* inst : id_to.decoration_map_[type_id]) { - if (inst->opcode() == SpvOpMemberDecorate && + if (inst->opcode() == spv::Op::OpMemberDecorate && inst->GetSingleWordOperand(0) == type_id && - inst->GetSingleWordOperand(2) == SpvDecorationBuiltIn) { - SpvBuiltIn built_in = SpvBuiltIn(inst->GetSingleWordOperand(3)); + spv::Decoration(inst->GetSingleWordOperand(2)) == + spv::Decoration::BuiltIn) { + spv::BuiltIn built_in = spv::BuiltIn(inst->GetSingleWordOperand(3)); // Only gl_PerVertex can have, and it can only have, the following // built-in decorations. - return built_in == SpvBuiltInPosition || - built_in == SpvBuiltInPointSize || - built_in == SpvBuiltInClipDistance || - built_in == SpvBuiltInCullDistance; + return built_in == spv::BuiltIn::Position || + built_in == spv::BuiltIn::PointSize || + built_in == spv::BuiltIn::ClipDistance || + built_in == spv::BuiltIn::CullDistance; } } @@ -1877,12 +1882,12 @@ bool Differ::IsPerVertexType(const IdInstructions& id_to, uint32_t type_id) { bool Differ::IsPerVertexVariable(const IdInstructions& id_to, uint32_t var_id) { // Get the type from the type pointer. - SpvStorageClass storage_class; + spv::StorageClass storage_class; uint32_t type_id = GetVarTypeId(id_to, var_id, &storage_class); const opt::Instruction* type_inst = GetInst(id_to, type_id); // If array, get the element type. - if (type_inst->opcode() == SpvOpTypeArray) { + if (type_inst->opcode() == spv::Op::OpTypeArray) { type_id = type_inst->GetSingleWordInOperand(0); } @@ -1890,21 +1895,21 @@ bool Differ::IsPerVertexVariable(const IdInstructions& id_to, uint32_t var_id) { return IsPerVertexType(id_to, type_id); } -SpvStorageClass Differ::GetPerVertexStorageClass(const opt::Module* module, - uint32_t type_id) { +spv::StorageClass Differ::GetPerVertexStorageClass(const opt::Module* module, + uint32_t type_id) { for (const opt::Instruction& inst : module->types_values()) { switch (inst.opcode()) { - case SpvOpTypeArray: + case spv::Op::OpTypeArray: // The gl_PerVertex instance could be an array, look for a variable of // the array type instead. if (inst.GetSingleWordInOperand(0) == type_id) { type_id = inst.result_id(); } break; - case SpvOpTypePointer: + case spv::Op::OpTypePointer: // Find the storage class of the pointer to this type. if (inst.GetSingleWordInOperand(1) == type_id) { - return SpvStorageClass(inst.GetSingleWordInOperand(0)); + return spv::StorageClass(inst.GetSingleWordInOperand(0)); } break; default: @@ -1915,7 +1920,7 @@ SpvStorageClass Differ::GetPerVertexStorageClass(const opt::Module* module, // gl_PerVertex is declared, but is unused. Return either of Input or Output // classes just so it matches one in the other module. This should be highly // unlikely, perhaps except for ancient GS-used-to-emulate-CS scenarios. - return SpvStorageClassOutput; + return spv::StorageClass::Output; } spv_ext_inst_type_t Differ::GetExtInstType(const IdInstructions& id_to, @@ -1941,9 +1946,9 @@ spv_number_kind_t Differ::GetNumberKind(const IdInstructions& id_to, case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: switch (inst.opcode()) { - case SpvOpSwitch: - case SpvOpConstant: - case SpvOpSpecConstant: + case spv::Op::OpSwitch: + case spv::Op::OpConstant: + case spv::Op::OpSpecConstant: // Same kind of number as the selector (OpSwitch) or the type // (Op*Constant). return GetTypeNumberKind(id_to, inst.GetSingleWordOperand(0), @@ -1969,12 +1974,12 @@ spv_number_kind_t Differ::GetTypeNumberKind(const IdInstructions& id_to, } switch (type_inst->opcode()) { - case SpvOpTypeInt: + case spv::Op::OpTypeInt: *number_bit_width = type_inst->GetSingleWordOperand(1); return type_inst->GetSingleWordOperand(2) == 0 ? SPV_NUMBER_UNSIGNED_INT : SPV_NUMBER_SIGNED_INT; break; - case SpvOpTypeFloat: + case spv::Op::OpTypeFloat: *number_bit_width = type_inst->GetSingleWordOperand(1); return SPV_NUMBER_FLOATING; default: @@ -2092,7 +2097,7 @@ void Differ::MatchTypeForwardPointers() { return inst.GetSingleWordOperand(0); }; auto accept_type_forward_pointer_ops = [](const opt::Instruction& inst) { - return inst.opcode() == SpvOpTypeForwardPointer; + return inst.opcode() == spv::Op::OpTypeForwardPointer; }; PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true, @@ -2116,17 +2121,17 @@ void Differ::MatchTypeForwardPointers() { // - If leftover is unique, match // Group forwarded pointers by storage class first and loop over them. - GroupIdsAndMatch( - potential_id_map.src_ids, potential_id_map.dst_ids, SpvStorageClassMax, - &Differ::GroupIdsHelperGetTypePointerStorageClass, + GroupIdsAndMatch( + potential_id_map.src_ids, potential_id_map.dst_ids, + spv::StorageClass::Max, &Differ::GroupIdsHelperGetTypePointerStorageClass, [this](const IdGroup& src_group_by_storage_class, const IdGroup& dst_group_by_storage_class) { // Group them further by the type they are pointing to and loop over // them. - GroupIdsAndMatch( - src_group_by_storage_class, dst_group_by_storage_class, SpvOpMax, - &Differ::GroupIdsHelperGetTypePointerTypeOp, + GroupIdsAndMatch( + src_group_by_storage_class, dst_group_by_storage_class, + spv::Op::Max, &Differ::GroupIdsHelperGetTypePointerTypeOp, [this](const IdGroup& src_group_by_type_op, const IdGroup& dst_group_by_type_op) { @@ -2182,8 +2187,8 @@ void Differ::MatchTypeIds() { MatchIds(potential_id_map, [this, flexibility]( const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - const SpvOp src_op = src_inst->opcode(); - const SpvOp dst_op = dst_inst->opcode(); + const spv::Op src_op = src_inst->opcode(); + const spv::Op dst_op = dst_inst->opcode(); // Don't match if the opcode is not the same. if (src_op != dst_op) { @@ -2191,26 +2196,26 @@ void Differ::MatchTypeIds() { } switch (src_op) { - case SpvOpTypeVoid: - case SpvOpTypeBool: - case SpvOpTypeSampler: + case spv::Op::OpTypeVoid: + case spv::Op::OpTypeBool: + case spv::Op::OpTypeSampler: // void, bool and sampler are unique, match them. return true; - case SpvOpTypeInt: - case SpvOpTypeFloat: - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeSampledImage: - case SpvOpTypeRuntimeArray: - case SpvOpTypePointer: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypePointer: // Match these instructions when all operands match. assert(src_inst->NumInOperandWords() == dst_inst->NumInOperandWords()); return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case SpvOpTypeFunction: - case SpvOpTypeImage: + case spv::Op::OpTypeFunction: + case spv::Op::OpTypeImage: // Match function types only if they have the same number of operands, // and they all match. // Match image types similarly, expecting the optional final parameter @@ -2221,7 +2226,7 @@ void Differ::MatchTypeIds() { return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case SpvOpTypeArray: + case spv::Op::OpTypeArray: // Match arrays only if the element type and length match. The length // is an id of a constant, so the actual constant it's defining is // compared instead. @@ -2238,7 +2243,7 @@ void Differ::MatchTypeIds() { // example if a spec contant is used). return DoOperandsMatch(src_inst, dst_inst, 1, 1); - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: return MatchOpTypeStruct(src_inst, dst_inst, flexibility); default: @@ -2270,8 +2275,8 @@ void Differ::MatchConstants() { MatchIds(potential_id_map, [this, flexibility]( const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - const SpvOp src_op = src_inst->opcode(); - const SpvOp dst_op = dst_inst->opcode(); + const spv::Op src_op = src_inst->opcode(); + const spv::Op dst_op = dst_inst->opcode(); // Don't match if the opcode is not the same. if (src_op != dst_op) { @@ -2279,14 +2284,14 @@ void Differ::MatchConstants() { } switch (src_op) { - case SpvOpConstantTrue: - case SpvOpConstantFalse: + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: // true and false are unique, match them. return true; - case SpvOpConstant: + case spv::Op::OpConstant: return MatchOpConstant(src_inst, dst_inst, flexibility); - case SpvOpConstantComposite: - case SpvOpSpecConstantComposite: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: // Composite constants must match in type and value. // // TODO: match OpConstantNull with OpConstantComposite with all zeros @@ -2299,7 +2304,7 @@ void Differ::MatchConstants() { dst_inst->GetOperand(0)) && DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case SpvOpConstantSampler: + case spv::Op::OpConstantSampler: // Match sampler constants exactly. // TODO: Allow flexibility in parameters to better diff shaders where // the sampler param has changed. @@ -2307,15 +2312,15 @@ void Differ::MatchConstants() { dst_inst->NumInOperandWords()); return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case SpvOpConstantNull: + case spv::Op::OpConstantNull: // Match null constants as long as the type matches. return DoesOperandMatch(src_inst->GetOperand(0), dst_inst->GetOperand(0)); - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: - case SpvOpSpecConstant: - case SpvOpSpecConstantOp: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantOp: // Match spec constants by name if available, then by the SpecId // decoration. return MatchOpSpecConstant(src_inst, dst_inst); @@ -2334,7 +2339,7 @@ void Differ::MatchVariableIds() { return inst.result_id(); }; auto accept_type_ops = [](const opt::Instruction& inst) { - return inst.opcode() == SpvOpVariable; + return inst.opcode() == spv::Op::OpVariable; }; PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true, @@ -2350,8 +2355,8 @@ void Differ::MatchVariableIds() { MatchIds(potential_id_map, [this, flexibility](const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - assert(src_inst->opcode() == SpvOpVariable); - assert(dst_inst->opcode() == SpvOpVariable); + assert(src_inst->opcode() == spv::Op::OpVariable); + assert(dst_inst->opcode() == spv::Op::OpVariable); return MatchOpVariable(src_inst, dst_inst, flexibility); }); @@ -2597,7 +2602,7 @@ void Differ::ToParsedInstruction( parsed_inst->num_words = static_cast(inst_binary.size()); parsed_inst->opcode = static_cast(inst.opcode()); parsed_inst->ext_inst_type = - inst.opcode() == SpvOpExtInst + inst.opcode() == spv::Op::OpExtInst ? GetExtInstType(id_to, original_inst.GetSingleWordInOperand(0)) : SPV_EXT_INST_TYPE_NONE; parsed_inst->type_id = diff --git a/3rdparty/spirv-tools/source/disassemble.cpp b/3rdparty/spirv-tools/source/disassemble.cpp index 1d61b9f9e..f862efd56 100644 --- a/3rdparty/spirv-tools/source/disassemble.cpp +++ b/3rdparty/spirv-tools/source/disassemble.cpp @@ -244,7 +244,7 @@ void InstructionDisassembler::EmitHeaderSchema(uint32_t schema) { void InstructionDisassembler::EmitInstruction( const spv_parsed_instruction_t& inst, size_t inst_byte_offset) { - auto opcode = static_cast(inst.opcode); + auto opcode = static_cast(inst.opcode); if (inst.result_id) { SetBlue(); @@ -268,7 +268,7 @@ void InstructionDisassembler::EmitInstruction( EmitOperand(inst, i); } - if (comment_ && opcode == SpvOpName) { + if (comment_ && opcode == spv::Op::OpName) { const spv_parsed_operand_t& operand = inst.operands[0]; const uint32_t word = inst.words[operand.offset]; stream_ << " ; id %" << word; @@ -290,8 +290,8 @@ void InstructionDisassembler::EmitInstruction( void InstructionDisassembler::EmitSectionComment( const spv_parsed_instruction_t& inst, bool& inserted_decoration_space, bool& inserted_debug_space, bool& inserted_type_space) { - auto opcode = static_cast(inst.opcode); - if (comment_ && opcode == SpvOpFunction) { + auto opcode = static_cast(inst.opcode); + if (comment_ && opcode == spv::Op::OpFunction) { stream_ << std::endl; stream_ << std::string(indent_, ' '); stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl; @@ -351,7 +351,7 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, } break; case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { spv_opcode_desc opcode_desc; - if (grammar_.lookupOpcode(SpvOp(word), &opcode_desc)) + if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc)) assert(false && "should have caught this earlier"); SetRed(); stream_ << opcode_desc->name; diff --git a/3rdparty/spirv-tools/source/enum_set.h b/3rdparty/spirv-tools/source/enum_set.h index d4d31e332..28ee5fee8 100644 --- a/3rdparty/spirv-tools/source/enum_set.h +++ b/3rdparty/spirv-tools/source/enum_set.h @@ -200,8 +200,8 @@ class EnumSet { std::unique_ptr overflow_ = {}; }; -// A set of SpvCapability, optimized for small capability values. -using CapabilitySet = EnumSet; +// A set of spv::Capability, optimized for small capability values. +using CapabilitySet = EnumSet; } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/enum_string_mapping.h b/3rdparty/spirv-tools/source/enum_string_mapping.h index af8f56b82..b13658406 100644 --- a/3rdparty/spirv-tools/source/enum_string_mapping.h +++ b/3rdparty/spirv-tools/source/enum_string_mapping.h @@ -29,7 +29,7 @@ bool GetExtensionFromString(const char* str, Extension* extension); const char* ExtensionToString(Extension extension); // Returns text string corresponding to |capability|. -const char* CapabilityToString(SpvCapability capability); +const char* CapabilityToString(spv::Capability capability); } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/extensions.cpp b/3rdparty/spirv-tools/source/extensions.cpp index 049a3ad10..ebf6bec06 100644 --- a/3rdparty/spirv-tools/source/extensions.cpp +++ b/3rdparty/spirv-tools/source/extensions.cpp @@ -24,7 +24,9 @@ namespace spvtools { std::string GetExtensionString(const spv_parsed_instruction_t* inst) { - if (inst->opcode != SpvOpExtension) return "ERROR_not_op_extension"; + if (inst->opcode != static_cast(spv::Op::OpExtension)) { + return "ERROR_not_op_extension"; + } assert(inst->num_operands == 1); diff --git a/3rdparty/spirv-tools/source/instruction.h b/3rdparty/spirv-tools/source/instruction.h index 9e7dccd03..2acbb5729 100644 --- a/3rdparty/spirv-tools/source/instruction.h +++ b/3rdparty/spirv-tools/source/instruction.h @@ -26,7 +26,7 @@ struct spv_instruction_t { // Normally, both opcode and extInstType contain valid data. // However, when the assembler parses ! as the first word in // an instruction and opcode and extInstType are invalid. - SpvOp opcode; + spv::Op opcode; spv_ext_inst_type_t extInstType; // The Id of the result type, if this instruction has one. Zero otherwise. diff --git a/3rdparty/spirv-tools/source/latest_version_spirv_header.h b/3rdparty/spirv-tools/source/latest_version_spirv_header.h index e4f28e43e..f6ab5c845 100644 --- a/3rdparty/spirv-tools/source/latest_version_spirv_header.h +++ b/3rdparty/spirv-tools/source/latest_version_spirv_header.h @@ -15,6 +15,6 @@ #ifndef SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ #define SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ -#include "spirv/unified1/spirv.h" +#include "spirv/unified1/spirv.hpp11" #endif // SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ diff --git a/3rdparty/spirv-tools/source/link/linker.cpp b/3rdparty/spirv-tools/source/link/linker.cpp index 3b388cc6e..e50391a1b 100644 --- a/3rdparty/spirv-tools/source/link/linker.cpp +++ b/3rdparty/spirv-tools/source/link/linker.cpp @@ -57,12 +57,12 @@ using opt::analysis::TypeManager; // Stores various information about an imported or exported symbol. struct LinkageSymbolInfo { - SpvId id; // ID of the symbol - SpvId type_id; // ID of the type of the symbol + spv::Id id; // ID of the symbol + spv::Id type_id; // ID of the type of the symbol std::string name; // unique name defining the symbol and used for matching // imports and exports together - std::vector parameter_ids; // ID of the parameters of the symbol, if - // it is a function + std::vector parameter_ids; // ID of the parameters of the symbol, if + // it is a function }; struct LinkageEntry { LinkageSymbolInfo imported_symbol; @@ -226,7 +226,7 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer, << " (input module " << (i + 1) << ")."; } - header->magic_number = SpvMagicNumber; + header->magic_number = spv::MagicNumber; header->version = linked_version; header->generator = SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_LINKER, 0); header->bound = max_id_bound; @@ -367,7 +367,7 @@ spv_result_t MergeModules(const MessageConsumer& consumer, std::vector processed_words = spvtools::utils::MakeVector(processed_string); linked_module->AddDebug3Inst(std::unique_ptr( - new Instruction(linked_context, SpvOpModuleProcessed, 0u, 0u, + new Instruction(linked_context, spv::Op::OpModuleProcessed, 0u, 0u, {{SPV_OPERAND_TYPE_LITERAL_STRING, processed_words}}))); } @@ -377,7 +377,7 @@ spv_result_t MergeModules(const MessageConsumer& consumer, std::unique_ptr(inst.Clone(linked_context))); // TODO(pierremoreau): Since the modules have not been validate, should we - // expect SpvStorageClassFunction variables outside + // expect spv::StorageClass::Function variables outside // functions? for (const auto& module : input_modules) { for (const auto& inst : module->types_values()) { @@ -414,16 +414,18 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer, // Figure out the imports and exports for (const auto& decoration : linked_context.annotations()) { - if (decoration.opcode() != SpvOpDecorate || - decoration.GetSingleWordInOperand(1u) != SpvDecorationLinkageAttributes) + if (decoration.opcode() != spv::Op::OpDecorate || + spv::Decoration(decoration.GetSingleWordInOperand(1u)) != + spv::Decoration::LinkageAttributes) continue; - const SpvId id = decoration.GetSingleWordInOperand(0u); + const spv::Id id = decoration.GetSingleWordInOperand(0u); // Ignore if the targeted symbol is a built-in bool is_built_in = false; for (const auto& id_decoration : decoration_manager.GetDecorationsFor(id, false)) { - if (id_decoration->GetSingleWordInOperand(1u) == SpvDecorationBuiltIn) { + if (spv::Decoration(id_decoration->GetSingleWordInOperand(1u)) == + spv::Decoration::BuiltIn) { is_built_in = true; break; } @@ -447,9 +449,9 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer, return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY) << "ID " << id << " is never defined:\n"; - if (def_inst->opcode() == SpvOpVariable) { + if (def_inst->opcode() == spv::Op::OpVariable) { symbol_info.type_id = def_inst->type_id(); - } else if (def_inst->opcode() == SpvOpFunction) { + } else if (def_inst->opcode() == spv::Op::OpFunction) { symbol_info.type_id = def_inst->GetSingleWordInOperand(1u); // range-based for loop calls begin()/end(), but never cbegin()/cend(), @@ -467,9 +469,9 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer, << " LinkageAttributes; " << id << " is neither of them.\n"; } - if (type == SpvLinkageTypeImport) + if (spv::LinkageType(type) == spv::LinkageType::Import) imports.push_back(symbol_info); - else if (type == SpvLinkageTypeExport) + else if (spv::LinkageType(type) == spv::LinkageType::Export) exports[symbol_info.name].push_back(symbol_info); } @@ -585,7 +587,7 @@ spv_result_t RemoveLinkageSpecificInstructions( // TODO(pierremoreau): This will not work if the decoration is applied // through a group, but the linker does not support that // either. - std::unordered_set imports; + std::unordered_set imports; if (options.GetAllowPartialLinkage()) { imports.reserve(linkings_to_do.size()); for (const auto& linking_entry : linkings_to_do) @@ -601,9 +603,11 @@ spv_result_t RemoveLinkageSpecificInstructions( // * if we do not allow partial linkage, remove all import annotations; // * otherwise, remove the annotation only if there was a corresponding // export. - if (inst->opcode() == SpvOpDecorate && - inst->GetSingleWordOperand(1u) == SpvDecorationLinkageAttributes && - inst->GetSingleWordOperand(3u) == SpvLinkageTypeImport && + if (inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(inst->GetSingleWordOperand(1u)) == + spv::Decoration::LinkageAttributes && + spv::LinkageType(inst->GetSingleWordOperand(3u)) == + spv::LinkageType::Import && (!options.GetAllowPartialLinkage() || imports.find(inst->GetSingleWordOperand(0u)) != imports.end())) { linked_context->KillInst(&*inst); @@ -616,9 +620,11 @@ spv_result_t RemoveLinkageSpecificInstructions( for (auto inst = next; inst != linked_context->annotation_end(); inst = next) { ++next; - if (inst->opcode() == SpvOpDecorate && - inst->GetSingleWordOperand(1u) == SpvDecorationLinkageAttributes && - inst->GetSingleWordOperand(3u) == SpvLinkageTypeExport) { + if (inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(inst->GetSingleWordOperand(1u)) == + spv::Decoration::LinkageAttributes && + spv::LinkageType(inst->GetSingleWordOperand(3u)) == + spv::LinkageType::Export) { linked_context->KillInst(&*inst); } } @@ -628,10 +634,11 @@ spv_result_t RemoveLinkageSpecificInstructions( // not allowed if (!options.GetCreateLibrary() && !options.GetAllowPartialLinkage()) { for (auto& inst : linked_context->capabilities()) - if (inst.GetSingleWordInOperand(0u) == SpvCapabilityLinkage) { + if (spv::Capability(inst.GetSingleWordInOperand(0u)) == + spv::Capability::Linkage) { linked_context->KillInst(&inst); // The RemoveDuplicatesPass did remove duplicated capabilities, so we - // now there aren’t more SpvCapabilityLinkage further down. + // now there aren’t more spv::Capability::Linkage further down. break; } } @@ -671,7 +678,7 @@ spv_result_t VerifyLimits(const MessageConsumer& consumer, size_t num_global_values = 0u; for (const auto& inst : linked_context.module()->types_values()) { - num_global_values += inst.opcode() == SpvOpVariable; + num_global_values += inst.opcode() == spv::Op::OpVariable; } if (num_global_values >= SPV_LIMIT_GLOBAL_VARIABLES_MAX) DiagnosticStream(position, consumer, "", SPV_WARNING) diff --git a/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp b/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp index b5a72b459..fe32e1ac2 100644 --- a/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp +++ b/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp @@ -19,7 +19,6 @@ #include "source/opt/dataflow.h" #include "source/opt/function.h" #include "source/opt/instruction.h" -#include "spirv/unified1/spirv.h" namespace spvtools { namespace lint { @@ -32,7 +31,7 @@ void DivergenceAnalysis::EnqueueSuccessors(opt::Instruction* inst) { uint32_t block_id; if (inst->IsBlockTerminator()) { block_id = context().get_instr_block(inst)->id(); - } else if (inst->opcode() == SpvOpLabel) { + } else if (inst->opcode() == spv::Op::OpLabel) { block_id = inst->result_id(); opt::BasicBlock* bb = context().cfg()->block(block_id); // Only enqueue phi instructions, as other uses don't affect divergence. @@ -54,7 +53,7 @@ void DivergenceAnalysis::EnqueueSuccessors(opt::Instruction* inst) { opt::DataFlowAnalysis::VisitResult DivergenceAnalysis::Visit( opt::Instruction* inst) { - if (inst->opcode() == SpvOpLabel) { + if (inst->opcode() == spv::Op::OpLabel) { return VisitBlock(inst->result_id()); } else { return VisitInstruction(inst); @@ -128,12 +127,12 @@ DivergenceAnalysis::ComputeInstructionDivergence(opt::Instruction* inst) { // Device/QueueFamily could satisfy fully uniform. uint32_t id = inst->result_id(); // Handle divergence roots. - if (inst->opcode() == SpvOpFunctionParameter) { + if (inst->opcode() == spv::Op::OpFunctionParameter) { divergence_source_[id] = 0; return divergence_[id] = DivergenceLevel::kDivergent; } else if (inst->IsLoad()) { spvtools::opt::Instruction* var = inst->GetBaseAddress(); - if (var->opcode() != SpvOpVariable) { + if (var->opcode() != spv::Op::OpVariable) { // Assume divergent. divergence_source_[id] = 0; return DivergenceLevel::kDivergent; @@ -166,29 +165,30 @@ DivergenceAnalysis::ComputeVariableDivergence(opt::Instruction* var) { uint32_t def_id = var->result_id(); DivergenceLevel ret; switch (type->storage_class()) { - case SpvStorageClassFunction: - case SpvStorageClassGeneric: - case SpvStorageClassAtomicCounter: - case SpvStorageClassStorageBuffer: - case SpvStorageClassPhysicalStorageBuffer: - case SpvStorageClassOutput: - case SpvStorageClassWorkgroup: - case SpvStorageClassImage: // Image atomics probably aren't uniform. - case SpvStorageClassPrivate: + case spv::StorageClass::Function: + case spv::StorageClass::Generic: + case spv::StorageClass::AtomicCounter: + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::PhysicalStorageBuffer: + case spv::StorageClass::Output: + case spv::StorageClass::Workgroup: + case spv::StorageClass::Image: // Image atomics probably aren't uniform. + case spv::StorageClass::Private: ret = DivergenceLevel::kDivergent; break; - case SpvStorageClassInput: + case spv::StorageClass::Input: ret = DivergenceLevel::kDivergent; // If this variable has a Flat decoration, it is partially uniform. // TODO(kuhar): Track access chain indices and also consider Flat members // of a structure. context().get_decoration_mgr()->WhileEachDecoration( - def_id, SpvDecorationFlat, [&ret](const opt::Instruction&) { + def_id, static_cast(spv::Decoration::Flat), + [&ret](const opt::Instruction&) { ret = DivergenceLevel::kPartiallyUniform; return false; }); break; - case SpvStorageClassUniformConstant: + case spv::StorageClass::UniformConstant: // May be a storage image which is also written to; mark those as // divergent. if (!var->IsVulkanStorageImage() || var->IsReadOnlyPointer()) { @@ -197,9 +197,10 @@ DivergenceAnalysis::ComputeVariableDivergence(opt::Instruction* var) { ret = DivergenceLevel::kDivergent; } break; - case SpvStorageClassUniform: - case SpvStorageClassPushConstant: - case SpvStorageClassCrossWorkgroup: // Not for shaders; default uniform. + case spv::StorageClass::Uniform: + case spv::StorageClass::PushConstant: + case spv::StorageClass::CrossWorkgroup: // Not for shaders; default + // uniform. default: ret = DivergenceLevel::kUniform; break; @@ -216,7 +217,7 @@ void DivergenceAnalysis::Setup(opt::Function* function) { function->entry().get(), [this](const opt::BasicBlock* bb) { uint32_t id = bb->id(); if (bb->terminator() == nullptr || - bb->terminator()->opcode() != SpvOpBranch) { + bb->terminator()->opcode() != spv::Op::OpBranch) { follow_unconditional_branches_[id] = id; } else { uint32_t target_id = bb->terminator()->GetSingleWordInOperand(0); diff --git a/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp b/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp index 512847b0c..82d5ac634 100644 --- a/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp +++ b/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp @@ -27,7 +27,6 @@ #include "source/opt/instruction.h" #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.h" -#include "spirv/unified1/spirv.h" namespace spvtools { namespace lint { @@ -43,7 +42,7 @@ std::string GetFriendlyName(opt::IRContext* context, uint32_t id) { ss << id; } else { opt::Instruction* inst_name = names.begin()->second; - if (inst_name->opcode() == SpvOpName) { + if (inst_name->opcode() == spv::Op::OpName) { ss << names.begin()->second->GetInOperand(0).AsString(); ss << "[" << id << "]"; } else { @@ -54,26 +53,26 @@ std::string GetFriendlyName(opt::IRContext* context, uint32_t id) { } bool InstructionHasDerivative(const opt::Instruction& inst) { - static const SpvOp derivative_opcodes[] = { + static const spv::Op derivative_opcodes[] = { // Implicit derivatives. - SpvOpImageSampleImplicitLod, - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleProjImplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSparseSampleImplicitLod, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleProjImplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSampleImplicitLod, + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleProjImplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleImplicitLod, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleProjImplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, // Explicit derivatives. - SpvOpDPdx, - SpvOpDPdy, - SpvOpFwidth, - SpvOpDPdxFine, - SpvOpDPdyFine, - SpvOpFwidthFine, - SpvOpDPdxCoarse, - SpvOpDPdyCoarse, - SpvOpFwidthCoarse, + spv::Op::OpDPdx, + spv::Op::OpDPdy, + spv::Op::OpFwidth, + spv::Op::OpDPdxFine, + spv::Op::OpDPdyFine, + spv::Op::OpFwidthFine, + spv::Op::OpDPdxCoarse, + spv::Op::OpDPdyCoarse, + spv::Op::OpFwidthCoarse, }; return std::find(std::begin(derivative_opcodes), std::end(derivative_opcodes), inst.opcode()) != std::end(derivative_opcodes); @@ -97,13 +96,14 @@ void PrintDivergenceFlow(opt::IRContext* context, DivergenceAnalysis div, opt::analysis::DefUseManager* def_use = context->get_def_use_mgr(); opt::CFG* cfg = context->cfg(); while (id != 0) { - bool is_block = def_use->GetDef(id)->opcode() == SpvOpLabel; + bool is_block = def_use->GetDef(id)->opcode() == spv::Op::OpLabel; if (is_block) { Warn(context, nullptr) << "block " << GetFriendlyName(context, id) << " is divergent"; uint32_t source = div.GetDivergenceSource(id); // Skip intermediate blocks. - while (source != 0 && def_use->GetDef(source)->opcode() == SpvOpLabel) { + while (source != 0 && + def_use->GetDef(source)->opcode() == spv::Op::OpLabel) { id = source; source = div.GetDivergenceSource(id); } @@ -122,7 +122,7 @@ void PrintDivergenceFlow(opt::IRContext* context, DivergenceAnalysis div, opt::Instruction* source_def = source == 0 ? nullptr : def_use->GetDef(source); // First print data -> data dependencies. - while (source != 0 && source_def->opcode() != SpvOpLabel) { + while (source != 0 && source_def->opcode() != spv::Op::OpLabel) { Warn(context, def_use->GetDef(id)) << "because " << GetFriendlyName(context, id) << " uses value " << GetFriendlyName(context, source) diff --git a/3rdparty/spirv-tools/source/lint/linter.cpp b/3rdparty/spirv-tools/source/lint/linter.cpp index e4ed04ea4..748067671 100644 --- a/3rdparty/spirv-tools/source/lint/linter.cpp +++ b/3rdparty/spirv-tools/source/lint/linter.cpp @@ -19,7 +19,6 @@ #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.h" #include "spirv-tools/libspirv.hpp" -#include "spirv/unified1/spirv.h" namespace spvtools { diff --git a/3rdparty/spirv-tools/source/name_mapper.cpp b/3rdparty/spirv-tools/source/name_mapper.cpp index 3b31d33a8..b2d0f4452 100644 --- a/3rdparty/spirv-tools/source/name_mapper.cpp +++ b/3rdparty/spirv-tools/source/name_mapper.cpp @@ -100,18 +100,18 @@ void FriendlyNameMapper::SaveName(uint32_t id, void FriendlyNameMapper::SaveBuiltInName(uint32_t target_id, uint32_t built_in) { #define GLCASE(name) \ - case SpvBuiltIn##name: \ + case spv::BuiltIn::name: \ SaveName(target_id, "gl_" #name); \ return; #define GLCASE2(name, suggested) \ - case SpvBuiltIn##name: \ + case spv::BuiltIn::name: \ SaveName(target_id, "gl_" #suggested); \ return; #define CASE(name) \ - case SpvBuiltIn##name: \ + case spv::BuiltIn::name: \ SaveName(target_id, #name); \ return; - switch (built_in) { + switch (spv::BuiltIn(built_in)) { GLCASE(Position) GLCASE(PointSize) GLCASE(ClipDistance) @@ -170,28 +170,28 @@ void FriendlyNameMapper::SaveBuiltInName(uint32_t target_id, spv_result_t FriendlyNameMapper::ParseInstruction( const spv_parsed_instruction_t& inst) { const auto result_id = inst.result_id; - switch (inst.opcode) { - case SpvOpName: + switch (spv::Op(inst.opcode)) { + case spv::Op::OpName: SaveName(inst.words[1], spvDecodeLiteralStringOperand(inst, 1)); break; - case SpvOpDecorate: + case spv::Op::OpDecorate: // Decorations come after OpName. So OpName will take precedence over // decorations. // // In theory, we should also handle OpGroupDecorate. But that's unlikely // to occur. - if (inst.words[2] == SpvDecorationBuiltIn) { + if (spv::Decoration(inst.words[2]) == spv::Decoration::BuiltIn) { assert(inst.num_words > 3); SaveBuiltInName(inst.words[1], inst.words[3]); } break; - case SpvOpTypeVoid: + case spv::Op::OpTypeVoid: SaveName(result_id, "void"); break; - case SpvOpTypeBool: + case spv::Op::OpTypeBool: SaveName(result_id, "bool"); break; - case SpvOpTypeInt: { + case spv::Op::OpTypeInt: { std::string signedness; std::string root; const auto bit_width = inst.words[2]; @@ -216,7 +216,7 @@ spv_result_t FriendlyNameMapper::ParseInstruction( if (0 == inst.words[3]) signedness = "u"; SaveName(result_id, signedness + root); } break; - case SpvOpTypeFloat: { + case spv::Op::OpTypeFloat: { const auto bit_width = inst.words[2]; switch (bit_width) { case 16: @@ -233,68 +233,68 @@ spv_result_t FriendlyNameMapper::ParseInstruction( break; } } break; - case SpvOpTypeVector: + case spv::Op::OpTypeVector: SaveName(result_id, std::string("v") + to_string(inst.words[3]) + NameForId(inst.words[2])); break; - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: SaveName(result_id, std::string("mat") + to_string(inst.words[3]) + NameForId(inst.words[2])); break; - case SpvOpTypeArray: + case spv::Op::OpTypeArray: SaveName(result_id, std::string("_arr_") + NameForId(inst.words[2]) + "_" + NameForId(inst.words[3])); break; - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeRuntimeArray: SaveName(result_id, std::string("_runtimearr_") + NameForId(inst.words[2])); break; - case SpvOpTypePointer: + case spv::Op::OpTypePointer: SaveName(result_id, std::string("_ptr_") + NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS, inst.words[2]) + "_" + NameForId(inst.words[3])); break; - case SpvOpTypePipe: + case spv::Op::OpTypePipe: SaveName(result_id, std::string("Pipe") + NameForEnumOperand(SPV_OPERAND_TYPE_ACCESS_QUALIFIER, inst.words[2])); break; - case SpvOpTypeEvent: + case spv::Op::OpTypeEvent: SaveName(result_id, "Event"); break; - case SpvOpTypeDeviceEvent: + case spv::Op::OpTypeDeviceEvent: SaveName(result_id, "DeviceEvent"); break; - case SpvOpTypeReserveId: + case spv::Op::OpTypeReserveId: SaveName(result_id, "ReserveId"); break; - case SpvOpTypeQueue: + case spv::Op::OpTypeQueue: SaveName(result_id, "Queue"); break; - case SpvOpTypeOpaque: + case spv::Op::OpTypeOpaque: SaveName(result_id, std::string("Opaque_") + Sanitize(spvDecodeLiteralStringOperand(inst, 1))); break; - case SpvOpTypePipeStorage: + case spv::Op::OpTypePipeStorage: SaveName(result_id, "PipeStorage"); break; - case SpvOpTypeNamedBarrier: + case spv::Op::OpTypeNamedBarrier: SaveName(result_id, "NamedBarrier"); break; - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: // Structs are mapped rather simplisitically. Just indicate that they // are a struct and then give the raw Id number. SaveName(result_id, std::string("_struct_") + to_string(result_id)); break; - case SpvOpConstantTrue: + case spv::Op::OpConstantTrue: SaveName(result_id, "true"); break; - case SpvOpConstantFalse: + case spv::Op::OpConstantFalse: SaveName(result_id, "false"); break; - case SpvOpConstant: { + case spv::Op::OpConstant: { std::ostringstream value; EmitNumericLiteral(&value, inst, inst.operands[2]); auto value_str = value.str(); diff --git a/3rdparty/spirv-tools/source/opcode.cpp b/3rdparty/spirv-tools/source/opcode.cpp index 3f927290e..b1785cccc 100644 --- a/3rdparty/spirv-tools/source/opcode.cpp +++ b/3rdparty/spirv-tools/source/opcode.cpp @@ -64,7 +64,7 @@ const char* spvGeneratorStr(uint32_t generator) { return "Unknown"; } -uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) { +uint32_t spvOpcodeMake(uint16_t wordCount, spv::Op opcode) { return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16); } @@ -125,7 +125,7 @@ spv_result_t spvOpcodeTableNameLookup(spv_target_env env, spv_result_t spvOpcodeTableValueLookup(spv_target_env env, const spv_opcode_table table, - const SpvOp opcode, + const spv::Op opcode, spv_opcode_desc* pEntry) { if (!table) return SPV_ERROR_INVALID_TABLE; if (!pEntry) return SPV_ERROR_INVALID_POINTER; @@ -166,7 +166,7 @@ spv_result_t spvOpcodeTableValueLookup(spv_target_env env, return SPV_ERROR_INVALID_LOOKUP; } -void spvInstructionCopy(const uint32_t* words, const SpvOp opcode, +void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, const uint16_t wordCount, const spv_endianness_t endian, spv_instruction_t* pInst) { pInst->opcode = opcode; @@ -177,7 +177,7 @@ void spvInstructionCopy(const uint32_t* words, const SpvOp opcode, uint16_t thisWordCount; uint16_t thisOpcode; spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode); - assert(opcode == static_cast(thisOpcode) && + assert(opcode == static_cast(thisOpcode) && wordCount == thisWordCount && "Endianness failed!"); } } @@ -186,7 +186,7 @@ void spvInstructionCopy(const uint32_t* words, const SpvOp opcode, const char* spvOpcodeString(const uint32_t opcode) { const auto beg = kOpcodeTableEntries; const auto end = kOpcodeTableEntries + ARRAY_SIZE(kOpcodeTableEntries); - spv_opcode_desc_t needle = {"", static_cast(opcode), + spv_opcode_desc_t needle = {"", static_cast(opcode), 0, nullptr, 0, {}, false, false, @@ -196,7 +196,7 @@ const char* spvOpcodeString(const uint32_t opcode) { return lhs.opcode < rhs.opcode; }; auto it = std::lower_bound(beg, end, needle, comp); - if (it != end && it->opcode == opcode) { + if (it != end && it->opcode == spv::Op(opcode)) { return it->name; } @@ -204,140 +204,145 @@ const char* spvOpcodeString(const uint32_t opcode) { return "unknown"; } -int32_t spvOpcodeIsScalarType(const SpvOp opcode) { +const char* spvOpcodeString(const spv::Op opcode) { + return spvOpcodeString(static_cast(opcode)); +} + +int32_t spvOpcodeIsScalarType(const spv::Op opcode) { switch (opcode) { - case SpvOpTypeInt: - case SpvOpTypeFloat: - case SpvOpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeBool: return true; default: return false; } } -int32_t spvOpcodeIsSpecConstant(const SpvOp opcode) { +int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) { switch (opcode) { - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: - case SpvOpSpecConstant: - case SpvOpSpecConstantComposite: - case SpvOpSpecConstantOp: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantOp: return true; default: return false; } } -int32_t spvOpcodeIsConstant(const SpvOp opcode) { +int32_t spvOpcodeIsConstant(const spv::Op opcode) { switch (opcode) { - case SpvOpConstantTrue: - case SpvOpConstantFalse: - case SpvOpConstant: - case SpvOpConstantComposite: - case SpvOpConstantSampler: - case SpvOpConstantNull: - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: - case SpvOpSpecConstant: - case SpvOpSpecConstantComposite: - case SpvOpSpecConstantOp: + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpConstant: + case spv::Op::OpConstantComposite: + case spv::Op::OpConstantSampler: + case spv::Op::OpConstantNull: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantOp: return true; default: return false; } } -bool spvOpcodeIsConstantOrUndef(const SpvOp opcode) { - return opcode == SpvOpUndef || spvOpcodeIsConstant(opcode); +bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) { + return opcode == spv::Op::OpUndef || spvOpcodeIsConstant(opcode); } -bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode) { +bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode) { switch (opcode) { - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: - case SpvOpSpecConstant: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: return true; default: return false; } } -int32_t spvOpcodeIsComposite(const SpvOp opcode) { +int32_t spvOpcodeIsComposite(const spv::Op opcode) { switch (opcode) { - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeArray: - case SpvOpTypeStruct: - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeStruct: + case spv::Op::OpTypeCooperativeMatrixNV: return true; default: return false; } } -bool spvOpcodeReturnsLogicalVariablePointer(const SpvOp opcode) { +bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) { switch (opcode) { - case SpvOpVariable: - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpFunctionParameter: - case SpvOpImageTexelPointer: - case SpvOpCopyObject: - case SpvOpSelect: - case SpvOpPhi: - case SpvOpFunctionCall: - case SpvOpPtrAccessChain: - case SpvOpLoad: - case SpvOpConstantNull: + case spv::Op::OpVariable: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpFunctionParameter: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpCopyObject: + case spv::Op::OpSelect: + case spv::Op::OpPhi: + case spv::Op::OpFunctionCall: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpLoad: + case spv::Op::OpConstantNull: return true; default: return false; } } -int32_t spvOpcodeReturnsLogicalPointer(const SpvOp opcode) { +int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) { switch (opcode) { - case SpvOpVariable: - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpFunctionParameter: - case SpvOpImageTexelPointer: - case SpvOpCopyObject: + case spv::Op::OpVariable: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpFunctionParameter: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpCopyObject: return true; default: return false; } } -int32_t spvOpcodeGeneratesType(SpvOp op) { +int32_t spvOpcodeGeneratesType(spv::Op op) { switch (op) { - case SpvOpTypeVoid: - case SpvOpTypeBool: - case SpvOpTypeInt: - case SpvOpTypeFloat: - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeImage: - case SpvOpTypeSampler: - case SpvOpTypeSampledImage: - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeStruct: - case SpvOpTypeOpaque: - case SpvOpTypePointer: - case SpvOpTypeFunction: - case SpvOpTypeEvent: - case SpvOpTypeDeviceEvent: - case SpvOpTypeReserveId: - case SpvOpTypeQueue: - case SpvOpTypePipe: - case SpvOpTypePipeStorage: - case SpvOpTypeNamedBarrier: - case SpvOpTypeAccelerationStructureNV: - case SpvOpTypeCooperativeMatrixNV: - // case SpvOpTypeAccelerationStructureKHR: covered by - // SpvOpTypeAccelerationStructureNV - case SpvOpTypeRayQueryKHR: + case spv::Op::OpTypeVoid: + case spv::Op::OpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeStruct: + case spv::Op::OpTypeOpaque: + case spv::Op::OpTypePointer: + case spv::Op::OpTypeFunction: + case spv::Op::OpTypeEvent: + case spv::Op::OpTypeDeviceEvent: + case spv::Op::OpTypeReserveId: + case spv::Op::OpTypeQueue: + case spv::Op::OpTypePipe: + case spv::Op::OpTypePipeStorage: + case spv::Op::OpTypeNamedBarrier: + case spv::Op::OpTypeAccelerationStructureNV: + case spv::Op::OpTypeCooperativeMatrixNV: + // case spv::Op::OpTypeAccelerationStructureKHR: covered by + // spv::Op::OpTypeAccelerationStructureNV + case spv::Op::OpTypeRayQueryKHR: + case spv::Op::OpTypeHitObjectNV: return true; default: // In particular, OpTypeForwardPointer does not generate a type, @@ -348,15 +353,15 @@ int32_t spvOpcodeGeneratesType(SpvOp op) { return 0; } -bool spvOpcodeIsDecoration(const SpvOp opcode) { +bool spvOpcodeIsDecoration(const spv::Op opcode) { switch (opcode) { - case SpvOpDecorate: - case SpvOpDecorateId: - case SpvOpMemberDecorate: - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: - case SpvOpDecorateStringGOOGLE: - case SpvOpMemberDecorateStringGOOGLE: + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpMemberDecorate: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: return true; default: break; @@ -364,402 +369,403 @@ bool spvOpcodeIsDecoration(const SpvOp opcode) { return false; } -bool spvOpcodeIsLoad(const SpvOp opcode) { +bool spvOpcodeIsLoad(const spv::Op opcode) { switch (opcode) { - case SpvOpLoad: - case SpvOpImageSampleExplicitLod: - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleDrefExplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageFetch: - case SpvOpImageGather: - case SpvOpImageDrefGather: - case SpvOpImageRead: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleExplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseFetch: - case SpvOpImageSparseGather: - case SpvOpImageSparseDrefGather: - case SpvOpImageSparseRead: + case spv::Op::OpLoad: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageFetch: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageSparseRead: return true; default: return false; } } -bool spvOpcodeIsBranch(SpvOp opcode) { +bool spvOpcodeIsBranch(spv::Op opcode) { switch (opcode) { - case SpvOpBranch: - case SpvOpBranchConditional: - case SpvOpSwitch: + case spv::Op::OpBranch: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: return true; default: return false; } } -bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode) { +bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) { switch (opcode) { - case SpvOpAtomicLoad: - case SpvOpAtomicExchange: - case SpvOpAtomicCompareExchange: - case SpvOpAtomicCompareExchangeWeak: - case SpvOpAtomicIIncrement: - case SpvOpAtomicIDecrement: - case SpvOpAtomicIAdd: - case SpvOpAtomicFAddEXT: - case SpvOpAtomicISub: - case SpvOpAtomicSMin: - case SpvOpAtomicUMin: - case SpvOpAtomicFMinEXT: - case SpvOpAtomicSMax: - case SpvOpAtomicUMax: - case SpvOpAtomicFMaxEXT: - case SpvOpAtomicAnd: - case SpvOpAtomicOr: - case SpvOpAtomicXor: - case SpvOpAtomicFlagTestAndSet: + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicFMaxEXT: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: return true; default: return false; } } -bool spvOpcodeIsAtomicOp(const SpvOp opcode) { - return (spvOpcodeIsAtomicWithLoad(opcode) || opcode == SpvOpAtomicStore || - opcode == SpvOpAtomicFlagClear); +bool spvOpcodeIsAtomicOp(const spv::Op opcode) { + return (spvOpcodeIsAtomicWithLoad(opcode) || + opcode == spv::Op::OpAtomicStore || + opcode == spv::Op::OpAtomicFlagClear); } -bool spvOpcodeIsReturn(SpvOp opcode) { +bool spvOpcodeIsReturn(spv::Op opcode) { switch (opcode) { - case SpvOpReturn: - case SpvOpReturnValue: + case spv::Op::OpReturn: + case spv::Op::OpReturnValue: return true; default: return false; } } -bool spvOpcodeIsAbort(SpvOp opcode) { +bool spvOpcodeIsAbort(spv::Op opcode) { switch (opcode) { - case SpvOpKill: - case SpvOpUnreachable: - case SpvOpTerminateInvocation: - case SpvOpTerminateRayKHR: - case SpvOpIgnoreIntersectionKHR: - case SpvOpEmitMeshTasksEXT: + case spv::Op::OpKill: + case spv::Op::OpUnreachable: + case spv::Op::OpTerminateInvocation: + case spv::Op::OpTerminateRayKHR: + case spv::Op::OpIgnoreIntersectionKHR: + case spv::Op::OpEmitMeshTasksEXT: return true; default: return false; } } -bool spvOpcodeIsReturnOrAbort(SpvOp opcode) { +bool spvOpcodeIsReturnOrAbort(spv::Op opcode) { return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode); } -bool spvOpcodeIsBlockTerminator(SpvOp opcode) { +bool spvOpcodeIsBlockTerminator(spv::Op opcode) { return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode); } -bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) { +bool spvOpcodeIsBaseOpaqueType(spv::Op opcode) { switch (opcode) { - case SpvOpTypeImage: - case SpvOpTypeSampler: - case SpvOpTypeSampledImage: - case SpvOpTypeOpaque: - case SpvOpTypeEvent: - case SpvOpTypeDeviceEvent: - case SpvOpTypeReserveId: - case SpvOpTypeQueue: - case SpvOpTypePipe: - case SpvOpTypeForwardPointer: - case SpvOpTypePipeStorage: - case SpvOpTypeNamedBarrier: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeOpaque: + case spv::Op::OpTypeEvent: + case spv::Op::OpTypeDeviceEvent: + case spv::Op::OpTypeReserveId: + case spv::Op::OpTypeQueue: + case spv::Op::OpTypePipe: + case spv::Op::OpTypeForwardPointer: + case spv::Op::OpTypePipeStorage: + case spv::Op::OpTypeNamedBarrier: return true; default: return false; } } -bool spvOpcodeIsNonUniformGroupOperation(SpvOp opcode) { +bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) { switch (opcode) { - case SpvOpGroupNonUniformElect: - case SpvOpGroupNonUniformAll: - case SpvOpGroupNonUniformAny: - case SpvOpGroupNonUniformAllEqual: - case SpvOpGroupNonUniformBroadcast: - case SpvOpGroupNonUniformBroadcastFirst: - case SpvOpGroupNonUniformBallot: - case SpvOpGroupNonUniformInverseBallot: - case SpvOpGroupNonUniformBallotBitExtract: - case SpvOpGroupNonUniformBallotBitCount: - case SpvOpGroupNonUniformBallotFindLSB: - case SpvOpGroupNonUniformBallotFindMSB: - case SpvOpGroupNonUniformShuffle: - case SpvOpGroupNonUniformShuffleXor: - case SpvOpGroupNonUniformShuffleUp: - case SpvOpGroupNonUniformShuffleDown: - case SpvOpGroupNonUniformIAdd: - case SpvOpGroupNonUniformFAdd: - case SpvOpGroupNonUniformIMul: - case SpvOpGroupNonUniformFMul: - case SpvOpGroupNonUniformSMin: - case SpvOpGroupNonUniformUMin: - case SpvOpGroupNonUniformFMin: - case SpvOpGroupNonUniformSMax: - case SpvOpGroupNonUniformUMax: - case SpvOpGroupNonUniformFMax: - case SpvOpGroupNonUniformBitwiseAnd: - case SpvOpGroupNonUniformBitwiseOr: - case SpvOpGroupNonUniformBitwiseXor: - case SpvOpGroupNonUniformLogicalAnd: - case SpvOpGroupNonUniformLogicalOr: - case SpvOpGroupNonUniformLogicalXor: - case SpvOpGroupNonUniformQuadBroadcast: - case SpvOpGroupNonUniformQuadSwap: - case SpvOpGroupNonUniformRotateKHR: + case spv::Op::OpGroupNonUniformElect: + case spv::Op::OpGroupNonUniformAll: + case spv::Op::OpGroupNonUniformAny: + case spv::Op::OpGroupNonUniformAllEqual: + case spv::Op::OpGroupNonUniformBroadcast: + case spv::Op::OpGroupNonUniformBroadcastFirst: + case spv::Op::OpGroupNonUniformBallot: + case spv::Op::OpGroupNonUniformInverseBallot: + case spv::Op::OpGroupNonUniformBallotBitExtract: + case spv::Op::OpGroupNonUniformBallotBitCount: + case spv::Op::OpGroupNonUniformBallotFindLSB: + case spv::Op::OpGroupNonUniformBallotFindMSB: + case spv::Op::OpGroupNonUniformShuffle: + case spv::Op::OpGroupNonUniformShuffleXor: + case spv::Op::OpGroupNonUniformShuffleUp: + case spv::Op::OpGroupNonUniformShuffleDown: + case spv::Op::OpGroupNonUniformIAdd: + case spv::Op::OpGroupNonUniformFAdd: + case spv::Op::OpGroupNonUniformIMul: + case spv::Op::OpGroupNonUniformFMul: + case spv::Op::OpGroupNonUniformSMin: + case spv::Op::OpGroupNonUniformUMin: + case spv::Op::OpGroupNonUniformFMin: + case spv::Op::OpGroupNonUniformSMax: + case spv::Op::OpGroupNonUniformUMax: + case spv::Op::OpGroupNonUniformFMax: + case spv::Op::OpGroupNonUniformBitwiseAnd: + case spv::Op::OpGroupNonUniformBitwiseOr: + case spv::Op::OpGroupNonUniformBitwiseXor: + case spv::Op::OpGroupNonUniformLogicalAnd: + case spv::Op::OpGroupNonUniformLogicalOr: + case spv::Op::OpGroupNonUniformLogicalXor: + case spv::Op::OpGroupNonUniformQuadBroadcast: + case spv::Op::OpGroupNonUniformQuadSwap: + case spv::Op::OpGroupNonUniformRotateKHR: return true; default: return false; } } -bool spvOpcodeIsScalarizable(SpvOp opcode) { +bool spvOpcodeIsScalarizable(spv::Op opcode) { switch (opcode) { - case SpvOpPhi: - case SpvOpCopyObject: - case SpvOpConvertFToU: - case SpvOpConvertFToS: - case SpvOpConvertSToF: - case SpvOpConvertUToF: - case SpvOpUConvert: - case SpvOpSConvert: - case SpvOpFConvert: - case SpvOpQuantizeToF16: - case SpvOpVectorInsertDynamic: - case SpvOpSNegate: - case SpvOpFNegate: - case SpvOpIAdd: - case SpvOpFAdd: - case SpvOpISub: - case SpvOpFSub: - case SpvOpIMul: - case SpvOpFMul: - case SpvOpUDiv: - case SpvOpSDiv: - case SpvOpFDiv: - case SpvOpUMod: - case SpvOpSRem: - case SpvOpSMod: - case SpvOpFRem: - case SpvOpFMod: - case SpvOpVectorTimesScalar: - case SpvOpIAddCarry: - case SpvOpISubBorrow: - case SpvOpUMulExtended: - case SpvOpSMulExtended: - case SpvOpShiftRightLogical: - case SpvOpShiftRightArithmetic: - case SpvOpShiftLeftLogical: - case SpvOpBitwiseOr: - case SpvOpBitwiseAnd: - case SpvOpNot: - case SpvOpBitFieldInsert: - case SpvOpBitFieldSExtract: - case SpvOpBitFieldUExtract: - case SpvOpBitReverse: - case SpvOpBitCount: - case SpvOpIsNan: - case SpvOpIsInf: - case SpvOpIsFinite: - case SpvOpIsNormal: - case SpvOpSignBitSet: - case SpvOpLessOrGreater: - case SpvOpOrdered: - case SpvOpUnordered: - case SpvOpLogicalEqual: - case SpvOpLogicalNotEqual: - case SpvOpLogicalOr: - case SpvOpLogicalAnd: - case SpvOpLogicalNot: - case SpvOpSelect: - case SpvOpIEqual: - case SpvOpINotEqual: - case SpvOpUGreaterThan: - case SpvOpSGreaterThan: - case SpvOpUGreaterThanEqual: - case SpvOpSGreaterThanEqual: - case SpvOpULessThan: - case SpvOpSLessThan: - case SpvOpULessThanEqual: - case SpvOpSLessThanEqual: - case SpvOpFOrdEqual: - case SpvOpFUnordEqual: - case SpvOpFOrdNotEqual: - case SpvOpFUnordNotEqual: - case SpvOpFOrdLessThan: - case SpvOpFUnordLessThan: - case SpvOpFOrdGreaterThan: - case SpvOpFUnordGreaterThan: - case SpvOpFOrdLessThanEqual: - case SpvOpFUnordLessThanEqual: - case SpvOpFOrdGreaterThanEqual: - case SpvOpFUnordGreaterThanEqual: + case spv::Op::OpPhi: + case spv::Op::OpCopyObject: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: + case spv::Op::OpUConvert: + case spv::Op::OpSConvert: + case spv::Op::OpFConvert: + case spv::Op::OpQuantizeToF16: + case spv::Op::OpVectorInsertDynamic: + case spv::Op::OpSNegate: + case spv::Op::OpFNegate: + case spv::Op::OpIAdd: + case spv::Op::OpFAdd: + case spv::Op::OpISub: + case spv::Op::OpFSub: + case spv::Op::OpIMul: + case spv::Op::OpFMul: + case spv::Op::OpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpFDiv: + case spv::Op::OpUMod: + case spv::Op::OpSRem: + case spv::Op::OpSMod: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpIAddCarry: + case spv::Op::OpISubBorrow: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: + case spv::Op::OpBitFieldInsert: + case spv::Op::OpBitFieldSExtract: + case spv::Op::OpBitFieldUExtract: + case spv::Op::OpBitReverse: + case spv::Op::OpBitCount: + case spv::Op::OpIsNan: + case spv::Op::OpIsInf: + case spv::Op::OpIsFinite: + case spv::Op::OpIsNormal: + case spv::Op::OpSignBitSet: + case spv::Op::OpLessOrGreater: + case spv::Op::OpOrdered: + case spv::Op::OpUnordered: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: + case spv::Op::OpLogicalNot: + case spv::Op::OpSelect: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: return true; default: return false; } } -bool spvOpcodeIsDebug(SpvOp opcode) { +bool spvOpcodeIsDebug(spv::Op opcode) { switch (opcode) { - case SpvOpName: - case SpvOpMemberName: - case SpvOpSource: - case SpvOpSourceContinued: - case SpvOpSourceExtension: - case SpvOpString: - case SpvOpLine: - case SpvOpNoLine: - case SpvOpModuleProcessed: + case spv::Op::OpName: + case spv::Op::OpMemberName: + case spv::Op::OpSource: + case spv::Op::OpSourceContinued: + case spv::Op::OpSourceExtension: + case spv::Op::OpString: + case spv::Op::OpLine: + case spv::Op::OpNoLine: + case spv::Op::OpModuleProcessed: return true; default: return false; } } -bool spvOpcodeIsCommutativeBinaryOperator(SpvOp opcode) { +bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) { switch (opcode) { - case SpvOpPtrEqual: - case SpvOpPtrNotEqual: - case SpvOpIAdd: - case SpvOpFAdd: - case SpvOpIMul: - case SpvOpFMul: - case SpvOpDot: - case SpvOpIAddCarry: - case SpvOpUMulExtended: - case SpvOpSMulExtended: - case SpvOpBitwiseOr: - case SpvOpBitwiseXor: - case SpvOpBitwiseAnd: - case SpvOpOrdered: - case SpvOpUnordered: - case SpvOpLogicalEqual: - case SpvOpLogicalNotEqual: - case SpvOpLogicalOr: - case SpvOpLogicalAnd: - case SpvOpIEqual: - case SpvOpINotEqual: - case SpvOpFOrdEqual: - case SpvOpFUnordEqual: - case SpvOpFOrdNotEqual: - case SpvOpFUnordNotEqual: + case spv::Op::OpPtrEqual: + case spv::Op::OpPtrNotEqual: + case spv::Op::OpIAdd: + case spv::Op::OpFAdd: + case spv::Op::OpIMul: + case spv::Op::OpFMul: + case spv::Op::OpDot: + case spv::Op::OpIAddCarry: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpOrdered: + case spv::Op::OpUnordered: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: return true; default: return false; } } -bool spvOpcodeIsLinearAlgebra(SpvOp opcode) { +bool spvOpcodeIsLinearAlgebra(spv::Op opcode) { switch (opcode) { - case SpvOpTranspose: - case SpvOpVectorTimesScalar: - case SpvOpMatrixTimesScalar: - case SpvOpVectorTimesMatrix: - case SpvOpMatrixTimesVector: - case SpvOpMatrixTimesMatrix: - case SpvOpOuterProduct: - case SpvOpDot: + case spv::Op::OpTranspose: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpMatrixTimesScalar: + case spv::Op::OpVectorTimesMatrix: + case spv::Op::OpMatrixTimesVector: + case spv::Op::OpMatrixTimesMatrix: + case spv::Op::OpOuterProduct: + case spv::Op::OpDot: return true; default: return false; } } -bool spvOpcodeIsImageSample(const SpvOp opcode) { +bool spvOpcodeIsImageSample(const spv::Op opcode) { switch (opcode) { - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleExplicitLod: - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleDrefExplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleExplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: return true; default: return false; } } -std::vector spvOpcodeMemorySemanticsOperandIndices(SpvOp opcode) { +std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) { switch (opcode) { - case SpvOpMemoryBarrier: + case spv::Op::OpMemoryBarrier: return {1}; - case SpvOpAtomicStore: - case SpvOpControlBarrier: - case SpvOpAtomicFlagClear: - case SpvOpMemoryNamedBarrier: + case spv::Op::OpAtomicStore: + case spv::Op::OpControlBarrier: + case spv::Op::OpAtomicFlagClear: + case spv::Op::OpMemoryNamedBarrier: return {2}; - case SpvOpAtomicLoad: - case SpvOpAtomicExchange: - case SpvOpAtomicIIncrement: - case SpvOpAtomicIDecrement: - case SpvOpAtomicIAdd: - case SpvOpAtomicFAddEXT: - case SpvOpAtomicISub: - case SpvOpAtomicSMin: - case SpvOpAtomicUMin: - case SpvOpAtomicSMax: - case SpvOpAtomicUMax: - case SpvOpAtomicAnd: - case SpvOpAtomicOr: - case SpvOpAtomicXor: - case SpvOpAtomicFlagTestAndSet: + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: return {4}; - case SpvOpAtomicCompareExchange: - case SpvOpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: return {4, 5}; default: return {}; } } -bool spvOpcodeIsAccessChain(SpvOp opcode) { +bool spvOpcodeIsAccessChain(spv::Op opcode) { switch (opcode) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: return true; default: return false; } } -bool spvOpcodeIsBit(SpvOp opcode) { +bool spvOpcodeIsBit(spv::Op opcode) { switch (opcode) { - case SpvOpShiftRightLogical: - case SpvOpShiftRightArithmetic: - case SpvOpShiftLeftLogical: - case SpvOpBitwiseOr: - case SpvOpBitwiseXor: - case SpvOpBitwiseAnd: - case SpvOpNot: - case SpvOpBitReverse: - case SpvOpBitCount: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: + case spv::Op::OpBitReverse: + case spv::Op::OpBitCount: return true; default: return false; diff --git a/3rdparty/spirv-tools/source/opcode.h b/3rdparty/spirv-tools/source/opcode.h index 77a0bed25..217aeb2b6 100644 --- a/3rdparty/spirv-tools/source/opcode.h +++ b/3rdparty/spirv-tools/source/opcode.h @@ -29,7 +29,7 @@ const char* spvGeneratorStr(uint32_t generator); // Combines word_count and opcode enumerant in single word. -uint32_t spvOpcodeMake(uint16_t word_count, SpvOp opcode); +uint32_t spvOpcodeMake(uint16_t word_count, spv::Op opcode); // Splits word into into two constituent parts: word_count and opcode. void spvOpcodeSplit(const uint32_t word, uint16_t* word_count, @@ -45,115 +45,118 @@ spv_result_t spvOpcodeTableNameLookup(spv_target_env, // SPV_SUCCESS and writes a handle of the table entry into *entry. spv_result_t spvOpcodeTableValueLookup(spv_target_env, const spv_opcode_table table, - const SpvOp opcode, + const spv::Op opcode, spv_opcode_desc* entry); // Copies an instruction's word and fixes the endianness to host native. The // source instruction's stream/opcode/endianness is in the words/opcode/endian // parameter. The word_count parameter specifies the number of words to copy. // Writes copied instruction into *inst. -void spvInstructionCopy(const uint32_t* words, const SpvOp opcode, +void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, const uint16_t word_count, const spv_endianness_t endian, spv_instruction_t* inst); // Determine if the given opcode is a scalar type. Returns zero if false, // non-zero otherwise. -int32_t spvOpcodeIsScalarType(const SpvOp opcode); +int32_t spvOpcodeIsScalarType(const spv::Op opcode); // Determines if the given opcode is a specialization constant. Returns zero if // false, non-zero otherwise. -int32_t spvOpcodeIsSpecConstant(const SpvOp opcode); +int32_t spvOpcodeIsSpecConstant(const spv::Op opcode); // Determines if the given opcode is a constant. Returns zero if false, non-zero // otherwise. -int32_t spvOpcodeIsConstant(const SpvOp opcode); +int32_t spvOpcodeIsConstant(const spv::Op opcode); // Returns true if the given opcode is a constant or undef. -bool spvOpcodeIsConstantOrUndef(const SpvOp opcode); +bool spvOpcodeIsConstantOrUndef(const spv::Op opcode); // Returns true if the given opcode is a scalar specialization constant. -bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode); +bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode); // Determines if the given opcode is a composite type. Returns zero if false, // non-zero otherwise. -int32_t spvOpcodeIsComposite(const SpvOp opcode); +int32_t spvOpcodeIsComposite(const spv::Op opcode); // Determines if the given opcode results in a pointer when using the logical // addressing model. Returns zero if false, non-zero otherwise. -int32_t spvOpcodeReturnsLogicalPointer(const SpvOp opcode); +int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode); // Returns whether the given opcode could result in a pointer or a variable // pointer when using the logical addressing model. -bool spvOpcodeReturnsLogicalVariablePointer(const SpvOp opcode); +bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode); // Determines if the given opcode generates a type. Returns zero if false, // non-zero otherwise. -int32_t spvOpcodeGeneratesType(SpvOp opcode); +int32_t spvOpcodeGeneratesType(spv::Op opcode); // Returns true if the opcode adds a decoration to an id. -bool spvOpcodeIsDecoration(const SpvOp opcode); +bool spvOpcodeIsDecoration(const spv::Op opcode); // Returns true if the opcode is a load from memory into a result id. This // function only considers core instructions. -bool spvOpcodeIsLoad(const SpvOp opcode); +bool spvOpcodeIsLoad(const spv::Op opcode); // Returns true if the opcode is an atomic operation that uses the original // value. -bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode); +bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode); // Returns true if the opcode is an atomic operation. -bool spvOpcodeIsAtomicOp(const SpvOp opcode); +bool spvOpcodeIsAtomicOp(const spv::Op opcode); // Returns true if the given opcode is a branch instruction. -bool spvOpcodeIsBranch(SpvOp opcode); +bool spvOpcodeIsBranch(spv::Op opcode); // Returns true if the given opcode is a return instruction. -bool spvOpcodeIsReturn(SpvOp opcode); +bool spvOpcodeIsReturn(spv::Op opcode); // Returns true if the given opcode aborts execution. To abort means that after // executing that instruction, no other instructions will be executed regardless // of the context in which the instruction appears. Note that `OpUnreachable` // is considered an abort even if its behaviour is undefined. -bool spvOpcodeIsAbort(SpvOp opcode); +bool spvOpcodeIsAbort(spv::Op opcode); // Returns true if the given opcode is a return instruction or it aborts // execution. -bool spvOpcodeIsReturnOrAbort(SpvOp opcode); +bool spvOpcodeIsReturnOrAbort(spv::Op opcode); // Returns true if the given opcode is a basic block terminator. -bool spvOpcodeIsBlockTerminator(SpvOp opcode); +bool spvOpcodeIsBlockTerminator(spv::Op opcode); // Returns true if the given opcode always defines an opaque type. -bool spvOpcodeIsBaseOpaqueType(SpvOp opcode); +bool spvOpcodeIsBaseOpaqueType(spv::Op opcode); // Returns true if the given opcode is a non-uniform group operation. -bool spvOpcodeIsNonUniformGroupOperation(SpvOp opcode); +bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode); // Returns true if the opcode with vector inputs could be divided into a series // of independent scalar operations that would give the same result. -bool spvOpcodeIsScalarizable(SpvOp opcode); +bool spvOpcodeIsScalarizable(spv::Op opcode); // Returns true if the given opcode is a debug instruction. -bool spvOpcodeIsDebug(SpvOp opcode); +bool spvOpcodeIsDebug(spv::Op opcode); // Returns true for opcodes that are binary operators, // where the order of the operands is irrelevant. -bool spvOpcodeIsCommutativeBinaryOperator(SpvOp opcode); +bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode); // Returns true for opcodes that represent linear algebra instructions. -bool spvOpcodeIsLinearAlgebra(SpvOp opcode); +bool spvOpcodeIsLinearAlgebra(spv::Op opcode); // Returns true for opcodes that represent image sample instructions. -bool spvOpcodeIsImageSample(SpvOp opcode); +bool spvOpcodeIsImageSample(spv::Op opcode); // Returns a vector containing the indices of the memory semantics // operands for |opcode|. -std::vector spvOpcodeMemorySemanticsOperandIndices(SpvOp opcode); +std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode); // Returns true for opcodes that represent access chain instructions. -bool spvOpcodeIsAccessChain(SpvOp opcode); +bool spvOpcodeIsAccessChain(spv::Op opcode); // Returns true for opcodes that represent bit instructions. -bool spvOpcodeIsBit(SpvOp opcode); +bool spvOpcodeIsBit(spv::Op opcode); + +// Gets the name of an instruction, without the "Op" prefix. +const char* spvOpcodeString(const spv::Op opcode); #endif // SOURCE_OPCODE_H_ diff --git a/3rdparty/spirv-tools/source/operand.cpp b/3rdparty/spirv-tools/source/operand.cpp index 0c255a352..31a6c5965 100644 --- a/3rdparty/spirv-tools/source/operand.cpp +++ b/3rdparty/spirv-tools/source/operand.cpp @@ -512,7 +512,7 @@ bool spvIsInIdType(spv_operand_type_t type) { } std::function spvOperandCanBeForwardDeclaredFunction( - SpvOp opcode) { + spv::Op opcode) { std::function out; if (spvOpcodeGeneratesType(opcode)) { // All types can use forward pointers. @@ -520,57 +520,57 @@ std::function spvOperandCanBeForwardDeclaredFunction( return out; } switch (opcode) { - case SpvOpExecutionMode: - case SpvOpExecutionModeId: - case SpvOpEntryPoint: - case SpvOpName: - case SpvOpMemberName: - case SpvOpSelectionMerge: - case SpvOpDecorate: - case SpvOpMemberDecorate: - case SpvOpDecorateId: - case SpvOpDecorateStringGOOGLE: - case SpvOpMemberDecorateStringGOOGLE: - case SpvOpBranch: - case SpvOpLoopMerge: + case spv::Op::OpExecutionMode: + case spv::Op::OpExecutionModeId: + case spv::Op::OpEntryPoint: + case spv::Op::OpName: + case spv::Op::OpMemberName: + case spv::Op::OpSelectionMerge: + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: + case spv::Op::OpBranch: + case spv::Op::OpLoopMerge: out = [](unsigned) { return true; }; break; - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: - case SpvOpBranchConditional: - case SpvOpSwitch: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: out = [](unsigned index) { return index != 0; }; break; - case SpvOpFunctionCall: + case spv::Op::OpFunctionCall: // The Function parameter. out = [](unsigned index) { return index == 2; }; break; - case SpvOpPhi: + case spv::Op::OpPhi: out = [](unsigned index) { return index > 1; }; break; - case SpvOpEnqueueKernel: + case spv::Op::OpEnqueueKernel: // The Invoke parameter. out = [](unsigned index) { return index == 8; }; break; - case SpvOpGetKernelNDrangeSubGroupCount: - case SpvOpGetKernelNDrangeMaxSubGroupSize: + case spv::Op::OpGetKernelNDrangeSubGroupCount: + case spv::Op::OpGetKernelNDrangeMaxSubGroupSize: // The Invoke parameter. out = [](unsigned index) { return index == 3; }; break; - case SpvOpGetKernelWorkGroupSize: - case SpvOpGetKernelPreferredWorkGroupSizeMultiple: + case spv::Op::OpGetKernelWorkGroupSize: + case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple: // The Invoke parameter. out = [](unsigned index) { return index == 2; }; break; - case SpvOpTypeForwardPointer: + case spv::Op::OpTypeForwardPointer: out = [](unsigned index) { return index == 0; }; break; - case SpvOpTypeArray: + case spv::Op::OpTypeArray: out = [](unsigned index) { return index == 1; }; break; default: diff --git a/3rdparty/spirv-tools/source/operand.h b/3rdparty/spirv-tools/source/operand.h index 7c73c6f56..a3010d934 100644 --- a/3rdparty/spirv-tools/source/operand.h +++ b/3rdparty/spirv-tools/source/operand.h @@ -139,7 +139,7 @@ bool spvIsInIdType(spv_operand_type_t type); // of the operand can be forward declared. This function will // used in the SSA validation stage of the pipeline std::function spvOperandCanBeForwardDeclaredFunction( - SpvOp opcode); + spv::Op opcode); // Takes the instruction key of a debug info extension instruction // and returns a function object that will return true if the index diff --git a/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp b/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp index 7fa5c8a95..53d13f18b 100644 --- a/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp @@ -31,51 +31,50 @@ namespace spvtools { namespace opt { - namespace { -const uint32_t kTypePointerStorageClassInIdx = 0; -const uint32_t kEntryPointFunctionIdInIdx = 1; -const uint32_t kSelectionMergeMergeBlockIdInIdx = 0; -const uint32_t kLoopMergeContinueBlockIdInIdx = 1; -const uint32_t kCopyMemoryTargetAddrInIdx = 0; -const uint32_t kCopyMemorySourceAddrInIdx = 1; -const uint32_t kLoadSourceAddrInIdx = 0; -const uint32_t kDebugDeclareOperandVariableIndex = 5; -const uint32_t kGlobalVariableVariableIndex = 12; +constexpr uint32_t kTypePointerStorageClassInIdx = 0; +constexpr uint32_t kEntryPointFunctionIdInIdx = 1; +constexpr uint32_t kSelectionMergeMergeBlockIdInIdx = 0; +constexpr uint32_t kLoopMergeContinueBlockIdInIdx = 1; +constexpr uint32_t kCopyMemoryTargetAddrInIdx = 0; +constexpr uint32_t kCopyMemorySourceAddrInIdx = 1; +constexpr uint32_t kLoadSourceAddrInIdx = 0; +constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; +constexpr uint32_t kGlobalVariableVariableIndex = 12; // Sorting functor to present annotation instructions in an easy-to-process // order. The functor orders by opcode first and falls back on unique id // ordering if both instructions have the same opcode. // // Desired priority: -// SpvOpGroupDecorate -// SpvOpGroupMemberDecorate -// SpvOpDecorate -// SpvOpMemberDecorate -// SpvOpDecorateId -// SpvOpDecorateStringGOOGLE -// SpvOpDecorationGroup +// spv::Op::OpGroupDecorate +// spv::Op::OpGroupMemberDecorate +// spv::Op::OpDecorate +// spv::Op::OpMemberDecorate +// spv::Op::OpDecorateId +// spv::Op::OpDecorateStringGOOGLE +// spv::Op::OpDecorationGroup struct DecorationLess { bool operator()(const Instruction* lhs, const Instruction* rhs) const { assert(lhs && rhs); - SpvOp lhsOp = lhs->opcode(); - SpvOp rhsOp = rhs->opcode(); + spv::Op lhsOp = lhs->opcode(); + spv::Op rhsOp = rhs->opcode(); if (lhsOp != rhsOp) { #define PRIORITY_CASE(opcode) \ if (lhsOp == opcode && rhsOp != opcode) return true; \ if (rhsOp == opcode && lhsOp != opcode) return false; // OpGroupDecorate and OpGroupMember decorate are highest priority to // eliminate dead targets early and simplify subsequent checks. - PRIORITY_CASE(SpvOpGroupDecorate) - PRIORITY_CASE(SpvOpGroupMemberDecorate) - PRIORITY_CASE(SpvOpDecorate) - PRIORITY_CASE(SpvOpMemberDecorate) - PRIORITY_CASE(SpvOpDecorateId) - PRIORITY_CASE(SpvOpDecorateStringGOOGLE) + PRIORITY_CASE(spv::Op::OpGroupDecorate) + PRIORITY_CASE(spv::Op::OpGroupMemberDecorate) + PRIORITY_CASE(spv::Op::OpDecorate) + PRIORITY_CASE(spv::Op::OpMemberDecorate) + PRIORITY_CASE(spv::Op::OpDecorateId) + PRIORITY_CASE(spv::Op::OpDecorateStringGOOGLE) // OpDecorationGroup is lowest priority to ensure use/def chains remain // usable for instructions that target this group. - PRIORITY_CASE(SpvOpDecorationGroup) + PRIORITY_CASE(spv::Op::OpDecorationGroup) #undef PRIORITY_CASE } @@ -86,25 +85,26 @@ struct DecorationLess { } // namespace -bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, uint32_t storageClass) { +bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, + spv::StorageClass storageClass) { if (varId == 0) return false; const Instruction* varInst = get_def_use_mgr()->GetDef(varId); - const SpvOp op = varInst->opcode(); - if (op != SpvOpVariable) return false; + const spv::Op op = varInst->opcode(); + if (op != spv::Op::OpVariable) return false; const uint32_t varTypeId = varInst->type_id(); const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (varTypeInst->opcode() != SpvOpTypePointer) return false; - return varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) == - storageClass; + if (varTypeInst->opcode() != spv::Op::OpTypePointer) return false; + return spv::StorageClass(varTypeInst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)) == storageClass; } bool AggressiveDCEPass::IsLocalVar(uint32_t varId, Function* func) { - if (IsVarOfStorage(varId, SpvStorageClassFunction)) { + if (IsVarOfStorage(varId, spv::StorageClass::Function)) { return true; } - if (!IsVarOfStorage(varId, SpvStorageClassPrivate) && - !IsVarOfStorage(varId, SpvStorageClassWorkgroup)) { + if (!IsVarOfStorage(varId, spv::StorageClass::Private) && + !IsVarOfStorage(varId, spv::StorageClass::Workgroup)) { return false; } @@ -122,21 +122,21 @@ void AggressiveDCEPass::AddStores(Function* func, uint32_t ptrId) { if (blk && blk->GetParent() != func) return; switch (user->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpCopyObject: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpCopyObject: this->AddStores(func, user->result_id()); break; - case SpvOpLoad: + case spv::Op::OpLoad: break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: if (user->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx) == ptrId) { AddToWorklist(user); } break; // If default, assume it stores e.g. frexp, modf, function call - case SpvOpStore: + case spv::Op::OpStore: default: AddToWorklist(user); break; @@ -154,7 +154,7 @@ bool AggressiveDCEPass::AllExtensionsSupported() const { // Only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise // around unknown extended instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == SpvOpExtInstImport && + assert(inst.opcode() == spv::Op::OpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -172,11 +172,11 @@ bool AggressiveDCEPass::IsTargetDead(Instruction* inst) { // This must be a decoration group. We go through annotations in a specific // order. So if this is not used by any group or group member decorates, it // is dead. - assert(tInst->opcode() == SpvOpDecorationGroup); + assert(tInst->opcode() == spv::Op::OpDecorationGroup); bool dead = true; get_def_use_mgr()->ForEachUser(tInst, [&dead](Instruction* user) { - if (user->opcode() == SpvOpGroupDecorate || - user->opcode() == SpvOpGroupMemberDecorate) + if (user->opcode() == spv::Op::OpGroupDecorate || + user->opcode() == spv::Op::OpGroupMemberDecorate) dead = false; }); return dead; @@ -197,7 +197,7 @@ void AggressiveDCEPass::ProcessLoad(Function* func, uint32_t varId) { void AggressiveDCEPass::AddBranch(uint32_t labelId, BasicBlock* bp) { std::unique_ptr newBranch( - new Instruction(context(), SpvOpBranch, 0, 0, + new Instruction(context(), spv::Op::OpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); context()->AnalyzeDefUse(&*newBranch); context()->set_instr_block(&*newBranch, bp); @@ -206,8 +206,8 @@ void AggressiveDCEPass::AddBranch(uint32_t labelId, BasicBlock* bp) { void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( Instruction* mergeInst) { - assert(mergeInst->opcode() == SpvOpSelectionMerge || - mergeInst->opcode() == SpvOpLoopMerge); + assert(mergeInst->opcode() == spv::Op::OpSelectionMerge || + mergeInst->opcode() == spv::Op::OpLoopMerge); BasicBlock* header = context()->get_instr_block(mergeInst); const uint32_t mergeId = mergeInst->GetSingleWordInOperand(0); @@ -223,7 +223,7 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( } }); - if (mergeInst->opcode() != SpvOpLoopMerge) { + if (mergeInst->opcode() != spv::Op::OpLoopMerge) { return; } @@ -231,26 +231,27 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( const uint32_t contId = mergeInst->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx); get_def_use_mgr()->ForEachUser(contId, [&contId, this](Instruction* user) { - SpvOp op = user->opcode(); - if (op == SpvOpBranchConditional || op == SpvOpSwitch) { + spv::Op op = user->opcode(); + if (op == spv::Op::OpBranchConditional || op == spv::Op::OpSwitch) { // A conditional branch or switch can only be a continue if it does not // have a merge instruction or its merge block is not the continue block. Instruction* hdrMerge = GetMergeInstruction(user); - if (hdrMerge != nullptr && hdrMerge->opcode() == SpvOpSelectionMerge) { + if (hdrMerge != nullptr && + hdrMerge->opcode() == spv::Op::OpSelectionMerge) { uint32_t hdrMergeId = hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); if (hdrMergeId == contId) return; // Need to mark merge instruction too AddToWorklist(hdrMerge); } - } else if (op == SpvOpBranch) { + } else if (op == spv::Op::OpBranch) { // An unconditional branch can only be a continue if it is not // branching to its own merge block. BasicBlock* blk = context()->get_instr_block(user); Instruction* hdrBranch = GetHeaderBranch(blk); if (hdrBranch == nullptr) return; Instruction* hdrMerge = GetMergeInstruction(hdrBranch); - if (hdrMerge->opcode() == SpvOpLoopMerge) return; + if (hdrMerge->opcode() == spv::Op::OpLoopMerge) return; uint32_t hdrMergeId = hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); if (contId == hdrMergeId) return; @@ -277,11 +278,11 @@ bool AggressiveDCEPass::KillDeadInstructions( uint32_t merge_block_id = 0; (*bi)->ForEachInst([this, &modified, &merge_block_id](Instruction* inst) { if (IsLive(inst)) return; - if (inst->opcode() == SpvOpLabel) return; + if (inst->opcode() == spv::Op::OpLabel) return; // If dead instruction is selection merge, remember merge block // for new branch at end of block - if (inst->opcode() == SpvOpSelectionMerge || - inst->opcode() == SpvOpLoopMerge) + if (inst->opcode() == spv::Op::OpSelectionMerge || + inst->opcode() == spv::Op::OpLoopMerge) merge_block_id = inst->GetSingleWordInOperand(0); to_kill_.push_back(inst); modified = true; @@ -295,19 +296,19 @@ bool AggressiveDCEPass::KillDeadInstructions( } auto merge_terminator = (*bi)->terminator(); - if (merge_terminator->opcode() == SpvOpUnreachable) { + if (merge_terminator->opcode() == spv::Op::OpUnreachable) { // The merge was unreachable. This is undefined behaviour so just // return (or return an undef). Then mark the new return as live. auto func_ret_type_inst = get_def_use_mgr()->GetDef(func->type_id()); - if (func_ret_type_inst->opcode() == SpvOpTypeVoid) { - merge_terminator->SetOpcode(SpvOpReturn); + if (func_ret_type_inst->opcode() == spv::Op::OpTypeVoid) { + merge_terminator->SetOpcode(spv::Op::OpReturn); } else { // Find an undef for the return value and make sure it gets kept by // the pass. auto undef_id = Type2Undef(func->type_id()); auto undef = get_def_use_mgr()->GetDef(undef_id); live_insts_.Set(undef->unique_id()); - merge_terminator->SetOpcode(SpvOpReturnValue); + merge_terminator->SetOpcode(spv::Op::OpReturnValue); merge_terminator->SetInOperands({{SPV_OPERAND_TYPE_ID, {undef_id}}}); get_def_use_mgr()->AnalyzeInstUse(merge_terminator); } @@ -369,11 +370,11 @@ void AggressiveDCEPass::AddDecorationsToWorkList(const Instruction* inst) { // We only care about OpDecorateId instructions because the are the only // decorations that will reference an id that will have to be kept live // because of that use. - if (dec->opcode() != SpvOpDecorateId) { + if (dec->opcode() != spv::Op::OpDecorateId) { continue; } - if (dec->GetSingleWordInOperand(1) == - SpvDecorationHlslCounterBufferGOOGLE) { + if (spv::Decoration(dec->GetSingleWordInOperand(1)) == + spv::Decoration::HlslCounterBufferGOOGLE) { // These decorations should not force the use id to be live. It will be // removed if either the target or the in operand are dead. continue; @@ -391,7 +392,7 @@ void AggressiveDCEPass::MarkLoadedVariablesAsLive(Function* func, } std::vector AggressiveDCEPass::GetLoadedVariables(Instruction* inst) { - if (inst->opcode() == SpvOpFunctionCall) { + if (inst->opcode() == spv::Op::OpFunctionCall) { return GetLoadedVariablesFromFunctionCall(inst); } uint32_t var_id = GetLoadedVariableFromNonFunctionCalls(inst); @@ -409,11 +410,11 @@ uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( } switch (inst->opcode()) { - case SpvOpLoad: - case SpvOpImageTexelPointer: + case spv::Op::OpLoad: + case spv::Op::OpImageTexelPointer: return GetVariableId(inst->GetSingleWordInOperand(kLoadSourceAddrInIdx)); - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: return GetVariableId( inst->GetSingleWordInOperand(kCopyMemorySourceAddrInIdx)); default: @@ -436,7 +437,7 @@ uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( std::vector AggressiveDCEPass::GetLoadedVariablesFromFunctionCall( const Instruction* inst) { - assert(inst->opcode() == SpvOpFunctionCall); + assert(inst->opcode() == spv::Op::OpFunctionCall); std::vector live_variables; inst->ForEachInId([this, &live_variables](const uint32_t* operand_id) { if (!IsPtr(*operand_id)) return; @@ -481,7 +482,7 @@ void AggressiveDCEPass::MarkBlockAsLive(Instruction* inst) { // the loop, so the loop construct must be live. We exclude the label because // it does not matter how many times it is executed. This could be extended // to more instructions, but we will need it for now. - if (inst->opcode() != SpvOpLabel) + if (inst->opcode() != spv::Op::OpLabel) MarkLoopConstructAsLiveIfLoopHeader(basic_block); Instruction* next_branch_inst = GetBranchForNextHeader(basic_block); @@ -491,8 +492,8 @@ void AggressiveDCEPass::MarkBlockAsLive(Instruction* inst) { AddToWorklist(mergeInst); } - if (inst->opcode() == SpvOpLoopMerge || - inst->opcode() == SpvOpSelectionMerge) { + if (inst->opcode() == spv::Op::OpLoopMerge || + inst->opcode() == spv::Op::OpSelectionMerge) { AddBreaksAndContinuesToWorklist(inst); } } @@ -529,27 +530,27 @@ void AggressiveDCEPass::InitializeWorkList( // cleaned up. for (auto& bi : structured_order) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { - SpvOp op = ii->opcode(); + spv::Op op = ii->opcode(); if (ii->IsBranch()) { continue; } switch (op) { - case SpvOpStore: { + case spv::Op::OpStore: { uint32_t var_id = 0; (void)GetPtr(&*ii, &var_id); if (!IsLocalVar(var_id, func)) AddToWorklist(&*ii); } break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: { + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: { uint32_t var_id = 0; uint32_t target_addr_id = ii->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx); (void)GetPtr(target_addr_id, &var_id); if (!IsLocalVar(var_id, func)) AddToWorklist(&*ii); } break; - case SpvOpLoopMerge: - case SpvOpSelectionMerge: - case SpvOpUnreachable: + case spv::Op::OpLoopMerge: + case spv::Op::OpSelectionMerge: + case spv::Op::OpUnreachable: break; default: { // Function calls, atomics, function params, function returns, etc. @@ -578,8 +579,10 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { auto* var = get_def_use_mgr()->GetDef(entry.GetSingleWordInOperand(i)); auto storage_class = var->GetSingleWordInOperand(0u); // Vulkan support outputs without an associated input, but not inputs - // without an associated output. - if (storage_class == SpvStorageClassOutput) { + // without an associated output. Don't remove outputs unless explicitly + // allowed. + if (!remove_outputs_ && + spv::StorageClass(storage_class) == spv::StorageClass::Output) { AddToWorklist(var); } } @@ -588,24 +591,29 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { } } for (auto& anno : get_module()->annotations()) { - if (anno.opcode() == SpvOpDecorate) { + if (anno.opcode() == spv::Op::OpDecorate) { // Keep workgroup size. - if (anno.GetSingleWordInOperand(1u) == SpvDecorationBuiltIn && - anno.GetSingleWordInOperand(2u) == SpvBuiltInWorkgroupSize) { + if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::BuiltIn && + spv::BuiltIn(anno.GetSingleWordInOperand(2u)) == + spv::BuiltIn::WorkgroupSize) { AddToWorklist(&anno); } if (context()->preserve_bindings()) { // Keep all bindings. - if ((anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet) || - (anno.GetSingleWordInOperand(1u) == SpvDecorationBinding)) { + if ((spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::DescriptorSet) || + (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::Binding)) { AddToWorklist(&anno); } } if (context()->preserve_spec_constants()) { // Keep all specialization constant instructions - if (anno.GetSingleWordInOperand(1u) == SpvDecorationSpecId) { + if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::SpecId) { AddToWorklist(&anno); } } @@ -624,7 +632,7 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { debug_global_seen = true; dbg.ForEachInId([this](const uint32_t* iid) { Instruction* in_inst = get_def_use_mgr()->GetDef(*iid); - if (in_inst->opcode() == SpvOpVariable) return; + if (in_inst->opcode() == spv::Op::OpVariable) return; AddToWorklist(in_inst); }); } @@ -647,19 +655,19 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { Pass::Status AggressiveDCEPass::ProcessImpl() { // Current functionality assumes shader capability // TODO(greg-lunarg): Handle additional capabilities - if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) return Status::SuccessWithoutChange; // Current functionality assumes relaxed logical addressing (see // instruction.h) // TODO(greg-lunarg): Handle non-logical addressing - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) return Status::SuccessWithoutChange; // The variable pointer extension is no longer needed to use the capability, // so we have to look for the capability. if (context()->get_feature_mgr()->HasCapability( - SpvCapabilityVariablePointersStorageBuffer)) + spv::Capability::VariablePointersStorageBuffer)) return Status::SuccessWithoutChange; // If any extensions in the module are not explicitly supported, @@ -743,7 +751,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { bool modified = false; Instruction* instruction = &*get_module()->debug2_begin(); while (instruction) { - if (instruction->opcode() != SpvOpName) { + if (instruction->opcode() != spv::Op::OpName) { instruction = instruction->NextNode(); continue; } @@ -764,22 +772,22 @@ bool AggressiveDCEPass::ProcessGlobalValues() { std::sort(annotations.begin(), annotations.end(), DecorationLess()); for (auto annotation : annotations) { switch (annotation->opcode()) { - case SpvOpDecorate: - case SpvOpMemberDecorate: - case SpvOpDecorateStringGOOGLE: - case SpvOpMemberDecorateStringGOOGLE: + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: if (IsTargetDead(annotation)) { context()->KillInst(annotation); modified = true; } break; - case SpvOpDecorateId: + case spv::Op::OpDecorateId: if (IsTargetDead(annotation)) { context()->KillInst(annotation); modified = true; } else { - if (annotation->GetSingleWordInOperand(1) == - SpvDecorationHlslCounterBufferGOOGLE) { + if (spv::Decoration(annotation->GetSingleWordInOperand(1)) == + spv::Decoration::HlslCounterBufferGOOGLE) { // HlslCounterBuffer will reference an id other than the target. // If that id is dead, then the decoration can be removed as well. uint32_t counter_buffer_id = annotation->GetSingleWordInOperand(2); @@ -792,7 +800,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { } } break; - case SpvOpGroupDecorate: { + case spv::Op::OpGroupDecorate: { // Go through the targets of this group decorate. Remove each dead // target. If all targets are dead, remove this decoration. bool dead = true; @@ -818,7 +826,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { } break; } - case SpvOpGroupMemberDecorate: { + case spv::Op::OpGroupMemberDecorate: { // Go through the targets of this group member decorate. Remove each // dead target (and member index). If all targets are dead, remove this // decoration. @@ -846,7 +854,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { } break; } - case SpvOpDecorationGroup: + case spv::Op::OpDecorationGroup: // By the time we hit decoration groups we've checked everything that // can target them. So if they have no uses they must be dead. if (get_def_use_mgr()->NumUsers(annotation) == 0) { @@ -887,7 +895,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { // this live as it does not have a result id. This is a little too // conservative since it is not known if the structure type that needed // it is still live. TODO(greg-lunarg): Only save if needed. - if (val.opcode() == SpvOpTypeForwardPointer) { + if (val.opcode() == spv::Op::OpTypeForwardPointer) { uint32_t ptr_ty_id = val.GetSingleWordInOperand(0); Instruction* ptr_ty_inst = get_def_use_mgr()->GetDef(ptr_ty_id); if (IsLive(ptr_ty_inst)) continue; @@ -1083,8 +1091,9 @@ bool AggressiveDCEPass::IsEntryPoint(Function* func) { } bool AggressiveDCEPass::HasCall(Function* func) { - return !func->WhileEachInst( - [](Instruction* inst) { return inst->opcode() != SpvOpFunctionCall; }); + return !func->WhileEachInst([](Instruction* inst) { + return inst->opcode() != spv::Op::OpFunctionCall; + }); } void AggressiveDCEPass::MarkFirstBlockAsLive(Function* func) { diff --git a/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h b/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h index c1291dc47..fbe08ad03 100644 --- a/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h +++ b/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h @@ -44,8 +44,10 @@ class AggressiveDCEPass : public MemPass { using GetBlocksFunction = std::function*(const BasicBlock*)>; - AggressiveDCEPass(bool preserve_interface = false) - : preserve_interface_(preserve_interface) {} + AggressiveDCEPass(bool preserve_interface = false, + bool remove_outputs = false) + : preserve_interface_(preserve_interface), + remove_outputs_(remove_outputs) {} const char* name() const override { return "eliminate-dead-code-aggressive"; } Status Process() override; @@ -63,9 +65,14 @@ class AggressiveDCEPass : public MemPass { // is not allowed. bool preserve_interface_; + // Output variables can be removed from the interface if this is true. + // This is safe if the caller knows that the corresponding input variable + // in the following shader has been removed. It is false by default. + bool remove_outputs_; + // Return true if |varId| is a variable of |storageClass|. |varId| must either // be 0 or the result of an instruction. - bool IsVarOfStorage(uint32_t varId, uint32_t storageClass); + bool IsVarOfStorage(uint32_t varId, spv::StorageClass storageClass); // Return true if the instance of the variable |varId| can only be access in // |func|. For example, a function scope variable, or a private variable diff --git a/3rdparty/spirv-tools/source/opt/amd_ext_to_khr.cpp b/3rdparty/spirv-tools/source/opt/amd_ext_to_khr.cpp index dd9bafda3..a314567f8 100644 --- a/3rdparty/spirv-tools/source/opt/amd_ext_to_khr.cpp +++ b/3rdparty/spirv-tools/source/opt/amd_ext_to_khr.cpp @@ -24,7 +24,6 @@ namespace spvtools { namespace opt { - namespace { enum AmdShaderBallotExtOpcodes { @@ -136,19 +135,19 @@ bool ReplaceTrinaryMid(IRContext* ctx, Instruction* inst, // Returns a folding rule that will replace the opcode with |opcode| and add // the capabilities required. The folding rule assumes it is folding an // OpGroup*NonUniformAMD instruction from the SPV_AMD_shader_ballot extension. -template +template bool ReplaceGroupNonuniformOperationOpCode( IRContext* ctx, Instruction* inst, const std::vector&) { switch (new_opcode) { - case SpvOpGroupNonUniformIAdd: - case SpvOpGroupNonUniformFAdd: - case SpvOpGroupNonUniformUMin: - case SpvOpGroupNonUniformSMin: - case SpvOpGroupNonUniformFMin: - case SpvOpGroupNonUniformUMax: - case SpvOpGroupNonUniformSMax: - case SpvOpGroupNonUniformFMax: + case spv::Op::OpGroupNonUniformIAdd: + case spv::Op::OpGroupNonUniformFAdd: + case spv::Op::OpGroupNonUniformUMin: + case spv::Op::OpGroupNonUniformSMin: + case spv::Op::OpGroupNonUniformFMin: + case spv::Op::OpGroupNonUniformUMax: + case spv::Op::OpGroupNonUniformSMax: + case spv::Op::OpGroupNonUniformFMax: break; default: assert( @@ -157,21 +156,21 @@ bool ReplaceGroupNonuniformOperationOpCode( } switch (inst->opcode()) { - case SpvOpGroupIAddNonUniformAMD: - case SpvOpGroupFAddNonUniformAMD: - case SpvOpGroupUMinNonUniformAMD: - case SpvOpGroupSMinNonUniformAMD: - case SpvOpGroupFMinNonUniformAMD: - case SpvOpGroupUMaxNonUniformAMD: - case SpvOpGroupSMaxNonUniformAMD: - case SpvOpGroupFMaxNonUniformAMD: + case spv::Op::OpGroupIAddNonUniformAMD: + case spv::Op::OpGroupFAddNonUniformAMD: + case spv::Op::OpGroupUMinNonUniformAMD: + case spv::Op::OpGroupSMinNonUniformAMD: + case spv::Op::OpGroupFMinNonUniformAMD: + case spv::Op::OpGroupUMaxNonUniformAMD: + case spv::Op::OpGroupSMaxNonUniformAMD: + case spv::Op::OpGroupFMaxNonUniformAMD: break; default: assert(false && "Should be replacing a group non uniform arithmetic operation."); } - ctx->AddCapability(SpvCapabilityGroupNonUniformArithmetic); + ctx->AddCapability(spv::Capability::GroupNonUniformArithmetic); inst->SetOpcode(new_opcode); return true; } @@ -215,8 +214,8 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); ctx->AddExtension("SPV_KHR_shader_ballot"); - ctx->AddCapability(SpvCapabilityGroupNonUniformBallot); - ctx->AddCapability(SpvCapabilityGroupNonUniformShuffle); + ctx->AddCapability(spv::Capability::GroupNonUniformBallot); + ctx->AddCapability(spv::Capability::GroupNonUniformShuffle); InstructionBuilder ir_builder( ctx, inst, @@ -226,8 +225,8 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, uint32_t offset_id = inst->GetSingleWordInOperand(3); // Get the subgroup invocation id. - uint32_t var_id = - ctx->GetBuiltinInputVarId(SpvBuiltInSubgroupLocalInvocationId); + uint32_t var_id = ctx->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); Instruction* var_ptr_type = @@ -239,35 +238,38 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, uint32_t quad_mask = ir_builder.GetUintConstantId(3); // This gives the offset in the group of 4 of this invocation. - Instruction* quad_idx = ir_builder.AddBinaryOp(uint_type_id, SpvOpBitwiseAnd, - id->result_id(), quad_mask); + Instruction* quad_idx = ir_builder.AddBinaryOp( + uint_type_id, spv::Op::OpBitwiseAnd, id->result_id(), quad_mask); // Get the invocation id of the first invocation in the group of 4. - Instruction* quad_ldr = ir_builder.AddBinaryOp( - uint_type_id, SpvOpBitwiseXor, id->result_id(), quad_idx->result_id()); + Instruction* quad_ldr = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpBitwiseXor, + id->result_id(), quad_idx->result_id()); // Get the offset of the target invocation from the offset vector. Instruction* my_offset = - ir_builder.AddBinaryOp(uint_type_id, SpvOpVectorExtractDynamic, offset_id, - quad_idx->result_id()); + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpVectorExtractDynamic, + offset_id, quad_idx->result_id()); // Determine the index of the invocation to read from. - Instruction* target_inv = ir_builder.AddBinaryOp( - uint_type_id, SpvOpIAdd, quad_ldr->result_id(), my_offset->result_id()); + Instruction* target_inv = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpIAdd, + quad_ldr->result_id(), my_offset->result_id()); // Do the group operations uint32_t uint_max_id = ir_builder.GetUintConstantId(0xFFFFFFFF); - uint32_t subgroup_scope = ir_builder.GetUintConstantId(SpvScopeSubgroup); + uint32_t subgroup_scope = + ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); const auto* ballot_value_const = const_mgr->GetConstant( type_mgr->GetUIntVectorType(4), {uint_max_id, uint_max_id, uint_max_id, uint_max_id}); Instruction* ballot_value = const_mgr->GetDefiningInstruction(ballot_value_const); Instruction* is_active = ir_builder.AddNaryOp( - type_mgr->GetBoolTypeId(), SpvOpGroupNonUniformBallotBitExtract, + type_mgr->GetBoolTypeId(), spv::Op::OpGroupNonUniformBallotBitExtract, {subgroup_scope, ballot_value->result_id(), target_inv->result_id()}); Instruction* shuffle = - ir_builder.AddNaryOp(inst->type_id(), SpvOpGroupNonUniformShuffle, + ir_builder.AddNaryOp(inst->type_id(), spv::Op::OpGroupNonUniformShuffle, {subgroup_scope, data_id, target_inv->result_id()}); // Create the null constant to use in the select. @@ -276,7 +278,7 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, Instruction* null_inst = const_mgr->GetDefiningInstruction(null); // Build the select. - inst->SetOpcode(SpvOpSelect); + inst->SetOpcode(spv::Op::OpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_active->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {shuffle->result_id()}}); @@ -327,8 +329,8 @@ bool ReplaceSwizzleInvocationsMasked( analysis::DefUseManager* def_use_mgr = ctx->get_def_use_mgr(); analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); - ctx->AddCapability(SpvCapabilityGroupNonUniformBallot); - ctx->AddCapability(SpvCapabilityGroupNonUniformShuffle); + ctx->AddCapability(spv::Capability::GroupNonUniformBallot); + ctx->AddCapability(spv::Capability::GroupNonUniformShuffle); InstructionBuilder ir_builder( ctx, inst, @@ -338,7 +340,7 @@ bool ReplaceSwizzleInvocationsMasked( uint32_t data_id = inst->GetSingleWordInOperand(2); Instruction* mask_inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(3)); - assert(mask_inst->opcode() == SpvOpConstantComposite && + assert(mask_inst->opcode() == spv::Op::OpConstantComposite && "The mask is suppose to be a vector constant."); assert(mask_inst->NumInOperands() == 3 && "The mask is suppose to have 3 components."); @@ -348,8 +350,8 @@ bool ReplaceSwizzleInvocationsMasked( uint32_t uint_z = mask_inst->GetSingleWordInOperand(2); // Get the subgroup invocation id. - uint32_t var_id = - ctx->GetBuiltinInputVarId(SpvBuiltInSubgroupLocalInvocationId); + uint32_t var_id = ctx->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); ctx->AddExtension("SPV_KHR_shader_ballot"); assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); @@ -361,28 +363,30 @@ bool ReplaceSwizzleInvocationsMasked( // Do the bitwise operations. uint32_t mask_extended = ir_builder.GetUintConstantId(0xFFFFFFE0); - Instruction* and_mask = ir_builder.AddBinaryOp(uint_type_id, SpvOpBitwiseOr, - uint_x, mask_extended); - Instruction* and_result = ir_builder.AddBinaryOp( - uint_type_id, SpvOpBitwiseAnd, id->result_id(), and_mask->result_id()); + Instruction* and_mask = ir_builder.AddBinaryOp( + uint_type_id, spv::Op::OpBitwiseOr, uint_x, mask_extended); + Instruction* and_result = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpBitwiseAnd, + id->result_id(), and_mask->result_id()); Instruction* or_result = ir_builder.AddBinaryOp( - uint_type_id, SpvOpBitwiseOr, and_result->result_id(), uint_y); + uint_type_id, spv::Op::OpBitwiseOr, and_result->result_id(), uint_y); Instruction* target_inv = ir_builder.AddBinaryOp( - uint_type_id, SpvOpBitwiseXor, or_result->result_id(), uint_z); + uint_type_id, spv::Op::OpBitwiseXor, or_result->result_id(), uint_z); // Do the group operations uint32_t uint_max_id = ir_builder.GetUintConstantId(0xFFFFFFFF); - uint32_t subgroup_scope = ir_builder.GetUintConstantId(SpvScopeSubgroup); + uint32_t subgroup_scope = + ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); const auto* ballot_value_const = const_mgr->GetConstant( type_mgr->GetUIntVectorType(4), {uint_max_id, uint_max_id, uint_max_id, uint_max_id}); Instruction* ballot_value = const_mgr->GetDefiningInstruction(ballot_value_const); Instruction* is_active = ir_builder.AddNaryOp( - type_mgr->GetBoolTypeId(), SpvOpGroupNonUniformBallotBitExtract, + type_mgr->GetBoolTypeId(), spv::Op::OpGroupNonUniformBallotBitExtract, {subgroup_scope, ballot_value->result_id(), target_inv->result_id()}); Instruction* shuffle = - ir_builder.AddNaryOp(inst->type_id(), SpvOpGroupNonUniformShuffle, + ir_builder.AddNaryOp(inst->type_id(), spv::Op::OpGroupNonUniformShuffle, {subgroup_scope, data_id, target_inv->result_id()}); // Create the null constant to use in the select. @@ -391,7 +395,7 @@ bool ReplaceSwizzleInvocationsMasked( Instruction* null_inst = const_mgr->GetDefiningInstruction(null); // Build the select. - inst->SetOpcode(SpvOpSelect); + inst->SetOpcode(spv::Op::OpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_active->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {shuffle->result_id()}}); @@ -420,9 +424,9 @@ bool ReplaceSwizzleInvocationsMasked( // Also adding the capabilities and builtins that are needed. bool ReplaceWriteInvocation(IRContext* ctx, Instruction* inst, const std::vector&) { - uint32_t var_id = - ctx->GetBuiltinInputVarId(SpvBuiltInSubgroupLocalInvocationId); - ctx->AddCapability(SpvCapabilitySubgroupBallotKHR); + uint32_t var_id = ctx->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); + ctx->AddCapability(spv::Capability::SubgroupBallotKHR); ctx->AddExtension("SPV_KHR_shader_ballot"); assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); @@ -437,11 +441,11 @@ bool ReplaceWriteInvocation(IRContext* ctx, Instruction* inst, analysis::Bool bool_type; uint32_t bool_type_id = ctx->get_type_mgr()->GetTypeInstruction(&bool_type); Instruction* cmp = - ir_builder.AddBinaryOp(bool_type_id, SpvOpIEqual, t->result_id(), + ir_builder.AddBinaryOp(bool_type_id, spv::Op::OpIEqual, t->result_id(), inst->GetSingleWordInOperand(4)); // Build a select. - inst->SetOpcode(SpvOpSelect); + inst->SetOpcode(spv::Op::OpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {cmp->result_id()}}); new_operands.push_back(inst->GetInOperand(3)); @@ -479,14 +483,15 @@ bool ReplaceMbcnt(IRContext* context, Instruction* inst, analysis::TypeManager* type_mgr = context->get_type_mgr(); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - uint32_t var_id = context->GetBuiltinInputVarId(SpvBuiltInSubgroupLtMask); + uint32_t var_id = + context->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::SubgroupLtMask)); assert(var_id != 0 && "Could not get SubgroupLtMask variable."); - context->AddCapability(SpvCapabilityGroupNonUniformBallot); + context->AddCapability(spv::Capability::GroupNonUniformBallot); Instruction* var_inst = def_use_mgr->GetDef(var_id); Instruction* var_ptr_type = def_use_mgr->GetDef(var_inst->type_id()); Instruction* var_type = def_use_mgr->GetDef(var_ptr_type->GetSingleWordInOperand(1)); - assert(var_type->opcode() == SpvOpTypeVector && + assert(var_type->opcode() == spv::Op::OpTypeVector && "Variable is suppose to be a vector of 4 ints"); // Get the type for the shuffle. @@ -509,11 +514,12 @@ bool ReplaceMbcnt(IRContext* context, Instruction* inst, Instruction* shuffle = ir_builder.AddVectorShuffle( shuffle_type_id, load->result_id(), load->result_id(), {0, 1}); Instruction* bitcast = ir_builder.AddUnaryOp( - mask_inst->type_id(), SpvOpBitcast, shuffle->result_id()); - Instruction* t = ir_builder.AddBinaryOp(mask_inst->type_id(), SpvOpBitwiseAnd, - bitcast->result_id(), mask_id); + mask_inst->type_id(), spv::Op::OpBitcast, shuffle->result_id()); + Instruction* t = + ir_builder.AddBinaryOp(mask_inst->type_id(), spv::Op::OpBitwiseAnd, + bitcast->result_id(), mask_id); - inst->SetOpcode(SpvOpBitCount); + inst->SetOpcode(spv::Op::OpBitCount); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {t->result_id()}}}); context->UpdateDefUse(inst); return true; @@ -599,11 +605,11 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, // Negate the input values. Instruction* nx = - ir_builder.AddUnaryOp(float_type_id, SpvOpFNegate, x->result_id()); + ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, x->result_id()); Instruction* ny = - ir_builder.AddUnaryOp(float_type_id, SpvOpFNegate, y->result_id()); + ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, y->result_id()); Instruction* nz = - ir_builder.AddUnaryOp(float_type_id, SpvOpFNegate, z->result_id()); + ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, z->result_id()); // Get the abolsute values of the inputs. Instruction* ax = ir_builder.AddNaryExtendedInstruction( @@ -614,12 +620,12 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {z->result_id()}); // Find which values are negative. Used in later computations. - Instruction* is_z_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, - z->result_id(), f0_const_id); - Instruction* is_y_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, - y->result_id(), f0_const_id); - Instruction* is_x_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, - x->result_id(), f0_const_id); + Instruction* is_z_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, z->result_id(), f0_const_id); + Instruction* is_y_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, y->result_id(), f0_const_id); + Instruction* is_x_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, x->result_id(), f0_const_id); // Compute cubema Instruction* amax_x_y = ir_builder.AddNaryExtendedInstruction( @@ -628,19 +634,21 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, Instruction* amax = ir_builder.AddNaryExtendedInstruction( float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, {az->result_id(), amax_x_y->result_id()}); - Instruction* cubema = ir_builder.AddBinaryOp(float_type_id, SpvOpFMul, + Instruction* cubema = ir_builder.AddBinaryOp(float_type_id, spv::Op::OpFMul, f2_const_id, amax->result_id()); // Do the comparisons needed for computing cubesc and cubetc. Instruction* is_z_max = - ir_builder.AddBinaryOp(bool_id, SpvOpFOrdGreaterThanEqual, + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, az->result_id(), amax_x_y->result_id()); - Instruction* not_is_z_max = - ir_builder.AddUnaryOp(bool_id, SpvOpLogicalNot, is_z_max->result_id()); - Instruction* y_gr_x = ir_builder.AddBinaryOp( - bool_id, SpvOpFOrdGreaterThanEqual, ay->result_id(), ax->result_id()); - Instruction* is_y_max = ir_builder.AddBinaryOp( - bool_id, SpvOpLogicalAnd, not_is_z_max->result_id(), y_gr_x->result_id()); + Instruction* not_is_z_max = ir_builder.AddUnaryOp( + bool_id, spv::Op::OpLogicalNot, is_z_max->result_id()); + Instruction* y_gr_x = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + ay->result_id(), ax->result_id()); + Instruction* is_y_max = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpLogicalAnd, + not_is_z_max->result_id(), y_gr_x->result_id()); // Select the correct value for cubesc. Instruction* cubesc_case_1 = ir_builder.AddSelect( @@ -667,10 +675,10 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, Instruction* denom = ir_builder.AddCompositeConstruct( v2_float_type_id, {cubema->result_id(), cubema->result_id()}); Instruction* div = ir_builder.AddBinaryOp( - v2_float_type_id, SpvOpFDiv, cube->result_id(), denom->result_id()); + v2_float_type_id, spv::Op::OpFDiv, cube->result_id(), denom->result_id()); // Get the final result by adding 0.5 to |div|. - inst->SetOpcode(SpvOpFAdd); + inst->SetOpcode(spv::Op::OpFAdd); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {div->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {vec_const_id}}); @@ -752,22 +760,23 @@ bool ReplaceCubeFaceIndex(IRContext* ctx, Instruction* inst, float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {z->result_id()}); // Find which values are negative. Used in later computations. - Instruction* is_z_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, - z->result_id(), f0_const_id); - Instruction* is_y_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, - y->result_id(), f0_const_id); - Instruction* is_x_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, - x->result_id(), f0_const_id); + Instruction* is_z_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, z->result_id(), f0_const_id); + Instruction* is_y_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, y->result_id(), f0_const_id); + Instruction* is_x_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, x->result_id(), f0_const_id); // Find the max value. Instruction* amax_x_y = ir_builder.AddNaryExtendedInstruction( float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, {ax->result_id(), ay->result_id()}); Instruction* is_z_max = - ir_builder.AddBinaryOp(bool_id, SpvOpFOrdGreaterThanEqual, + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, az->result_id(), amax_x_y->result_id()); - Instruction* y_gr_x = ir_builder.AddBinaryOp( - bool_id, SpvOpFOrdGreaterThanEqual, ay->result_id(), ax->result_id()); + Instruction* y_gr_x = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + ay->result_id(), ax->result_id()); // Get the value for each case. Instruction* case_z = ir_builder.AddSelect( @@ -783,7 +792,7 @@ bool ReplaceCubeFaceIndex(IRContext* ctx, Instruction* inst, case_y->result_id(), case_x->result_id()); // Get the final result by adding 0.5 to |div|. - inst->SetOpcode(SpvOpSelect); + inst->SetOpcode(spv::Op::OpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_z_max->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {case_z->result_id()}}); @@ -813,11 +822,12 @@ bool ReplaceTimeAMD(IRContext* ctx, Instruction* inst, ctx, inst, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); ctx->AddExtension("SPV_KHR_shader_clock"); - ctx->AddCapability(SpvCapabilityShaderClockKHR); + ctx->AddCapability(spv::Capability::ShaderClockKHR); - inst->SetOpcode(SpvOpReadClockKHR); + inst->SetOpcode(spv::Op::OpReadClockKHR); Instruction::OperandList args; - uint32_t subgroup_scope_id = ir_builder.GetUintConstantId(SpvScopeSubgroup); + uint32_t subgroup_scope_id = + ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); args.push_back({SPV_OPERAND_TYPE_ID, {subgroup_scope_id}}); inst->SetInOperands(std::move(args)); ctx->UpdateDefUse(inst); @@ -831,22 +841,22 @@ class AmdExtFoldingRules : public FoldingRules { protected: virtual void AddFoldingRules() override { - rules_[SpvOpGroupIAddNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupFAddNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupUMinNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupSMinNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupFMinNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupUMaxNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupSMaxNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[SpvOpGroupFMaxNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupIAddNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupFAddNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupUMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupSMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupFMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupUMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupSMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupFMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); uint32_t extension_id = context()->module()->GetExtInstImportId("SPV_AMD_shader_ballot"); @@ -934,7 +944,7 @@ Pass::Status AmdExtensionToKhrPass::Process() { std::vector to_be_killed; for (Instruction& inst : context()->module()->extensions()) { - if (inst.opcode() == SpvOpExtension) { + if (inst.opcode() == spv::Op::OpExtension) { if (ext_to_remove.count(inst.GetInOperand(0).AsString()) != 0) { to_be_killed.push_back(&inst); } @@ -942,7 +952,7 @@ Pass::Status AmdExtensionToKhrPass::Process() { } for (Instruction& inst : context()->ext_inst_imports()) { - if (inst.opcode() == SpvOpExtInstImport) { + if (inst.opcode() == spv::Op::OpExtInstImport) { if (ext_to_remove.count(inst.GetInOperand(0).AsString()) != 0) { to_be_killed.push_back(&inst); } diff --git a/3rdparty/spirv-tools/source/opt/analyze_live_input_pass.cpp b/3rdparty/spirv-tools/source/opt/analyze_live_input_pass.cpp new file mode 100644 index 000000000..529e68467 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/analyze_live_input_pass.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/analyze_live_input_pass.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status AnalyzeLiveInputPass::Process() { + // Current functionality assumes shader capability + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + Pass::Status status = DoLiveInputAnalysis(); + return status; +} + +Pass::Status AnalyzeLiveInputPass::DoLiveInputAnalysis() { + // Current functionality only supports frag, tesc, tese or geom shaders. + // Report failure for any other stage. + auto stage = context()->GetStage(); + if (stage != spv::ExecutionModel::Fragment && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::Geometry) + return Status::Failure; + context()->get_liveness_mgr()->GetLiveness(live_locs_, live_builtins_); + return Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/analyze_live_input_pass.h b/3rdparty/spirv-tools/source/opt/analyze_live_input_pass.h new file mode 100644 index 000000000..ab292effe --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/analyze_live_input_pass.h @@ -0,0 +1,57 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ +#define SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ + +#include + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class AnalyzeLiveInputPass : public Pass { + public: + explicit AnalyzeLiveInputPass(std::unordered_set* live_locs, + std::unordered_set* live_builtins) + : live_locs_(live_locs), live_builtins_(live_builtins) {} + + const char* name() const override { return "analyze-live-input"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Do live input analysis + Status DoLiveInputAnalysis(); + + std::unordered_set* live_locs_; + std::unordered_set* live_builtins_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ diff --git a/3rdparty/spirv-tools/source/opt/basic_block.cpp b/3rdparty/spirv-tools/source/opt/basic_block.cpp index e82a744af..d12178ebe 100644 --- a/3rdparty/spirv-tools/source/opt/basic_block.cpp +++ b/3rdparty/spirv-tools/source/opt/basic_block.cpp @@ -25,11 +25,9 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kLoopMergeContinueBlockIdInIdx = 1; -const uint32_t kLoopMergeMergeBlockIdInIdx = 0; -const uint32_t kSelectionMergeMergeBlockIdInIdx = 0; - +constexpr uint32_t kLoopMergeContinueBlockIdInIdx = 1; +constexpr uint32_t kLoopMergeMergeBlockIdInIdx = 0; +constexpr uint32_t kSelectionMergeMergeBlockIdInIdx = 0; } // namespace BasicBlock* BasicBlock::Clone(IRContext* context) const { @@ -58,7 +56,7 @@ const Instruction* BasicBlock::GetMergeInst() const { if (iter != cbegin()) { --iter; const auto opcode = iter->opcode(); - if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) { + if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) { result = &*iter; } } @@ -73,7 +71,7 @@ Instruction* BasicBlock::GetMergeInst() { if (iter != begin()) { --iter; const auto opcode = iter->opcode(); - if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) { + if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) { result = &*iter; } } @@ -82,7 +80,7 @@ Instruction* BasicBlock::GetMergeInst() { const Instruction* BasicBlock::GetLoopMergeInst() const { if (auto* merge = GetMergeInst()) { - if (merge->opcode() == SpvOpLoopMerge) { + if (merge->opcode() == spv::Op::OpLoopMerge) { return merge; } } @@ -91,7 +89,7 @@ const Instruction* BasicBlock::GetLoopMergeInst() const { Instruction* BasicBlock::GetLoopMergeInst() { if (auto* merge = GetMergeInst()) { - if (merge->opcode() == SpvOpLoopMerge) { + if (merge->opcode() == spv::Op::OpLoopMerge) { return merge; } } @@ -100,7 +98,7 @@ Instruction* BasicBlock::GetLoopMergeInst() { void BasicBlock::KillAllInsts(bool killLabel) { ForEachInst([killLabel](Instruction* ip) { - if (killLabel || ip->opcode() != SpvOpLabel) { + if (killLabel || ip->opcode() != spv::Op::OpLabel) { ip->context()->KillInst(ip); } }); @@ -118,10 +116,10 @@ bool BasicBlock::WhileEachSuccessorLabel( const std::function& f) const { const auto br = &insts_.back(); switch (br->opcode()) { - case SpvOpBranch: + case spv::Op::OpBranch: return f(br->GetOperand(0).words[0]); - case SpvOpBranchConditional: - case SpvOpSwitch: { + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: { bool is_first = true; return br->WhileEachInId([&is_first, &f](const uint32_t* idp) { if (!is_first) return f(*idp); @@ -138,13 +136,13 @@ void BasicBlock::ForEachSuccessorLabel( const std::function& f) { auto br = &insts_.back(); switch (br->opcode()) { - case SpvOpBranch: { + case spv::Op::OpBranch: { uint32_t tmp_id = br->GetOperand(0).words[0]; f(&tmp_id); if (tmp_id != br->GetOperand(0).words[0]) br->SetOperand(0, {tmp_id}); } break; - case SpvOpBranchConditional: - case SpvOpSwitch: { + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: { bool is_first = true; br->ForEachInId([&is_first, &f](uint32_t* idp) { if (!is_first) f(idp); @@ -171,7 +169,8 @@ void BasicBlock::ForMergeAndContinueLabel( --ii; if (ii == insts_.begin()) return; --ii; - if (ii->opcode() == SpvOpSelectionMerge || ii->opcode() == SpvOpLoopMerge) { + if (ii->opcode() == spv::Op::OpSelectionMerge || + ii->opcode() == spv::Op::OpLoopMerge) { ii->ForEachInId([&f](const uint32_t* idp) { f(*idp); }); } } @@ -182,9 +181,9 @@ uint32_t BasicBlock::MergeBlockIdIfAny() const { uint32_t mbid = 0; if (merge_ii != cbegin()) { --merge_ii; - if (merge_ii->opcode() == SpvOpLoopMerge) { + if (merge_ii->opcode() == spv::Op::OpLoopMerge) { mbid = merge_ii->GetSingleWordInOperand(kLoopMergeMergeBlockIdInIdx); - } else if (merge_ii->opcode() == SpvOpSelectionMerge) { + } else if (merge_ii->opcode() == spv::Op::OpSelectionMerge) { mbid = merge_ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); } } @@ -204,7 +203,7 @@ uint32_t BasicBlock::ContinueBlockIdIfAny() const { uint32_t cbid = 0; if (merge_ii != cbegin()) { --merge_ii; - if (merge_ii->opcode() == SpvOpLoopMerge) { + if (merge_ii->opcode() == spv::Op::OpLoopMerge) { cbid = merge_ii->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx); } } @@ -241,9 +240,9 @@ BasicBlock* BasicBlock::SplitBasicBlock(IRContext* context, uint32_t label_id, iterator iter) { assert(!insts_.empty()); - std::unique_ptr new_block_temp = - MakeUnique(MakeUnique( - context, SpvOpLabel, 0, label_id, std::initializer_list{})); + std::unique_ptr new_block_temp = MakeUnique( + MakeUnique(context, spv::Op::OpLabel, 0, label_id, + std::initializer_list{})); BasicBlock* new_block = new_block_temp.get(); function_->InsertBasicBlockAfter(std::move(new_block_temp), this); diff --git a/3rdparty/spirv-tools/source/opt/basic_block.h b/3rdparty/spirv-tools/source/opt/basic_block.h index dd3b2e287..24d5fceb3 100644 --- a/3rdparty/spirv-tools/source/opt/basic_block.h +++ b/3rdparty/spirv-tools/source/opt/basic_block.h @@ -319,7 +319,7 @@ inline bool BasicBlock::WhileEachPhiInst( Instruction* inst = &insts_.front(); while (inst != nullptr) { Instruction* next_instruction = inst->NextNode(); - if (inst->opcode() != SpvOpPhi) break; + if (inst->opcode() != spv::Op::OpPhi) break; if (!inst->WhileEachInst(f, run_on_debug_line_insts)) return false; inst = next_instruction; } diff --git a/3rdparty/spirv-tools/source/opt/block_merge_util.cpp b/3rdparty/spirv-tools/source/opt/block_merge_util.cpp index 83c702ca3..fe23e36f9 100644 --- a/3rdparty/spirv-tools/source/opt/block_merge_util.cpp +++ b/3rdparty/spirv-tools/source/opt/block_merge_util.cpp @@ -20,7 +20,6 @@ namespace spvtools { namespace opt { namespace blockmergeutil { - namespace { // Returns true if |block| contains a merge instruction. @@ -34,14 +33,15 @@ bool IsHeader(IRContext* context, uint32_t id) { // Returns true if |id| is the merge target of a merge instruction. bool IsMerge(IRContext* context, uint32_t id) { - return !context->get_def_use_mgr()->WhileEachUse(id, [](Instruction* user, - uint32_t index) { - SpvOp op = user->opcode(); - if ((op == SpvOpLoopMerge || op == SpvOpSelectionMerge) && index == 0u) { - return false; - } - return true; - }); + return !context->get_def_use_mgr()->WhileEachUse( + id, [](Instruction* user, uint32_t index) { + spv::Op op = user->opcode(); + if ((op == spv::Op::OpLoopMerge || op == spv::Op::OpSelectionMerge) && + index == 0u) { + return false; + } + return true; + }); } // Returns true if |block| is the merge target of a merge instruction. @@ -53,8 +53,8 @@ bool IsMerge(IRContext* context, BasicBlock* block) { bool IsContinue(IRContext* context, uint32_t id) { return !context->get_def_use_mgr()->WhileEachUse( id, [](Instruction* user, uint32_t index) { - SpvOp op = user->opcode(); - if (op == SpvOpLoopMerge && index == 1u) { + spv::Op op = user->opcode(); + if (op == spv::Op::OpLoopMerge && index == 1u) { return false; } return true; @@ -82,7 +82,7 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) { auto ii = block->end(); --ii; Instruction* br = &*ii; - if (br->opcode() != SpvOpBranch) { + if (br->opcode() != spv::Op::OpBranch) { return false; } @@ -119,9 +119,10 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) { // The merge must be a loop merge because a selection merge cannot be // followed by an unconditional branch. BasicBlock* succ_block = context->get_instr_block(lab_id); - SpvOp succ_term_op = succ_block->terminator()->opcode(); - assert(merge_inst->opcode() == SpvOpLoopMerge); - if (succ_term_op != SpvOpBranch && succ_term_op != SpvOpBranchConditional) { + spv::Op succ_term_op = succ_block->terminator()->opcode(); + assert(merge_inst->opcode() == spv::Op::OpLoopMerge); + if (succ_term_op != spv::Op::OpBranch && + succ_term_op != spv::Op::OpBranchConditional) { return false; } } @@ -170,6 +171,11 @@ void MergeWithSuccessor(IRContext* context, Function* func, // sbi must follow bi in func's ordering. assert(sbi != func->end()); + if (sbi->tail()->opcode() == spv::Op::OpSwitch && + sbi->MergeBlockIdIfAny() != 0) { + context->InvalidateAnalyses(IRContext::Analysis::kAnalysisStructuredCFG); + } + // Update the inst-to-block mapping for the instructions in sbi. for (auto& inst : *sbi) { context->set_instr_block(&inst, &*bi); diff --git a/3rdparty/spirv-tools/source/opt/ccp_pass.cpp b/3rdparty/spirv-tools/source/opt/ccp_pass.cpp index 5f8550276..63627a2f7 100644 --- a/3rdparty/spirv-tools/source/opt/ccp_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/ccp_pass.cpp @@ -29,14 +29,11 @@ namespace spvtools { namespace opt { - namespace { - // This SSA id is never defined nor referenced in the IR. It is a special ID // which represents varying values. When an ID is found to have a varying // value, its entry in the |values_| table maps to kVaryingSSAId. -const uint32_t kVaryingSSAId = std::numeric_limits::max(); - +constexpr uint32_t kVaryingSSAId = std::numeric_limits::max(); } // namespace bool CCPPass::IsVaryingValue(uint32_t id) const { return id == kVaryingSSAId; } @@ -136,7 +133,7 @@ SSAPropagator::PropStatus CCPPass::VisitAssignment(Instruction* instr) { // If this is a copy operation, and the RHS is a known constant, assign its // value to the LHS. - if (instr->opcode() == SpvOpCopyObject) { + if (instr->opcode() == spv::Op::OpCopyObject) { uint32_t rhs_id = instr->GetSingleWordInOperand(0); auto it = values_.find(rhs_id); if (it != values_.end()) { @@ -211,10 +208,10 @@ SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, *dest_bb = nullptr; uint32_t dest_label = 0; - if (instr->opcode() == SpvOpBranch) { + if (instr->opcode() == spv::Op::OpBranch) { // An unconditional jump always goes to its unique destination. dest_label = instr->GetSingleWordInOperand(0); - } else if (instr->opcode() == SpvOpBranchConditional) { + } else if (instr->opcode() == spv::Op::OpBranchConditional) { // For a conditional branch, determine whether the predicate selector has a // known value in |values_|. If it does, set the destination block // according to the selector's boolean value. @@ -243,7 +240,7 @@ SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, // For an OpSwitch, extract the value taken by the switch selector and check // which of the target literals it matches. The branch associated with that // literal is the taken branch. - assert(instr->opcode() == SpvOpSwitch); + assert(instr->opcode() == spv::Op::OpSwitch); if (instr->GetOperand(0).words.size() != 1) { // If the selector is wider than 32-bits, return varying. TODO(dnovillo): // Add support for wider constants. @@ -290,7 +287,7 @@ SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, SSAPropagator::PropStatus CCPPass::VisitInstruction(Instruction* instr, BasicBlock** dest_bb) { *dest_bb = nullptr; - if (instr->opcode() == SpvOpPhi) { + if (instr->opcode() == spv::Op::OpPhi) { return VisitPhi(instr); } else if (instr->IsBranch()) { return VisitBranch(instr, dest_bb); diff --git a/3rdparty/spirv-tools/source/opt/cfg.cpp b/3rdparty/spirv-tools/source/opt/cfg.cpp index a0248d54c..4c4bb2568 100644 --- a/3rdparty/spirv-tools/source/opt/cfg.cpp +++ b/3rdparty/spirv-tools/source/opt/cfg.cpp @@ -29,16 +29,16 @@ namespace { using cbb_ptr = const opt::BasicBlock*; // Universal Limit of ResultID + 1 -const int kMaxResultId = 0x400000; +constexpr int kMaxResultId = 0x400000; } // namespace CFG::CFG(Module* module) : module_(module), pseudo_entry_block_(std::unique_ptr( - new Instruction(module->context(), SpvOpLabel, 0, 0, {}))), + new Instruction(module->context(), spv::Op::OpLabel, 0, 0, {}))), pseudo_exit_block_(std::unique_ptr(new Instruction( - module->context(), SpvOpLabel, 0, kMaxResultId, {}))) { + module->context(), spv::Op::OpLabel, 0, kMaxResultId, {}))) { for (auto& fn : *module) { for (auto& blk : fn) { RegisterBlock(&blk); @@ -81,7 +81,7 @@ void CFG::ComputeStructuredOrder(Function* func, BasicBlock* root, BasicBlock* end, std::list* order) { assert(module_->context()->get_feature_mgr()->HasCapability( - SpvCapabilityShader) && + spv::Capability::Shader) && "This only works on structured control flow"); // Compute structured successors and do DFS. @@ -228,7 +228,7 @@ BasicBlock* CFG::SplitLoopHeader(BasicBlock* bb) { // Create the new header bb basic bb. // Leave the phi instructions behind. auto iter = bb->begin(); - while (iter->opcode() == SpvOpPhi) { + while (iter->opcode() == spv::Op::OpPhi) { ++iter; } @@ -304,7 +304,7 @@ BasicBlock* CFG::SplitLoopHeader(BasicBlock* bb) { context, bb, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); bb->AddInstruction( - MakeUnique(context, SpvOpBranch, 0, 0, + MakeUnique(context, spv::Op::OpBranch, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {new_header->id()}}})); context->AnalyzeUses(bb->terminator()); diff --git a/3rdparty/spirv-tools/source/opt/code_sink.cpp b/3rdparty/spirv-tools/source/opt/code_sink.cpp index cd7779747..35a8df23b 100644 --- a/3rdparty/spirv-tools/source/opt/code_sink.cpp +++ b/3rdparty/spirv-tools/source/opt/code_sink.cpp @@ -50,7 +50,8 @@ bool CodeSinkingPass::SinkInstructionsInBB(BasicBlock* bb) { } bool CodeSinkingPass::SinkInstruction(Instruction* inst) { - if (inst->opcode() != SpvOpLoad && inst->opcode() != SpvOpAccessChain) { + if (inst->opcode() != spv::Op::OpLoad && + inst->opcode() != spv::Op::OpAccessChain) { return false; } @@ -60,7 +61,7 @@ bool CodeSinkingPass::SinkInstruction(Instruction* inst) { if (BasicBlock* target_bb = FindNewBasicBlockFor(inst)) { Instruction* pos = &*target_bb->begin(); - while (pos->opcode() == SpvOpPhi) { + while (pos->opcode() == spv::Op::OpPhi) { pos = pos->NextNode(); } @@ -79,7 +80,7 @@ BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { std::unordered_set bbs_with_uses; get_def_use_mgr()->ForEachUse( inst, [&bbs_with_uses, this](Instruction* use, uint32_t idx) { - if (use->opcode() != SpvOpPhi) { + if (use->opcode() != spv::Op::OpPhi) { BasicBlock* use_bb = context()->get_instr_block(use); if (use_bb) { bbs_with_uses.insert(use_bb->id()); @@ -99,7 +100,7 @@ BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { // of succ_bb, then |inst| can be moved to succ_bb. If succ_bb, has move // then one predecessor, then moving |inst| into succ_bb could cause it to // be executed more often, so the search has to stop. - if (bb->terminator()->opcode() == SpvOpBranch) { + if (bb->terminator()->opcode() == spv::Op::OpBranch) { uint32_t succ_bb_id = bb->terminator()->GetSingleWordInOperand(0); if (cfg()->preds(succ_bb_id).size() == 1) { bb = context()->get_instr_block(succ_bb_id); @@ -113,7 +114,8 @@ BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { // instruction or an OpLoopMerge, then it is a break or continue. We could // figure it out, but not worth doing it now. Instruction* merge_inst = bb->GetMergeInst(); - if (merge_inst == nullptr || merge_inst->opcode() != SpvOpSelectionMerge) { + if (merge_inst == nullptr || + merge_inst->opcode() != spv::Op::OpSelectionMerge) { break; } @@ -173,7 +175,7 @@ bool CodeSinkingPass::ReferencesMutableMemory(Instruction* inst) { } Instruction* base_ptr = inst->GetBaseAddress(); - if (base_ptr->opcode() != SpvOpVariable) { + if (base_ptr->opcode() != spv::Op::OpVariable) { return true; } @@ -185,7 +187,8 @@ bool CodeSinkingPass::ReferencesMutableMemory(Instruction* inst) { return true; } - if (base_ptr->GetSingleWordInOperand(0) != SpvStorageClassUniform) { + if (spv::StorageClass(base_ptr->GetSingleWordInOperand(0)) != + spv::StorageClass::Uniform) { return true; } @@ -200,41 +203,41 @@ bool CodeSinkingPass::HasUniformMemorySync() { bool has_sync = false; get_module()->ForEachInst([this, &has_sync](Instruction* inst) { switch (inst->opcode()) { - case SpvOpMemoryBarrier: { + case spv::Op::OpMemoryBarrier: { uint32_t mem_semantics_id = inst->GetSingleWordInOperand(1); if (IsSyncOnUniform(mem_semantics_id)) { has_sync = true; } break; } - case SpvOpControlBarrier: - case SpvOpAtomicLoad: - case SpvOpAtomicStore: - case SpvOpAtomicExchange: - case SpvOpAtomicIIncrement: - case SpvOpAtomicIDecrement: - case SpvOpAtomicIAdd: - case SpvOpAtomicFAddEXT: - case SpvOpAtomicISub: - case SpvOpAtomicSMin: - case SpvOpAtomicUMin: - case SpvOpAtomicFMinEXT: - case SpvOpAtomicSMax: - case SpvOpAtomicUMax: - case SpvOpAtomicFMaxEXT: - case SpvOpAtomicAnd: - case SpvOpAtomicOr: - case SpvOpAtomicXor: - case SpvOpAtomicFlagTestAndSet: - case SpvOpAtomicFlagClear: { + case spv::Op::OpControlBarrier: + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicStore: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicFMaxEXT: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: + case spv::Op::OpAtomicFlagClear: { uint32_t mem_semantics_id = inst->GetSingleWordInOperand(2); if (IsSyncOnUniform(mem_semantics_id)) { has_sync = true; } break; } - case SpvOpAtomicCompareExchange: - case SpvOpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: if (IsSyncOnUniform(inst->GetSingleWordInOperand(2)) || IsSyncOnUniform(inst->GetSingleWordInOperand(3))) { has_sync = true; @@ -259,28 +262,30 @@ bool CodeSinkingPass::IsSyncOnUniform(uint32_t mem_semantics_id) const { // If it does not affect uniform memory, then it is does not apply to uniform // memory. - if ((mem_semantics_int & SpvMemorySemanticsUniformMemoryMask) == 0) { + if ((mem_semantics_int & uint32_t(spv::MemorySemanticsMask::UniformMemory)) == + 0) { return false; } // Check if there is an acquire or release. If so not, this it does not add // any memory constraints. - return (mem_semantics_int & (SpvMemorySemanticsAcquireMask | - SpvMemorySemanticsAcquireReleaseMask | - SpvMemorySemanticsReleaseMask)) != 0; + return (mem_semantics_int & + uint32_t(spv::MemorySemanticsMask::Acquire | + spv::MemorySemanticsMask::AcquireRelease | + spv::MemorySemanticsMask::Release)) != 0; } bool CodeSinkingPass::HasPossibleStore(Instruction* var_inst) { - assert(var_inst->opcode() == SpvOpVariable || - var_inst->opcode() == SpvOpAccessChain || - var_inst->opcode() == SpvOpPtrAccessChain); + assert(var_inst->opcode() == spv::Op::OpVariable || + var_inst->opcode() == spv::Op::OpAccessChain || + var_inst->opcode() == spv::Op::OpPtrAccessChain); return get_def_use_mgr()->WhileEachUser(var_inst, [this](Instruction* use) { switch (use->opcode()) { - case SpvOpStore: + case spv::Op::OpStore: return true; - case SpvOpAccessChain: - case SpvOpPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpPtrAccessChain: return HasPossibleStore(use); default: return false; diff --git a/3rdparty/spirv-tools/source/opt/combine_access_chains.cpp b/3rdparty/spirv-tools/source/opt/combine_access_chains.cpp index 142897a2e..99ec79625 100644 --- a/3rdparty/spirv-tools/source/opt/combine_access_chains.cpp +++ b/3rdparty/spirv-tools/source/opt/combine_access_chains.cpp @@ -44,10 +44,10 @@ bool CombineAccessChains::ProcessFunction(Function& function) { function.entry().get(), [&modified, this](BasicBlock* block) { block->ForEachInst([&modified, this](Instruction* inst) { switch (inst->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: modified |= CombineAccessChain(inst); break; default: @@ -76,10 +76,10 @@ uint32_t CombineAccessChains::GetConstantValue( uint32_t CombineAccessChains::GetArrayStride(const Instruction* inst) { uint32_t array_stride = 0; context()->get_decoration_mgr()->WhileEachDecoration( - inst->type_id(), SpvDecorationArrayStride, + inst->type_id(), uint32_t(spv::Decoration::ArrayStride), [&array_stride](const Instruction& decoration) { - assert(decoration.opcode() != SpvOpDecorateId); - if (decoration.opcode() == SpvOpDecorate) { + assert(decoration.opcode() != spv::Op::OpDecorateId); + if (decoration.opcode() == spv::Op::OpDecorate) { array_stride = decoration.GetSingleWordInOperand(1); } else { array_stride = decoration.GetSingleWordInOperand(2); @@ -200,18 +200,18 @@ bool CombineAccessChains::CreateNewInputOperands( } bool CombineAccessChains::CombineAccessChain(Instruction* inst) { - assert((inst->opcode() == SpvOpPtrAccessChain || - inst->opcode() == SpvOpAccessChain || - inst->opcode() == SpvOpInBoundsAccessChain || - inst->opcode() == SpvOpInBoundsPtrAccessChain) && + assert((inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) && "Wrong opcode. Expected an access chain."); Instruction* ptr_input = context()->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0)); - if (ptr_input->opcode() != SpvOpAccessChain && - ptr_input->opcode() != SpvOpInBoundsAccessChain && - ptr_input->opcode() != SpvOpPtrAccessChain && - ptr_input->opcode() != SpvOpInBoundsPtrAccessChain) { + if (ptr_input->opcode() != spv::Op::OpAccessChain && + ptr_input->opcode() != spv::Op::OpInBoundsAccessChain && + ptr_input->opcode() != spv::Op::OpPtrAccessChain && + ptr_input->opcode() != spv::Op::OpInBoundsPtrAccessChain) { return false; } @@ -246,7 +246,7 @@ bool CombineAccessChains::CombineAccessChain(Instruction* inst) { } else if (inst->NumInOperands() == 1) { // |inst| is a no-op, change it to a copy. Instruction simplification will // clean it up. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); } else { std::vector new_operands; if (!CreateNewInputOperands(ptr_input, inst, &new_operands)) return false; @@ -259,23 +259,25 @@ bool CombineAccessChains::CombineAccessChain(Instruction* inst) { return true; } -SpvOp CombineAccessChains::UpdateOpcode(SpvOp base_opcode, SpvOp input_opcode) { - auto IsInBounds = [](SpvOp opcode) { - return opcode == SpvOpInBoundsPtrAccessChain || - opcode == SpvOpInBoundsAccessChain; +spv::Op CombineAccessChains::UpdateOpcode(spv::Op base_opcode, + spv::Op input_opcode) { + auto IsInBounds = [](spv::Op opcode) { + return opcode == spv::Op::OpInBoundsPtrAccessChain || + opcode == spv::Op::OpInBoundsAccessChain; }; - if (input_opcode == SpvOpInBoundsPtrAccessChain) { - if (!IsInBounds(base_opcode)) return SpvOpPtrAccessChain; - } else if (input_opcode == SpvOpInBoundsAccessChain) { - if (!IsInBounds(base_opcode)) return SpvOpAccessChain; + if (input_opcode == spv::Op::OpInBoundsPtrAccessChain) { + if (!IsInBounds(base_opcode)) return spv::Op::OpPtrAccessChain; + } else if (input_opcode == spv::Op::OpInBoundsAccessChain) { + if (!IsInBounds(base_opcode)) return spv::Op::OpAccessChain; } return input_opcode; } -bool CombineAccessChains::IsPtrAccessChain(SpvOp opcode) { - return opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain; +bool CombineAccessChains::IsPtrAccessChain(spv::Op opcode) { + return opcode == spv::Op::OpPtrAccessChain || + opcode == spv::Op::OpInBoundsPtrAccessChain; } bool CombineAccessChains::Has64BitIndices(Instruction* inst) { diff --git a/3rdparty/spirv-tools/source/opt/combine_access_chains.h b/3rdparty/spirv-tools/source/opt/combine_access_chains.h index 531209ec1..32ee50d30 100644 --- a/3rdparty/spirv-tools/source/opt/combine_access_chains.h +++ b/3rdparty/spirv-tools/source/opt/combine_access_chains.h @@ -68,10 +68,10 @@ class CombineAccessChains : public Pass { std::vector* new_operands); // Returns the opcode to use for the combined access chain. - SpvOp UpdateOpcode(SpvOp base_opcode, SpvOp input_opcode); + spv::Op UpdateOpcode(spv::Op base_opcode, spv::Op input_opcode); // Returns true if |opcode| is a pointer access chain. - bool IsPtrAccessChain(SpvOp opcode); + bool IsPtrAccessChain(spv::Op opcode); // Returns true if |inst| (an access chain) has 64-bit indices. bool Has64BitIndices(Instruction* inst); diff --git a/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp b/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp index 0ad755c94..14f22089b 100644 --- a/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp +++ b/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp @@ -19,8 +19,7 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kExtractCompositeIdInIdx = 0; // Returns a constants with the value NaN of the given type. Only works for // 32-bit and 64-bit float point types. Returns |nullptr| if an error occurs. @@ -120,11 +119,97 @@ ConstantFoldingRule FoldExtractWithConstants() { }; } +// Folds an OpcompositeInsert where input is a composite constant. +ConstantFoldingRule FoldInsertWithConstants() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Constant* object = constants[0]; + const analysis::Constant* composite = constants[1]; + if (object == nullptr || composite == nullptr) { + return nullptr; + } + + // If there is more than 1 index, then each additional constant used by the + // index will need to be recreated to use the inserted object. + std::vector chain; + std::vector components; + const analysis::Type* type = nullptr; + const uint32_t final_index = (inst->NumInOperands() - 1); + + // Work down hierarchy of all indexes + for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { + type = composite->type(); + + if (composite->AsNullConstant()) { + // Make new composite so it can be inserted in the index with the + // non-null value + const auto new_composite = const_mgr->GetNullCompositeConstant(type); + // Keep track of any indexes along the way to last index + if (i != final_index) { + chain.push_back(new_composite); + } + components = new_composite->AsCompositeConstant()->GetComponents(); + } else { + // Keep track of any indexes along the way to last index + if (i != final_index) { + chain.push_back(composite); + } + components = composite->AsCompositeConstant()->GetComponents(); + } + const uint32_t index = inst->GetSingleWordInOperand(i); + composite = components[index]; + } + + // Final index in hierarchy is inserted with new object. + const uint32_t final_operand = inst->GetSingleWordInOperand(final_index); + std::vector ids; + for (size_t i = 0; i < components.size(); i++) { + const analysis::Constant* constant = + (i == final_operand) ? object : components[i]; + Instruction* member_inst = const_mgr->GetDefiningInstruction(constant); + ids.push_back(member_inst->result_id()); + } + const analysis::Constant* new_constant = const_mgr->GetConstant(type, ids); + + // Work backwards up the chain and replace each index with new constant. + for (size_t i = chain.size(); i > 0; i--) { + // Need to insert any previous instruction into the module first. + // Can't just insert in types_values_begin() because it will move above + // where the types are declared. + // Can't compare with location of inst because not all new added + // instructions are added to types_values_ + auto iter = context->types_values_end(); + Module::inst_iterator* pos = &iter; + const_mgr->BuildInstructionAndAddToModule(new_constant, pos); + + composite = chain[i - 1]; + components = composite->AsCompositeConstant()->GetComponents(); + type = composite->type(); + ids.clear(); + for (size_t k = 0; k < components.size(); k++) { + const uint32_t index = + inst->GetSingleWordInOperand(1 + static_cast(i)); + const analysis::Constant* constant = + (k == index) ? new_constant : components[k]; + const uint32_t constant_id = + const_mgr->FindDeclaredConstant(constant, 0); + ids.push_back(constant_id); + } + new_constant = const_mgr->GetConstant(type, ids); + } + + // If multiple constants were created, only need to return the top index. + return new_constant; + }; +} + ConstantFoldingRule FoldVectorShuffleWithConstants() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == SpvOpVectorShuffle); + assert(inst->opcode() == spv::Op::OpVectorShuffle); const analysis::Constant* c1 = constants[0]; const analysis::Constant* c2 = constants[1]; if (c1 == nullptr || c2 == nullptr) { @@ -180,7 +265,7 @@ ConstantFoldingRule FoldVectorTimesScalar() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == SpvOpVectorTimesScalar); + assert(inst->opcode() == spv::Op::OpVectorTimesScalar); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -255,7 +340,7 @@ ConstantFoldingRule FoldVectorTimesMatrix() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == SpvOpVectorTimesMatrix); + assert(inst->opcode() == spv::Op::OpVectorTimesMatrix); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -348,7 +433,7 @@ ConstantFoldingRule FoldMatrixTimesVector() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == SpvOpMatrixTimesVector); + assert(inst->opcode() == spv::Op::OpMatrixTimesVector); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -458,9 +543,9 @@ ConstantFoldingRule FoldCompositeWithConstants() { } uint32_t component_type_id = 0; - if (type_inst->opcode() == SpvOpTypeStruct) { + if (type_inst->opcode() == spv::Op::OpTypeStruct) { component_type_id = type_inst->GetSingleWordInOperand(i); - } else if (type_inst->opcode() == SpvOpTypeArray) { + } else if (type_inst->opcode() == spv::Op::OpTypeArray) { component_type_id = type_inst->GetSingleWordInOperand(0); } @@ -509,7 +594,7 @@ ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) { } const analysis::Constant* arg = - (inst->opcode() == SpvOpExtInst) ? constants[1] : constants[0]; + (inst->opcode() == spv::Op::OpExtInst) ? constants[1] : constants[0]; if (arg == nullptr) { return nullptr; @@ -599,7 +684,7 @@ ConstantFoldingRule FoldFPBinaryOp(BinaryScalarFoldingRule scalar_rule) { if (!inst->IsFloatingPointFoldingAllowed()) { return nullptr; } - if (inst->opcode() == SpvOpExtInst) { + if (inst->opcode() == spv::Op::OpExtInst) { return FoldFPBinaryOp(scalar_rule, inst->type_id(), {constants[1], constants[2]}, context); } @@ -957,7 +1042,7 @@ UnaryScalarFoldingRule FoldFNegateOp() { ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(FoldFNegateOp()); } -ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { +ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { return [cmp_opcode](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { @@ -985,7 +1070,7 @@ ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { return nullptr; } - if (operand_inst->opcode() != SpvOpExtInst) { + if (operand_inst->opcode() != spv::Op::OpExtInst) { return nullptr; } @@ -1009,25 +1094,25 @@ ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { bool result = false; switch (cmp_opcode) { - case SpvOpFOrdLessThan: - case SpvOpFUnordLessThan: - case SpvOpFOrdGreaterThanEqual: - case SpvOpFUnordGreaterThanEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: if (constants[0]) { if (min_const) { if (constants[0]->GetValueAsDouble() < min_const->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == SpvOpFOrdLessThan || - cmp_opcode == SpvOpFUnordLessThan); + result = (cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); } } if (max_const) { if (constants[0]->GetValueAsDouble() >= max_const->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == SpvOpFOrdLessThan || - cmp_opcode == SpvOpFUnordLessThan); + result = !(cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); } } } @@ -1037,8 +1122,8 @@ ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { if (max_const->GetValueAsDouble() < constants[1]->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == SpvOpFOrdLessThan || - cmp_opcode == SpvOpFUnordLessThan); + result = (cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); } } @@ -1046,31 +1131,31 @@ ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { if (min_const->GetValueAsDouble() >= constants[1]->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == SpvOpFOrdLessThan || - cmp_opcode == SpvOpFUnordLessThan); + result = !(cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); } } } break; - case SpvOpFOrdGreaterThan: - case SpvOpFUnordGreaterThan: - case SpvOpFOrdLessThanEqual: - case SpvOpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: if (constants[0]) { if (min_const) { if (constants[0]->GetValueAsDouble() <= min_const->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == SpvOpFOrdLessThanEqual || - cmp_opcode == SpvOpFUnordLessThanEqual); + result = (cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); } } if (max_const) { if (constants[0]->GetValueAsDouble() > max_const->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == SpvOpFOrdLessThanEqual || - cmp_opcode == SpvOpFUnordLessThanEqual); + result = !(cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); } } } @@ -1080,8 +1165,8 @@ ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { if (max_const->GetValueAsDouble() <= constants[1]->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == SpvOpFOrdLessThanEqual || - cmp_opcode == SpvOpFUnordLessThanEqual); + result = (cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); } } @@ -1089,8 +1174,8 @@ ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { if (min_const->GetValueAsDouble() > constants[1]->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == SpvOpFOrdLessThanEqual || - cmp_opcode == SpvOpFUnordLessThanEqual); + result = !(cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); } } } @@ -1117,7 +1202,7 @@ ConstantFoldingRule FoldFMix() { const std::vector& constants) -> const analysis::Constant* { analysis::ConstantManager* const_mgr = context->get_constant_mgr(); - assert(inst->opcode() == SpvOpExtInst && + assert(inst->opcode() == spv::Op::OpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1267,7 +1352,7 @@ const analysis::Constant* FoldMax(const analysis::Type* result_type, const analysis::Constant* FoldClamp1( IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpExtInst && + assert(inst->opcode() == spv::Op::OpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1293,7 +1378,7 @@ const analysis::Constant* FoldClamp1( const analysis::Constant* FoldClamp2( IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpExtInst && + assert(inst->opcode() == spv::Op::OpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1321,7 +1406,7 @@ const analysis::Constant* FoldClamp2( const analysis::Constant* FoldClamp3( IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpExtInst && + assert(inst->opcode() == spv::Op::OpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1407,68 +1492,70 @@ void ConstantFoldingRules::AddFoldingRules() { // applies to the instruction, the rest of the rules will not be attempted. // Take that into consideration. - rules_[SpvOpCompositeConstruct].push_back(FoldCompositeWithConstants()); + rules_[spv::Op::OpCompositeConstruct].push_back(FoldCompositeWithConstants()); - rules_[SpvOpCompositeExtract].push_back(FoldExtractWithConstants()); + rules_[spv::Op::OpCompositeExtract].push_back(FoldExtractWithConstants()); + rules_[spv::Op::OpCompositeInsert].push_back(FoldInsertWithConstants()); - rules_[SpvOpConvertFToS].push_back(FoldFToI()); - rules_[SpvOpConvertFToU].push_back(FoldFToI()); - rules_[SpvOpConvertSToF].push_back(FoldIToF()); - rules_[SpvOpConvertUToF].push_back(FoldIToF()); + rules_[spv::Op::OpConvertFToS].push_back(FoldFToI()); + rules_[spv::Op::OpConvertFToU].push_back(FoldFToI()); + rules_[spv::Op::OpConvertSToF].push_back(FoldIToF()); + rules_[spv::Op::OpConvertUToF].push_back(FoldIToF()); - rules_[SpvOpDot].push_back(FoldOpDotWithConstants()); - rules_[SpvOpFAdd].push_back(FoldFAdd()); - rules_[SpvOpFDiv].push_back(FoldFDiv()); - rules_[SpvOpFMul].push_back(FoldFMul()); - rules_[SpvOpFSub].push_back(FoldFSub()); + rules_[spv::Op::OpDot].push_back(FoldOpDotWithConstants()); + rules_[spv::Op::OpFAdd].push_back(FoldFAdd()); + rules_[spv::Op::OpFDiv].push_back(FoldFDiv()); + rules_[spv::Op::OpFMul].push_back(FoldFMul()); + rules_[spv::Op::OpFSub].push_back(FoldFSub()); - rules_[SpvOpFOrdEqual].push_back(FoldFOrdEqual()); + rules_[spv::Op::OpFOrdEqual].push_back(FoldFOrdEqual()); - rules_[SpvOpFUnordEqual].push_back(FoldFUnordEqual()); + rules_[spv::Op::OpFUnordEqual].push_back(FoldFUnordEqual()); - rules_[SpvOpFOrdNotEqual].push_back(FoldFOrdNotEqual()); + rules_[spv::Op::OpFOrdNotEqual].push_back(FoldFOrdNotEqual()); - rules_[SpvOpFUnordNotEqual].push_back(FoldFUnordNotEqual()); + rules_[spv::Op::OpFUnordNotEqual].push_back(FoldFUnordNotEqual()); - rules_[SpvOpFOrdLessThan].push_back(FoldFOrdLessThan()); - rules_[SpvOpFOrdLessThan].push_back( - FoldFClampFeedingCompare(SpvOpFOrdLessThan)); + rules_[spv::Op::OpFOrdLessThan].push_back(FoldFOrdLessThan()); + rules_[spv::Op::OpFOrdLessThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdLessThan)); - rules_[SpvOpFUnordLessThan].push_back(FoldFUnordLessThan()); - rules_[SpvOpFUnordLessThan].push_back( - FoldFClampFeedingCompare(SpvOpFUnordLessThan)); + rules_[spv::Op::OpFUnordLessThan].push_back(FoldFUnordLessThan()); + rules_[spv::Op::OpFUnordLessThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordLessThan)); - rules_[SpvOpFOrdGreaterThan].push_back(FoldFOrdGreaterThan()); - rules_[SpvOpFOrdGreaterThan].push_back( - FoldFClampFeedingCompare(SpvOpFOrdGreaterThan)); + rules_[spv::Op::OpFOrdGreaterThan].push_back(FoldFOrdGreaterThan()); + rules_[spv::Op::OpFOrdGreaterThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdGreaterThan)); - rules_[SpvOpFUnordGreaterThan].push_back(FoldFUnordGreaterThan()); - rules_[SpvOpFUnordGreaterThan].push_back( - FoldFClampFeedingCompare(SpvOpFUnordGreaterThan)); + rules_[spv::Op::OpFUnordGreaterThan].push_back(FoldFUnordGreaterThan()); + rules_[spv::Op::OpFUnordGreaterThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordGreaterThan)); - rules_[SpvOpFOrdLessThanEqual].push_back(FoldFOrdLessThanEqual()); - rules_[SpvOpFOrdLessThanEqual].push_back( - FoldFClampFeedingCompare(SpvOpFOrdLessThanEqual)); + rules_[spv::Op::OpFOrdLessThanEqual].push_back(FoldFOrdLessThanEqual()); + rules_[spv::Op::OpFOrdLessThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdLessThanEqual)); - rules_[SpvOpFUnordLessThanEqual].push_back(FoldFUnordLessThanEqual()); - rules_[SpvOpFUnordLessThanEqual].push_back( - FoldFClampFeedingCompare(SpvOpFUnordLessThanEqual)); + rules_[spv::Op::OpFUnordLessThanEqual].push_back(FoldFUnordLessThanEqual()); + rules_[spv::Op::OpFUnordLessThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordLessThanEqual)); - rules_[SpvOpFOrdGreaterThanEqual].push_back(FoldFOrdGreaterThanEqual()); - rules_[SpvOpFOrdGreaterThanEqual].push_back( - FoldFClampFeedingCompare(SpvOpFOrdGreaterThanEqual)); + rules_[spv::Op::OpFOrdGreaterThanEqual].push_back(FoldFOrdGreaterThanEqual()); + rules_[spv::Op::OpFOrdGreaterThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdGreaterThanEqual)); - rules_[SpvOpFUnordGreaterThanEqual].push_back(FoldFUnordGreaterThanEqual()); - rules_[SpvOpFUnordGreaterThanEqual].push_back( - FoldFClampFeedingCompare(SpvOpFUnordGreaterThanEqual)); + rules_[spv::Op::OpFUnordGreaterThanEqual].push_back( + FoldFUnordGreaterThanEqual()); + rules_[spv::Op::OpFUnordGreaterThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordGreaterThanEqual)); - rules_[SpvOpVectorShuffle].push_back(FoldVectorShuffleWithConstants()); - rules_[SpvOpVectorTimesScalar].push_back(FoldVectorTimesScalar()); - rules_[SpvOpVectorTimesMatrix].push_back(FoldVectorTimesMatrix()); - rules_[SpvOpMatrixTimesVector].push_back(FoldMatrixTimesVector()); + rules_[spv::Op::OpVectorShuffle].push_back(FoldVectorShuffleWithConstants()); + rules_[spv::Op::OpVectorTimesScalar].push_back(FoldVectorTimesScalar()); + rules_[spv::Op::OpVectorTimesMatrix].push_back(FoldVectorTimesMatrix()); + rules_[spv::Op::OpMatrixTimesVector].push_back(FoldMatrixTimesVector()); - rules_[SpvOpFNegate].push_back(FoldFNegate()); - rules_[SpvOpQuantizeToF16].push_back(FoldQuantizeToF16()); + rules_[spv::Op::OpFNegate].push_back(FoldFNegate()); + rules_[spv::Op::OpQuantizeToF16].push_back(FoldQuantizeToF16()); // Add rules for GLSLstd450 FeatureManager* feature_manager = context_->get_feature_mgr(); diff --git a/3rdparty/spirv-tools/source/opt/const_folding_rules.h b/3rdparty/spirv-tools/source/opt/const_folding_rules.h index 41ee2aa22..fa345321f 100644 --- a/3rdparty/spirv-tools/source/opt/const_folding_rules.h +++ b/3rdparty/spirv-tools/source/opt/const_folding_rules.h @@ -88,7 +88,7 @@ class ConstantFoldingRules { // Returns true if there is at least 1 folding rule for |inst|. const std::vector& GetRulesForInstruction( const Instruction* inst) const { - if (inst->opcode() != SpvOpExtInst) { + if (inst->opcode() != spv::Op::OpExtInst) { auto it = rules_.find(inst->opcode()); if (it != rules_.end()) { return it->second.value; @@ -108,9 +108,15 @@ class ConstantFoldingRules { virtual void AddFoldingRules(); protected: + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + // |rules[opcode]| is the set of rules that can be applied to instructions // with |opcode| as the opcode. - std::unordered_map rules_; + std::unordered_map rules_; // The folding rules for extended instructions. std::map ext_rules_; diff --git a/3rdparty/spirv-tools/source/opt/constants.cpp b/3rdparty/spirv-tools/source/opt/constants.cpp index bcff08c13..d70e27bb2 100644 --- a/3rdparty/spirv-tools/source/opt/constants.cpp +++ b/3rdparty/spirv-tools/source/opt/constants.cpp @@ -306,16 +306,16 @@ const Constant* ConstantManager::GetConstantFromInst(const Instruction* inst) { switch (inst->opcode()) { // OpConstant{True|False} have the value embedded in the opcode. So they // are not handled by the for-loop above. Here we add the value explicitly. - case SpvOp::SpvOpConstantTrue: + case spv::Op::OpConstantTrue: literal_words_or_ids.push_back(true); break; - case SpvOp::SpvOpConstantFalse: + case spv::Op::OpConstantFalse: literal_words_or_ids.push_back(false); break; - case SpvOp::SpvOpConstantNull: - case SpvOp::SpvOpConstant: - case SpvOp::SpvOpConstantComposite: - case SpvOp::SpvOpSpecConstantComposite: + case spv::Op::OpConstantNull: + case spv::Op::OpConstant: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: break; default: return nullptr; @@ -329,22 +329,22 @@ std::unique_ptr ConstantManager::CreateInstruction( uint32_t type = (type_id == 0) ? context()->get_type_mgr()->GetId(c->type()) : type_id; if (c->AsNullConstant()) { - return MakeUnique(context(), SpvOp::SpvOpConstantNull, type, - id, std::initializer_list{}); + return MakeUnique(context(), spv::Op::OpConstantNull, type, id, + std::initializer_list{}); } else if (const BoolConstant* bc = c->AsBoolConstant()) { return MakeUnique( context(), - bc->value() ? SpvOp::SpvOpConstantTrue : SpvOp::SpvOpConstantFalse, - type, id, std::initializer_list{}); + bc->value() ? spv::Op::OpConstantTrue : spv::Op::OpConstantFalse, type, + id, std::initializer_list{}); } else if (const IntConstant* ic = c->AsIntConstant()) { return MakeUnique( - context(), SpvOp::SpvOpConstant, type, id, + context(), spv::Op::OpConstant, type, id, std::initializer_list{ Operand(spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, ic->words())}); } else if (const FloatConstant* fc = c->AsFloatConstant()) { return MakeUnique( - context(), SpvOp::SpvOpConstant, type, id, + context(), spv::Op::OpConstant, type, id, std::initializer_list{ Operand(spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, fc->words())}); @@ -362,9 +362,9 @@ std::unique_ptr ConstantManager::CreateCompositeInstruction( uint32_t component_index = 0; for (const Constant* component_const : cc->GetComponents()) { uint32_t component_type_id = 0; - if (type_inst && type_inst->opcode() == SpvOpTypeStruct) { + if (type_inst && type_inst->opcode() == spv::Op::OpTypeStruct) { component_type_id = type_inst->GetSingleWordInOperand(component_index); - } else if (type_inst && type_inst->opcode() == SpvOpTypeArray) { + } else if (type_inst && type_inst->opcode() == spv::Op::OpTypeArray) { component_type_id = type_inst->GetSingleWordInOperand(0); } uint32_t id = FindDeclaredConstant(component_const, component_type_id); @@ -381,7 +381,7 @@ std::unique_ptr ConstantManager::CreateCompositeInstruction( } uint32_t type = (type_id == 0) ? context()->get_type_mgr()->GetId(cc->type()) : type_id; - return MakeUnique(context(), SpvOp::SpvOpConstantComposite, type, + return MakeUnique(context(), spv::Op::OpConstantComposite, type, result_id, std::move(operands)); } @@ -391,6 +391,43 @@ const Constant* ConstantManager::GetConstant( return cst ? RegisterConstant(std::move(cst)) : nullptr; } +const Constant* ConstantManager::GetNullCompositeConstant(const Type* type) { + std::vector literal_words_or_id; + + if (type->AsVector()) { + const Type* element_type = type->AsVector()->element_type(); + const uint32_t null_id = GetNullConstId(element_type); + const uint32_t element_count = type->AsVector()->element_count(); + for (uint32_t i = 0; i < element_count; i++) { + literal_words_or_id.push_back(null_id); + } + } else if (type->AsMatrix()) { + const Type* element_type = type->AsMatrix()->element_type(); + const uint32_t null_id = GetNullConstId(element_type); + const uint32_t element_count = type->AsMatrix()->element_count(); + for (uint32_t i = 0; i < element_count; i++) { + literal_words_or_id.push_back(null_id); + } + } else if (type->AsStruct()) { + // TODO (sfricke-lunarg) add proper struct support + return nullptr; + } else if (type->AsArray()) { + const Type* element_type = type->AsArray()->element_type(); + const uint32_t null_id = GetNullConstId(element_type); + assert(type->AsArray()->length_info().words[0] == + analysis::Array::LengthInfo::kConstant && + "unexpected array length"); + const uint32_t element_count = type->AsArray()->length_info().words[0]; + for (uint32_t i = 0; i < element_count; i++) { + literal_words_or_id.push_back(null_id); + } + } else { + return nullptr; + } + + return GetConstant(type, literal_words_or_id); +} + const Constant* ConstantManager::GetNumericVectorConstantWithWords( const Vector* type, const std::vector& literal_words) { const auto* element_type = type->element_type(); @@ -445,18 +482,23 @@ const Constant* ConstantManager::GetDoubleConst(double val) { return c; } -uint32_t ConstantManager::GetSIntConst(int32_t val) { +uint32_t ConstantManager::GetSIntConstId(int32_t val) { Type* sint_type = context()->get_type_mgr()->GetSIntType(); const Constant* c = GetConstant(sint_type, {static_cast(val)}); return GetDefiningInstruction(c)->result_id(); } -uint32_t ConstantManager::GetUIntConst(uint32_t val) { +uint32_t ConstantManager::GetUIntConstId(uint32_t val) { Type* uint_type = context()->get_type_mgr()->GetUIntType(); const Constant* c = GetConstant(uint_type, {val}); return GetDefiningInstruction(c)->result_id(); } +uint32_t ConstantManager::GetNullConstId(const Type* type) { + const Constant* c = GetConstant(type, {}); + return GetDefiningInstruction(c)->result_id(); +} + std::vector Constant::GetVectorComponents( analysis::ConstantManager* const_mgr) const { std::vector components; diff --git a/3rdparty/spirv-tools/source/opt/constants.h b/3rdparty/spirv-tools/source/opt/constants.h index 620991efa..6b123bd92 100644 --- a/3rdparty/spirv-tools/source/opt/constants.h +++ b/3rdparty/spirv-tools/source/opt/constants.h @@ -520,6 +520,14 @@ class ConstantManager { literal_words_or_ids.end())); } + // Takes a type and creates a OpConstantComposite + // This allows a + // OpConstantNull %composite_type + // to become a + // OpConstantComposite %composite_type %null %null ... etc + // Assumes type is a Composite already, otherwise returns null + const Constant* GetNullCompositeConstant(const Type* type); + // Gets or creates a unique Constant instance of Vector type |type| with // numeric elements and a vector of constant defining words |literal_words|. // If a Constant instance existed already in the constant pool, it returns a @@ -649,10 +657,13 @@ class ConstantManager { const Constant* GetDoubleConst(double val); // Returns the id of a 32-bit signed integer constant with value |val|. - uint32_t GetSIntConst(int32_t val); + uint32_t GetSIntConstId(int32_t val); // Returns the id of a 32-bit unsigned integer constant with value |val|. - uint32_t GetUIntConst(uint32_t val); + uint32_t GetUIntConstId(uint32_t val); + + // Returns the id of a OpConstantNull with type of |type|. + uint32_t GetNullConstId(const Type* type); private: // Creates a Constant instance with the given type and a vector of constant diff --git a/3rdparty/spirv-tools/source/opt/control_dependence.cpp b/3rdparty/spirv-tools/source/opt/control_dependence.cpp index f4879e0f3..a153cabfc 100644 --- a/3rdparty/spirv-tools/source/opt/control_dependence.cpp +++ b/3rdparty/spirv-tools/source/opt/control_dependence.cpp @@ -24,7 +24,6 @@ #include "source/opt/dominator_analysis.h" #include "source/opt/function.h" #include "source/opt/instruction.h" -#include "spirv/unified1/spirv.h" // Computes the control dependence graph (CDG) using the algorithm in Cytron // 1991, "Efficiently Computing Static Single Assignment Form and the Control @@ -49,8 +48,8 @@ uint32_t ControlDependence::GetConditionID(const CFG& cfg) const { } const BasicBlock* source_bb = cfg.block(source_bb_id()); const Instruction* branch = source_bb->terminator(); - assert((branch->opcode() == SpvOpBranchConditional || - branch->opcode() == SpvOpSwitch) && + assert((branch->opcode() == spv::Op::OpBranchConditional || + branch->opcode() == spv::Op::OpSwitch) && "invalid control dependence; last instruction must be conditional " "branch or switch"); return branch->GetSingleWordInOperand(0); diff --git a/3rdparty/spirv-tools/source/opt/convert_to_half_pass.cpp b/3rdparty/spirv-tools/source/opt/convert_to_half_pass.cpp index 4086e31ac..7a4c1f409 100644 --- a/3rdparty/spirv-tools/source/opt/convert_to_half_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/convert_to_half_pass.cpp @@ -18,19 +18,16 @@ #include "source/opt/ir_builder.h" -namespace { - -// Indices of operands in SPIR-V instructions -static const int kImageSampleDrefIdInIdx = 2; - -} // anonymous namespace - namespace spvtools { namespace opt { +namespace { +// Indices of operands in SPIR-V instructions +constexpr int kImageSampleDrefIdInIdx = 2; +} // namespace bool ConvertToHalfPass::IsArithmetic(Instruction* inst) { return target_ops_core_.count(inst->opcode()) != 0 || - (inst->opcode() == SpvOpExtInst && + (inst->opcode() == spv::Op::OpExtInst && inst->GetSingleWordInOperand(0) == context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && target_ops_450_.count(inst->GetSingleWordInOperand(1)) != 0); @@ -45,9 +42,11 @@ bool ConvertToHalfPass::IsFloat(Instruction* inst, uint32_t width) { bool ConvertToHalfPass::IsDecoratedRelaxed(Instruction* inst) { uint32_t r_id = inst->result_id(); for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false)) - if (r_inst->opcode() == SpvOpDecorate && - r_inst->GetSingleWordInOperand(1) == SpvDecorationRelaxedPrecision) + if (r_inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(r_inst->GetSingleWordInOperand(1)) == + spv::Decoration::RelaxedPrecision) { return true; + } return false; } @@ -82,12 +81,12 @@ analysis::Type* ConvertToHalfPass::FloatMatrixType(uint32_t v_cnt, uint32_t ConvertToHalfPass::EquivFloatTypeId(uint32_t ty_id, uint32_t width) { analysis::Type* reg_equiv_ty; Instruction* ty_inst = get_def_use_mgr()->GetDef(ty_id); - if (ty_inst->opcode() == SpvOpTypeMatrix) + if (ty_inst->opcode() == spv::Op::OpTypeMatrix) reg_equiv_ty = FloatMatrixType(ty_inst->GetSingleWordInOperand(1), ty_inst->GetSingleWordInOperand(0), width); - else if (ty_inst->opcode() == SpvOpTypeVector) + else if (ty_inst->opcode() == spv::Op::OpTypeVector) reg_equiv_ty = FloatVectorType(ty_inst->GetSingleWordInOperand(1), width); - else // SpvOpTypeFloat + else // spv::Op::OpTypeFloat reg_equiv_ty = FloatScalarType(width); return context()->get_type_mgr()->GetTypeInstruction(reg_equiv_ty); } @@ -102,18 +101,18 @@ void ConvertToHalfPass::GenConvert(uint32_t* val_idp, uint32_t width, InstructionBuilder builder( context(), inst, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - if (val_inst->opcode() == SpvOpUndef) - cvt_inst = builder.AddNullaryOp(nty_id, SpvOpUndef); + if (val_inst->opcode() == spv::Op::OpUndef) + cvt_inst = builder.AddNullaryOp(nty_id, spv::Op::OpUndef); else - cvt_inst = builder.AddUnaryOp(nty_id, SpvOpFConvert, *val_idp); + cvt_inst = builder.AddUnaryOp(nty_id, spv::Op::OpFConvert, *val_idp); *val_idp = cvt_inst->result_id(); } bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { - if (inst->opcode() != SpvOpFConvert) return false; + if (inst->opcode() != spv::Op::OpFConvert) return false; uint32_t mty_id = inst->type_id(); Instruction* mty_inst = get_def_use_mgr()->GetDef(mty_id); - if (mty_inst->opcode() != SpvOpTypeMatrix) return false; + if (mty_inst->opcode() != spv::Op::OpTypeMatrix) return false; uint32_t vty_id = mty_inst->GetSingleWordInOperand(0); uint32_t v_cnt = mty_inst->GetSingleWordInOperand(1); Instruction* vty_inst = get_def_use_mgr()->GetDef(vty_id); @@ -130,18 +129,18 @@ bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { std::vector opnds = {}; for (uint32_t vidx = 0; vidx < v_cnt; ++vidx) { Instruction* ext_inst = builder.AddIdLiteralOp( - orig_vty_id, SpvOpCompositeExtract, orig_mat_id, vidx); + orig_vty_id, spv::Op::OpCompositeExtract, orig_mat_id, vidx); Instruction* cvt_inst = - builder.AddUnaryOp(vty_id, SpvOpFConvert, ext_inst->result_id()); + builder.AddUnaryOp(vty_id, spv::Op::OpFConvert, ext_inst->result_id()); opnds.push_back({SPV_OPERAND_TYPE_ID, {cvt_inst->result_id()}}); } uint32_t mat_id = TakeNextId(); std::unique_ptr mat_inst(new Instruction( - context(), SpvOpCompositeConstruct, mty_id, mat_id, opnds)); + context(), spv::Op::OpCompositeConstruct, mty_id, mat_id, opnds)); (void)builder.AddInstruction(std::move(mat_inst)); context()->ReplaceAllUsesWith(inst->result_id(), mat_id); // Turn original instruction into copy so it is valid. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetResultType(EquivFloatTypeId(mty_id, orig_width)); get_def_use_mgr()->AnalyzeInstUse(inst); return true; @@ -150,10 +149,11 @@ bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { bool ConvertToHalfPass::RemoveRelaxedDecoration(uint32_t id) { return context()->get_decoration_mgr()->RemoveDecorationsFrom( id, [](const Instruction& dec) { - if (dec.opcode() == SpvOpDecorate && - dec.GetSingleWordInOperand(1u) == SpvDecorationRelaxedPrecision) + if (dec.opcode() == spv::Op::OpDecorate && + spv::Decoration(dec.GetSingleWordInOperand(1u)) == + spv::Decoration::RelaxedPrecision) { return true; - else + } else return false; }); } @@ -196,8 +196,8 @@ bool ConvertToHalfPass::ProcessPhi(Instruction* inst, uint32_t from_width, auto insert_before = bp->tail(); if (insert_before != bp->begin()) { --insert_before; - if (insert_before->opcode() != SpvOpSelectionMerge && - insert_before->opcode() != SpvOpLoopMerge) + if (insert_before->opcode() != spv::Op::OpSelectionMerge && + insert_before->opcode() != spv::Op::OpLoopMerge) ++insert_before; } GenConvert(prev_idp, to_width, &*insert_before); @@ -229,7 +229,8 @@ bool ConvertToHalfPass::ProcessConvert(Instruction* inst) { // changed to half. uint32_t val_id = inst->GetSingleWordInOperand(0); Instruction* val_inst = get_def_use_mgr()->GetDef(val_id); - if (inst->type_id() == val_inst->type_id()) inst->SetOpcode(SpvOpCopyObject); + if (inst->type_id() == val_inst->type_id()) + inst->SetOpcode(spv::Op::OpCopyObject); return true; // modified } @@ -251,7 +252,7 @@ bool ConvertToHalfPass::ProcessImageRef(Instruction* inst) { bool ConvertToHalfPass::ProcessDefault(Instruction* inst) { // If non-relaxed instruction has changed operands, need to convert // them back to float32 - if (inst->opcode() == SpvOpPhi) return ProcessPhi(inst, 16u, 32u); + if (inst->opcode() == spv::Op::OpPhi) return ProcessPhi(inst, 16u, 32u); bool modified = false; inst->ForEachInId([&inst, &modified, this](uint32_t* idp) { if (converted_ids_.count(*idp) == 0) return; @@ -269,9 +270,9 @@ bool ConvertToHalfPass::GenHalfInst(Instruction* inst) { bool inst_relaxed = IsRelaxed(inst->result_id()); if (IsArithmetic(inst) && inst_relaxed) modified = GenHalfArith(inst); - else if (inst->opcode() == SpvOpPhi && inst_relaxed) + else if (inst->opcode() == spv::Op::OpPhi && inst_relaxed) modified = ProcessPhi(inst, 32u, 16u); - else if (inst->opcode() == SpvOpFConvert) + else if (inst->opcode() == spv::Op::OpFConvert) modified = ProcessConvert(inst); else if (image_ops_.count(inst->opcode()) != 0) modified = ProcessImageRef(inst); @@ -350,7 +351,7 @@ Pass::Status ConvertToHalfPass::ProcessImpl() { }; bool modified = context()->ProcessReachableCallTree(pfn); // If modified, make sure module has Float16 capability - if (modified) context()->AddCapability(SpvCapabilityFloat16); + if (modified) context()->AddCapability(spv::Capability::Float16); // Remove all RelaxedPrecision decorations from instructions and globals for (auto c_id : relaxed_ids_set_) { modified |= RemoveRelaxedDecoration(c_id); @@ -371,44 +372,44 @@ Pass::Status ConvertToHalfPass::Process() { void ConvertToHalfPass::Initialize() { target_ops_core_ = { - SpvOpVectorExtractDynamic, - SpvOpVectorInsertDynamic, - SpvOpVectorShuffle, - SpvOpCompositeConstruct, - SpvOpCompositeInsert, - SpvOpCompositeExtract, - SpvOpCopyObject, - SpvOpTranspose, - SpvOpConvertSToF, - SpvOpConvertUToF, - // SpvOpFConvert, - // SpvOpQuantizeToF16, - SpvOpFNegate, - SpvOpFAdd, - SpvOpFSub, - SpvOpFMul, - SpvOpFDiv, - SpvOpFMod, - SpvOpVectorTimesScalar, - SpvOpMatrixTimesScalar, - SpvOpVectorTimesMatrix, - SpvOpMatrixTimesVector, - SpvOpMatrixTimesMatrix, - SpvOpOuterProduct, - SpvOpDot, - SpvOpSelect, - SpvOpFOrdEqual, - SpvOpFUnordEqual, - SpvOpFOrdNotEqual, - SpvOpFUnordNotEqual, - SpvOpFOrdLessThan, - SpvOpFUnordLessThan, - SpvOpFOrdGreaterThan, - SpvOpFUnordGreaterThan, - SpvOpFOrdLessThanEqual, - SpvOpFUnordLessThanEqual, - SpvOpFOrdGreaterThanEqual, - SpvOpFUnordGreaterThanEqual, + spv::Op::OpVectorExtractDynamic, + spv::Op::OpVectorInsertDynamic, + spv::Op::OpVectorShuffle, + spv::Op::OpCompositeConstruct, + spv::Op::OpCompositeInsert, + spv::Op::OpCompositeExtract, + spv::Op::OpCopyObject, + spv::Op::OpTranspose, + spv::Op::OpConvertSToF, + spv::Op::OpConvertUToF, + // spv::Op::OpFConvert, + // spv::Op::OpQuantizeToF16, + spv::Op::OpFNegate, + spv::Op::OpFAdd, + spv::Op::OpFSub, + spv::Op::OpFMul, + spv::Op::OpFDiv, + spv::Op::OpFMod, + spv::Op::OpVectorTimesScalar, + spv::Op::OpMatrixTimesScalar, + spv::Op::OpVectorTimesMatrix, + spv::Op::OpMatrixTimesVector, + spv::Op::OpMatrixTimesMatrix, + spv::Op::OpOuterProduct, + spv::Op::OpDot, + spv::Op::OpSelect, + spv::Op::OpFOrdEqual, + spv::Op::OpFUnordEqual, + spv::Op::OpFOrdNotEqual, + spv::Op::OpFUnordNotEqual, + spv::Op::OpFOrdLessThan, + spv::Op::OpFUnordLessThan, + spv::Op::OpFOrdGreaterThan, + spv::Op::OpFUnordGreaterThan, + spv::Op::OpFOrdLessThanEqual, + spv::Op::OpFUnordLessThanEqual, + spv::Op::OpFOrdGreaterThanEqual, + spv::Op::OpFUnordGreaterThanEqual, }; target_ops_450_ = { GLSLstd450Round, GLSLstd450RoundEven, GLSLstd450Trunc, GLSLstd450FAbs, @@ -427,53 +428,53 @@ void ConvertToHalfPass::Initialize() { GLSLstd450Ldexp, GLSLstd450Length, GLSLstd450Distance, GLSLstd450Cross, GLSLstd450Normalize, GLSLstd450FaceForward, GLSLstd450Reflect, GLSLstd450Refract, GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp}; - image_ops_ = {SpvOpImageSampleImplicitLod, - SpvOpImageSampleExplicitLod, - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleDrefExplicitLod, - SpvOpImageSampleProjImplicitLod, - SpvOpImageSampleProjExplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSampleProjDrefExplicitLod, - SpvOpImageFetch, - SpvOpImageGather, - SpvOpImageDrefGather, - SpvOpImageRead, - SpvOpImageSparseSampleImplicitLod, - SpvOpImageSparseSampleExplicitLod, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleDrefExplicitLod, - SpvOpImageSparseSampleProjImplicitLod, - SpvOpImageSparseSampleProjExplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, - SpvOpImageSparseSampleProjDrefExplicitLod, - SpvOpImageSparseFetch, - SpvOpImageSparseGather, - SpvOpImageSparseDrefGather, - SpvOpImageSparseTexelsResident, - SpvOpImageSparseRead}; + image_ops_ = {spv::Op::OpImageSampleImplicitLod, + spv::Op::OpImageSampleExplicitLod, + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleProjImplicitLod, + spv::Op::OpImageSampleProjExplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageFetch, + spv::Op::OpImageGather, + spv::Op::OpImageDrefGather, + spv::Op::OpImageRead, + spv::Op::OpImageSparseSampleImplicitLod, + spv::Op::OpImageSparseSampleExplicitLod, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleDrefExplicitLod, + spv::Op::OpImageSparseSampleProjImplicitLod, + spv::Op::OpImageSparseSampleProjExplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleProjDrefExplicitLod, + spv::Op::OpImageSparseFetch, + spv::Op::OpImageSparseGather, + spv::Op::OpImageSparseDrefGather, + spv::Op::OpImageSparseTexelsResident, + spv::Op::OpImageSparseRead}; dref_image_ops_ = { - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleDrefExplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSampleProjDrefExplicitLod, - SpvOpImageDrefGather, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleDrefExplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, - SpvOpImageSparseSampleProjDrefExplicitLod, - SpvOpImageSparseDrefGather, + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageDrefGather, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleDrefExplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleProjDrefExplicitLod, + spv::Op::OpImageSparseDrefGather, }; closure_ops_ = { - SpvOpVectorExtractDynamic, - SpvOpVectorInsertDynamic, - SpvOpVectorShuffle, - SpvOpCompositeConstruct, - SpvOpCompositeInsert, - SpvOpCompositeExtract, - SpvOpCopyObject, - SpvOpTranspose, - SpvOpPhi, + spv::Op::OpVectorExtractDynamic, + spv::Op::OpVectorInsertDynamic, + spv::Op::OpVectorShuffle, + spv::Op::OpCompositeConstruct, + spv::Op::OpCompositeInsert, + spv::Op::OpCompositeExtract, + spv::Op::OpCopyObject, + spv::Op::OpTranspose, + spv::Op::OpPhi, }; relaxed_ids_set_.clear(); converted_ids_.clear(); diff --git a/3rdparty/spirv-tools/source/opt/convert_to_half_pass.h b/3rdparty/spirv-tools/source/opt/convert_to_half_pass.h index c6e84d1b7..feabfba3e 100644 --- a/3rdparty/spirv-tools/source/opt/convert_to_half_pass.h +++ b/3rdparty/spirv-tools/source/opt/convert_to_half_pass.h @@ -120,20 +120,26 @@ class ConvertToHalfPass : public Pass { // Initialize state for converting to half void Initialize(); + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + // Set of core operations to be processed - std::unordered_set target_ops_core_; + std::unordered_set target_ops_core_; // Set of 450 extension operations to be processed std::unordered_set target_ops_450_; // Set of sample operations - std::unordered_set image_ops_; + std::unordered_set image_ops_; // Set of dref sample operations - std::unordered_set dref_image_ops_; + std::unordered_set dref_image_ops_; // Set of dref sample operations - std::unordered_set closure_ops_; + std::unordered_set closure_ops_; // Set of ids of all relaxed instructions std::unordered_set relaxed_ids_set_; diff --git a/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp b/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp index e84d3578a..2effc3e4c 100644 --- a/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp @@ -70,7 +70,7 @@ uint32_t GetImageTypeOfSampledImage(analysis::TypeManager* type_mgr, Instruction* GetNonCopyObjectDef(analysis::DefUseManager* def_use_mgr, uint32_t inst_id) { Instruction* inst = def_use_mgr->GetDef(inst_id); - while (inst->opcode() == SpvOpCopyObject) { + while (inst->opcode() == spv::Op::OpCopyObject) { inst_id = inst->GetSingleWordInOperand(0u); inst = def_use_mgr->GetDef(inst_id); } @@ -87,8 +87,9 @@ bool ConvertToSampledImagePass::GetDescriptorSetBinding( bool found_binding_to_convert = false; for (auto decorate : decoration_manager->GetDecorationsFor(inst.result_id(), false)) { - uint32_t decoration = decorate->GetSingleWordInOperand(1u); - if (decoration == SpvDecorationDescriptorSet) { + spv::Decoration decoration = + spv::Decoration(decorate->GetSingleWordInOperand(1u)); + if (decoration == spv::Decoration::DescriptorSet) { if (found_descriptor_set_to_convert) { assert(false && "A resource has two OpDecorate for the descriptor set"); return false; @@ -96,7 +97,7 @@ bool ConvertToSampledImagePass::GetDescriptorSetBinding( descriptor_set_binding->descriptor_set = decorate->GetSingleWordInOperand(2u); found_descriptor_set_to_convert = true; - } else if (decoration == SpvDecorationBinding) { + } else if (decoration == spv::Decoration::Binding) { if (found_binding_to_convert) { assert(false && "A resource has two OpDecorate for the binding"); return false; @@ -116,7 +117,7 @@ bool ConvertToSampledImagePass::ShouldResourceBeConverted( const analysis::Type* ConvertToSampledImagePass::GetVariableType( const Instruction& variable) const { - if (variable.opcode() != SpvOpVariable) return nullptr; + if (variable.opcode() != spv::Op::OpVariable) return nullptr; auto* type = context()->get_type_mgr()->GetType(variable.type_id()); auto* pointer_type = type->AsPointer(); if (!pointer_type) return nullptr; @@ -124,12 +125,12 @@ const analysis::Type* ConvertToSampledImagePass::GetVariableType( return pointer_type->pointee_type(); } -SpvStorageClass ConvertToSampledImagePass::GetStorageClass( +spv::StorageClass ConvertToSampledImagePass::GetStorageClass( const Instruction& variable) const { - assert(variable.opcode() == SpvOpVariable); + assert(variable.opcode() == spv::Op::OpVariable); auto* type = context()->get_type_mgr()->GetType(variable.type_id()); auto* pointer_type = type->AsPointer(); - if (!pointer_type) return SpvStorageClassMax; + if (!pointer_type) return spv::StorageClass::Max; return pointer_type->storage_class(); } @@ -205,12 +206,12 @@ Pass::Status ConvertToSampledImagePass::Process() { void ConvertToSampledImagePass::FindUses(const Instruction* inst, std::vector* uses, - uint32_t user_opcode) const { + spv::Op user_opcode) const { auto* def_use_mgr = context()->get_def_use_mgr(); def_use_mgr->ForEachUser(inst, [uses, user_opcode, this](Instruction* user) { if (user->opcode() == user_opcode) { uses->push_back(user); - } else if (user->opcode() == SpvOpCopyObject) { + } else if (user->opcode() == spv::Op::OpCopyObject) { FindUses(user, uses, user_opcode); } }); @@ -221,21 +222,21 @@ void ConvertToSampledImagePass::FindUsesOfImage( auto* def_use_mgr = context()->get_def_use_mgr(); def_use_mgr->ForEachUser(image, [uses, this](Instruction* user) { switch (user->opcode()) { - case SpvOpImageFetch: - case SpvOpImageRead: - case SpvOpImageWrite: - case SpvOpImageQueryFormat: - case SpvOpImageQueryOrder: - case SpvOpImageQuerySizeLod: - case SpvOpImageQuerySize: - case SpvOpImageQueryLevels: - case SpvOpImageQuerySamples: - case SpvOpImageSparseFetch: + case spv::Op::OpImageFetch: + case spv::Op::OpImageRead: + case spv::Op::OpImageWrite: + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: + case spv::Op::OpImageQuerySizeLod: + case spv::Op::OpImageQuerySize: + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: + case spv::Op::OpImageSparseFetch: uses->push_back(user); default: break; } - if (user->opcode() == SpvOpCopyObject) { + if (user->opcode() == spv::Op::OpCopyObject) { FindUsesOfImage(user, uses); } }); @@ -248,7 +249,7 @@ Instruction* ConvertToSampledImagePass::CreateImageExtraction( IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); return builder.AddUnaryOp( GetImageTypeOfSampledImage(context()->get_type_mgr(), sampled_image), - SpvOpImage, sampled_image->result_id()); + spv::Op::OpImage, sampled_image->result_id()); } uint32_t ConvertToSampledImagePass::GetSampledImageTypeForImage( @@ -284,7 +285,7 @@ bool ConvertToSampledImagePass:: auto* def_use_mgr = context()->get_def_use_mgr(); uint32_t sampler_id = sampled_image_inst->GetSingleWordInOperand(1u); auto* sampler_load = def_use_mgr->GetDef(sampler_id); - if (sampler_load->opcode() != SpvOpLoad) return false; + if (sampler_load->opcode() != spv::Op::OpLoad) return false; auto* sampler = def_use_mgr->GetDef(sampler_load->GetSingleWordInOperand(0u)); DescriptorSetAndBinding sampler_descriptor_set_binding; return GetDescriptorSetBinding(*sampler, &sampler_descriptor_set_binding) && @@ -295,7 +296,7 @@ void ConvertToSampledImagePass::UpdateSampledImageUses( Instruction* image_load, Instruction* image_extraction, const DescriptorSetAndBinding& image_descriptor_set_binding) { std::vector sampled_image_users; - FindUses(image_load, &sampled_image_users, SpvOpSampledImage); + FindUses(image_load, &sampled_image_users, spv::Op::OpSampledImage); auto* def_use_mgr = context()->get_def_use_mgr(); for (auto* sampled_image_inst : sampled_image_users) { @@ -328,7 +329,7 @@ bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage( context()->get_type_mgr()->GetType(sampled_image_type_id); if (sampled_image_type == nullptr) return false; auto storage_class = GetStorageClass(*image_variable); - if (storage_class == SpvStorageClassMax) return false; + if (storage_class == spv::StorageClass::Max) return false; analysis::Pointer sampled_image_pointer(sampled_image_type, storage_class); // Make sure |image_variable| is behind its type i.e., avoid the forward @@ -343,7 +344,7 @@ Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage( Instruction* image_variable, const DescriptorSetAndBinding& descriptor_set_binding) { std::vector image_variable_loads; - FindUses(image_variable, &image_variable_loads, SpvOpLoad); + FindUses(image_variable, &image_variable_loads, spv::Op::OpLoad); if (image_variable_loads.empty()) return Status::SuccessWithoutChange; const uint32_t sampled_image_type_id = @@ -364,14 +365,14 @@ Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage( bool ConvertToSampledImagePass::DoesSampledImageReferenceImage( Instruction* sampled_image_inst, Instruction* image_variable) { - if (sampled_image_inst->opcode() != SpvOpSampledImage) return false; + if (sampled_image_inst->opcode() != spv::Op::OpSampledImage) return false; auto* def_use_mgr = context()->get_def_use_mgr(); auto* image_load = GetNonCopyObjectDef( def_use_mgr, sampled_image_inst->GetSingleWordInOperand(0u)); - if (image_load->opcode() != SpvOpLoad) return false; + if (image_load->opcode() != spv::Op::OpLoad) return false; auto* image = GetNonCopyObjectDef(def_use_mgr, image_load->GetSingleWordInOperand(0u)); - return image->opcode() == SpvOpVariable && + return image->opcode() == spv::Op::OpVariable && image->result_id() == image_variable->result_id(); } @@ -381,10 +382,10 @@ Pass::Status ConvertToSampledImagePass::CheckUsesOfSamplerVariable( if (image_to_be_combined_with == nullptr) return Status::Failure; std::vector sampler_variable_loads; - FindUses(sampler_variable, &sampler_variable_loads, SpvOpLoad); + FindUses(sampler_variable, &sampler_variable_loads, spv::Op::OpLoad); for (auto* load : sampler_variable_loads) { std::vector sampled_image_users; - FindUses(load, &sampled_image_users, SpvOpSampledImage); + FindUses(load, &sampled_image_users, spv::Op::OpSampledImage); for (auto* sampled_image_inst : sampled_image_users) { if (!DoesSampledImageReferenceImage(sampled_image_inst, image_to_be_combined_with)) { diff --git a/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h b/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h index d3938af7d..a8b1501e6 100644 --- a/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h +++ b/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h @@ -120,13 +120,13 @@ class ConvertToSampledImagePass : public Pass { const analysis::Type* GetVariableType(const Instruction& variable) const; // Returns the storage class of |variable|. - SpvStorageClass GetStorageClass(const Instruction& variable) const; + spv::StorageClass GetStorageClass(const Instruction& variable) const; // Finds |inst|'s users whose opcode is |user_opcode| or users of OpCopyObject // instructions of |inst| whose opcode is |user_opcode| and puts them in // |uses|. void FindUses(const Instruction* inst, std::vector* uses, - uint32_t user_opcode) const; + spv::Op user_opcode) const; // Finds OpImage* instructions using |image| or OpCopyObject instructions that // copy |image| and puts them in |uses|. diff --git a/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp b/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp index 0b235629b..66a268fba 100644 --- a/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp +++ b/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp @@ -22,12 +22,12 @@ namespace spvtools { namespace opt { namespace { -const uint32_t kLoadPointerInOperand = 0; -const uint32_t kStorePointerInOperand = 0; -const uint32_t kStoreObjectInOperand = 1; -const uint32_t kCompositeExtractObjectInOperand = 0; -const uint32_t kTypePointerStorageClassInIdx = 0; -const uint32_t kTypePointerPointeeInIdx = 1; +constexpr uint32_t kLoadPointerInOperand = 0; +constexpr uint32_t kStorePointerInOperand = 0; +constexpr uint32_t kStoreObjectInOperand = 1; +constexpr uint32_t kCompositeExtractObjectInOperand = 0; +constexpr uint32_t kTypePointerStorageClassInIdx = 0; +constexpr uint32_t kTypePointerPointeeInIdx = 1; bool IsDebugDeclareOrValue(Instruction* di) { auto dbg_opcode = di->GetCommonDebugOpcode(); @@ -46,8 +46,8 @@ Pass::Status CopyPropagateArrays::Process() { BasicBlock* entry_bb = &*function.begin(); - for (auto var_inst = entry_bb->begin(); var_inst->opcode() == SpvOpVariable; - ++var_inst) { + for (auto var_inst = entry_bb->begin(); + var_inst->opcode() == spv::Op::OpVariable; ++var_inst) { if (!IsPointerToArrayType(var_inst->type_id())) { continue; } @@ -76,7 +76,7 @@ Pass::Status CopyPropagateArrays::Process() { std::unique_ptr CopyPropagateArrays::FindSourceObjectIfPossible(Instruction* var_inst, Instruction* store_inst) { - assert(var_inst->opcode() == SpvOpVariable && "Expecting a variable."); + assert(var_inst->opcode() == spv::Op::OpVariable && "Expecting a variable."); // Check that the variable is a composite object where |store_inst| // dominates all of its loads. @@ -114,7 +114,7 @@ Instruction* CopyPropagateArrays::FindStoreInstruction( Instruction* store_inst = nullptr; get_def_use_mgr()->WhileEachUser( var_inst, [&store_inst, var_inst](Instruction* use) { - if (use->opcode() == SpvOpStore && + if (use->opcode() == spv::Op::OpStore && use->GetSingleWordInOperand(kStorePointerInOperand) == var_inst->result_id()) { if (store_inst == nullptr) { @@ -132,7 +132,7 @@ Instruction* CopyPropagateArrays::FindStoreInstruction( void CopyPropagateArrays::PropagateObject(Instruction* var_inst, MemoryObject* source, Instruction* insertion_point) { - assert(var_inst->opcode() == SpvOpVariable && + assert(var_inst->opcode() == spv::Op::OpVariable && "This function propagates variables."); Instruction* new_access_chain = BuildNewAccessChain(insertion_point, source); @@ -166,17 +166,17 @@ Instruction* CopyPropagateArrays::BuildNewAccessChain( bool CopyPropagateArrays::HasNoStores(Instruction* ptr_inst) { return get_def_use_mgr()->WhileEachUser(ptr_inst, [this](Instruction* use) { - if (use->opcode() == SpvOpLoad) { + if (use->opcode() == spv::Op::OpLoad) { return true; - } else if (use->opcode() == SpvOpAccessChain) { + } else if (use->opcode() == spv::Op::OpAccessChain) { return HasNoStores(use); - } else if (use->IsDecoration() || use->opcode() == SpvOpName) { + } else if (use->IsDecoration() || use->opcode() == spv::Op::OpName) { return true; - } else if (use->opcode() == SpvOpStore) { + } else if (use->opcode() == spv::Op::OpStore) { return false; - } else if (use->opcode() == SpvOpImageTexelPointer) { + } else if (use->opcode() == spv::Op::OpImageTexelPointer) { return true; - } else if (use->opcode() == SpvOpEntryPoint) { + } else if (use->opcode() == spv::Op::OpEntryPoint) { return true; } // Some other instruction. Be conservative. @@ -193,19 +193,19 @@ bool CopyPropagateArrays::HasValidReferencesOnly(Instruction* ptr_inst, return get_def_use_mgr()->WhileEachUser( ptr_inst, [this, store_inst, dominator_analysis, ptr_inst](Instruction* use) { - if (use->opcode() == SpvOpLoad || - use->opcode() == SpvOpImageTexelPointer) { + if (use->opcode() == spv::Op::OpLoad || + use->opcode() == spv::Op::OpImageTexelPointer) { // TODO: If there are many load in the same BB as |store_inst| the // time to do the multiple traverses can add up. Consider collecting // those loads and doing a single traversal. return dominator_analysis->Dominates(store_inst, use); - } else if (use->opcode() == SpvOpAccessChain) { + } else if (use->opcode() == spv::Op::OpAccessChain) { return HasValidReferencesOnly(use, store_inst); - } else if (use->IsDecoration() || use->opcode() == SpvOpName) { + } else if (use->IsDecoration() || use->opcode() == spv::Op::OpName) { return true; - } else if (use->opcode() == SpvOpStore) { + } else if (use->opcode() == spv::Op::OpStore) { // If we are storing to part of the object it is not an candidate. - return ptr_inst->opcode() == SpvOpVariable && + return ptr_inst->opcode() == spv::Op::OpVariable && store_inst->GetSingleWordInOperand(kStorePointerInOperand) == ptr_inst->result_id(); } else if (IsDebugDeclareOrValue(use)) { @@ -221,15 +221,15 @@ CopyPropagateArrays::GetSourceObjectIfAny(uint32_t result) { Instruction* result_inst = context()->get_def_use_mgr()->GetDef(result); switch (result_inst->opcode()) { - case SpvOpLoad: + case spv::Op::OpLoad: return BuildMemoryObjectFromLoad(result_inst); - case SpvOpCompositeExtract: + case spv::Op::OpCompositeExtract: return BuildMemoryObjectFromExtract(result_inst); - case SpvOpCompositeConstruct: + case spv::Op::OpCompositeConstruct: return BuildMemoryObjectFromCompositeConstruct(result_inst); - case SpvOpCopyObject: + case spv::Op::OpCopyObject: return GetSourceObjectIfAny(result_inst->GetSingleWordInOperand(0)); - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: return BuildMemoryObjectFromInsert(result_inst); default: return nullptr; @@ -251,7 +251,7 @@ CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { // // It is built in reverse order because the different |OpAccessChain| // instructions are visited in reverse order from which they are applied. - while (current_inst->opcode() == SpvOpAccessChain) { + while (current_inst->opcode() == spv::Op::OpAccessChain) { for (uint32_t i = current_inst->NumInOperands() - 1; i >= 1; --i) { uint32_t element_index_id = current_inst->GetSingleWordInOperand(i); components_in_reverse.push_back(element_index_id); @@ -263,7 +263,7 @@ CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { // instruction followed by a series of |OpAccessChain| instructions, then // return |nullptr| because we cannot identify the owner or access chain // exactly. - if (current_inst->opcode() != SpvOpVariable) { + if (current_inst->opcode() != spv::Op::OpVariable) { return nullptr; } @@ -276,7 +276,7 @@ CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { std::unique_ptr CopyPropagateArrays::BuildMemoryObjectFromExtract(Instruction* extract_inst) { - assert(extract_inst->opcode() == SpvOpCompositeExtract && + assert(extract_inst->opcode() == spv::Op::OpCompositeExtract && "Expecting an OpCompositeExtract instruction."); std::unique_ptr result = GetSourceObjectIfAny( extract_inst->GetSingleWordInOperand(kCompositeExtractObjectInOperand)); @@ -297,7 +297,7 @@ CopyPropagateArrays::BuildMemoryObjectFromExtract(Instruction* extract_inst) { std::unique_ptr CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( Instruction* conststruct_inst) { - assert(conststruct_inst->opcode() == SpvOpCompositeConstruct && + assert(conststruct_inst->opcode() == spv::Op::OpCompositeConstruct && "Expecting an OpCompositeConstruct instruction."); // If every operand in the instruction are part of the same memory object, and @@ -352,7 +352,7 @@ CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( std::unique_ptr CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { - assert(insert_inst->opcode() == SpvOpCompositeInsert && + assert(insert_inst->opcode() == spv::Op::OpCompositeInsert && "Expecting an OpCompositeInsert instruction."); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); @@ -407,7 +407,7 @@ CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { Instruction* current_insert = def_use_mgr->GetDef(insert_inst->GetSingleWordInOperand(1)); for (uint32_t i = number_of_elements - 1; i > 0; --i) { - if (current_insert->opcode() != SpvOpCompositeInsert) { + if (current_insert->opcode() != spv::Op::OpCompositeInsert) { return nullptr; } @@ -500,7 +500,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, if (IsDebugDeclareOrValue(use)) return true; switch (use->opcode()) { - case SpvOpLoad: { + case spv::Op::OpLoad: { analysis::Pointer* pointer_type = type->AsPointer(); uint32_t new_type_id = type_mgr->GetId(pointer_type->pointee_type()); @@ -509,7 +509,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, } return true; } - case SpvOpAccessChain: { + case spv::Op::OpAccessChain: { analysis::Pointer* pointer_type = type->AsPointer(); const analysis::Type* pointee_type = pointer_type->pointee_type(); @@ -547,7 +547,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, } return true; } - case SpvOpCompositeExtract: { + case spv::Op::OpCompositeExtract: { std::vector access_chain; for (uint32_t i = 1; i < use->NumInOperands(); ++i) { access_chain.push_back(use->GetSingleWordInOperand(i)); @@ -565,13 +565,13 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, } return true; } - case SpvOpStore: + case spv::Op::OpStore: // If needed, we can create an element-by-element copy to change the // type of the value being stored. This way we can always handled // stores. return true; - case SpvOpImageTexelPointer: - case SpvOpName: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpName: return true; default: return use->IsDecoration(); @@ -598,8 +598,8 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, if (use->IsCommonDebugInstr()) { switch (use->GetCommonDebugOpcode()) { case CommonDebugInfoDebugDeclare: { - if (new_ptr_inst->opcode() == SpvOpVariable || - new_ptr_inst->opcode() == SpvOpFunctionParameter) { + if (new_ptr_inst->opcode() == spv::Op::OpVariable || + new_ptr_inst->opcode() == spv::Op::OpFunctionParameter) { context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); context()->AnalyzeUses(use); @@ -640,7 +640,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, } switch (use->opcode()) { - case SpvOpLoad: { + case spv::Op::OpLoad: { // Replace the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -658,7 +658,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } } break; - case SpvOpAccessChain: { + case spv::Op::OpAccessChain: { // Update the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -685,7 +685,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, pointer_type_inst->GetSingleWordInOperand(kTypePointerPointeeInIdx), access_chain); - SpvStorageClass storage_class = static_cast( + spv::StorageClass storage_class = static_cast( pointer_type_inst->GetSingleWordInOperand( kTypePointerStorageClassInIdx)); @@ -700,7 +700,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } } break; - case SpvOpCompositeExtract: { + case spv::Op::OpCompositeExtract: { // Update the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -721,7 +721,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } } break; - case SpvOpStore: + case spv::Op::OpStore: // If the use is the pointer, then it is the single store to that // variable. We do not want to replace it. Instead, it will become // dead after all of the loads are removed, and ADCE will get rid of it. @@ -744,11 +744,11 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } break; - case SpvOpDecorate: + case spv::Op::OpDecorate: // We treat an OpImageTexelPointer as a load. The result type should // always have the Image storage class, and should not need to be // updated. - case SpvOpImageTexelPointer: + case spv::Op::OpImageTexelPointer: // Replace the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -766,13 +766,13 @@ uint32_t CopyPropagateArrays::GetMemberTypeId( for (uint32_t element_index : access_chain) { Instruction* type_inst = get_def_use_mgr()->GetDef(id); switch (type_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeMatrix: - case SpvOpTypeVector: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: id = type_inst->GetSingleWordInOperand(0); break; - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: id = type_inst->GetSingleWordInOperand(element_index); break; default: diff --git a/3rdparty/spirv-tools/source/opt/copy_prop_arrays.h b/3rdparty/spirv-tools/source/opt/copy_prop_arrays.h index 9e7641f61..7486f8086 100644 --- a/3rdparty/spirv-tools/source/opt/copy_prop_arrays.h +++ b/3rdparty/spirv-tools/source/opt/copy_prop_arrays.h @@ -134,13 +134,13 @@ class CopyPropagateArrays : public MemPass { var_pointer_inst->GetSingleWordInOperand(1), GetAccessIds()); uint32_t member_pointer_type_id = type_mgr->FindPointerToType( - member_type_id, static_cast( + member_type_id, static_cast( var_pointer_inst->GetSingleWordInOperand(0))); return member_pointer_type_id; } // Returns the storage class of the memory object. - SpvStorageClass GetStorageClass() const { + spv::StorageClass GetStorageClass() const { analysis::TypeManager* type_mgr = GetVariable()->context()->get_type_mgr(); const analysis::Pointer* pointer_type = diff --git a/3rdparty/spirv-tools/source/opt/dataflow.cpp b/3rdparty/spirv-tools/source/opt/dataflow.cpp index c91fad08e..8d74e4137 100644 --- a/3rdparty/spirv-tools/source/opt/dataflow.cpp +++ b/3rdparty/spirv-tools/source/opt/dataflow.cpp @@ -78,7 +78,7 @@ void ForwardDataFlowAnalysis::EnqueueUsers(Instruction* inst) { } void ForwardDataFlowAnalysis::EnqueueBlockSuccessors(Instruction* inst) { - if (inst->opcode() != SpvOpLabel) return; + if (inst->opcode() != spv::Op::OpLabel) return; context() .cfg() ->block(inst->result_id()) diff --git a/3rdparty/spirv-tools/source/opt/dead_branch_elim_pass.cpp b/3rdparty/spirv-tools/source/opt/dead_branch_elim_pass.cpp index d99b7f78a..319b8d161 100644 --- a/3rdparty/spirv-tools/source/opt/dead_branch_elim_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/dead_branch_elim_pass.cpp @@ -29,28 +29,25 @@ namespace spvtools { namespace opt { - namespace { - -const uint32_t kBranchCondTrueLabIdInIdx = 1; -const uint32_t kBranchCondFalseLabIdInIdx = 2; - -} // anonymous namespace +constexpr uint32_t kBranchCondTrueLabIdInIdx = 1; +constexpr uint32_t kBranchCondFalseLabIdInIdx = 2; +} // namespace bool DeadBranchElimPass::GetConstCondition(uint32_t condId, bool* condVal) { bool condIsConst; Instruction* cInst = get_def_use_mgr()->GetDef(condId); switch (cInst->opcode()) { - case SpvOpConstantNull: - case SpvOpConstantFalse: { + case spv::Op::OpConstantNull: + case spv::Op::OpConstantFalse: { *condVal = false; condIsConst = true; } break; - case SpvOpConstantTrue: { + case spv::Op::OpConstantTrue: { *condVal = true; condIsConst = true; } break; - case SpvOpLogicalNot: { + case spv::Op::OpLogicalNot: { bool negVal; condIsConst = GetConstCondition(cInst->GetSingleWordInOperand(0), &negVal); @@ -65,13 +62,13 @@ bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { Instruction* sInst = get_def_use_mgr()->GetDef(selId); uint32_t typeId = sInst->type_id(); Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); - if (!typeInst || (typeInst->opcode() != SpvOpTypeInt)) return false; + if (!typeInst || (typeInst->opcode() != spv::Op::OpTypeInt)) return false; // TODO(greg-lunarg): Support non-32 bit ints if (typeInst->GetSingleWordInOperand(0) != 32) return false; - if (sInst->opcode() == SpvOpConstant) { + if (sInst->opcode() == spv::Op::OpConstant) { *selVal = sInst->GetSingleWordInOperand(0); return true; - } else if (sInst->opcode() == SpvOpConstantNull) { + } else if (sInst->opcode() == spv::Op::OpConstantNull) { *selVal = 0; return true; } @@ -81,7 +78,7 @@ bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { void DeadBranchElimPass::AddBranch(uint32_t labelId, BasicBlock* bp) { assert(get_def_use_mgr()->GetDef(labelId) != nullptr); std::unique_ptr newBranch( - new Instruction(context(), SpvOpBranch, 0, 0, + new Instruction(context(), spv::Op::OpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); context()->AnalyzeDefUse(&*newBranch); context()->set_instr_block(&*newBranch, bp); @@ -115,13 +112,13 @@ bool DeadBranchElimPass::MarkLiveBlocks( Instruction* terminator = block->terminator(); uint32_t live_lab_id = 0; // Check if the terminator has a single valid successor. - if (terminator->opcode() == SpvOpBranchConditional) { + if (terminator->opcode() == spv::Op::OpBranchConditional) { bool condVal; if (GetConstCondition(terminator->GetSingleWordInOperand(0u), &condVal)) { live_lab_id = terminator->GetSingleWordInOperand( condVal ? kBranchCondTrueLabIdInIdx : kBranchCondFalseLabIdInIdx); } - } else if (terminator->opcode() == SpvOpSwitch) { + } else if (terminator->opcode() == spv::Op::OpSwitch) { uint32_t sel_val; if (GetConstInteger(terminator->GetSingleWordInOperand(0u), &sel_val)) { // Search switch operands for selector value, set live_lab_id to @@ -194,8 +191,8 @@ bool DeadBranchElimPass::SimplifyBranch(BasicBlock* block, uint32_t live_lab_id) { Instruction* merge_inst = block->GetMergeInst(); Instruction* terminator = block->terminator(); - if (merge_inst && merge_inst->opcode() == SpvOpSelectionMerge) { - if (merge_inst->NextNode()->opcode() == SpvOpSwitch && + if (merge_inst && merge_inst->opcode() == spv::Op::OpSelectionMerge) { + if (merge_inst->NextNode()->opcode() == spv::Op::OpSwitch && SwitchHasNestedBreak(block->id())) { if (terminator->NumInOperands() == 2) { // We cannot remove the branch, and it already has a single case, so no @@ -266,7 +263,7 @@ bool DeadBranchElimPass::FixPhiNodesInLiveBlocks( for (auto& block : *func) { if (live_blocks.count(&block)) { for (auto iter = block.begin(); iter != block.end();) { - if (iter->opcode() != SpvOpPhi) { + if (iter->opcode() != spv::Op::OpPhi) { break; } @@ -292,7 +289,7 @@ bool DeadBranchElimPass::FixPhiNodesInLiveBlocks( cont_iter->second == &block && inst->NumInOperands() > 4) { if (get_def_use_mgr() ->GetDef(inst->GetSingleWordInOperand(i - 1)) - ->opcode() == SpvOpUndef) { + ->opcode() == spv::Op::OpUndef) { // Already undef incoming value, no change necessary. operands.push_back(inst->GetInOperand(i - 1)); operands.push_back(inst->GetInOperand(i)); @@ -378,14 +375,14 @@ bool DeadBranchElimPass::EraseDeadBlocks( if (unreachable_continues.count(&*ebi)) { uint32_t cont_id = unreachable_continues.find(&*ebi)->second->id(); if (ebi->begin() != ebi->tail() || - ebi->terminator()->opcode() != SpvOpBranch || + ebi->terminator()->opcode() != spv::Op::OpBranch || ebi->terminator()->GetSingleWordInOperand(0u) != cont_id) { // Make unreachable, but leave the label. KillAllInsts(&*ebi, false); // Add unconditional branch to header. assert(unreachable_continues.count(&*ebi)); ebi->AddInstruction(MakeUnique( - context(), SpvOpBranch, 0, 0, + context(), spv::Op::OpBranch, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {cont_id}}})); get_def_use_mgr()->AnalyzeInstUse(&*ebi->tail()); context()->set_instr_block(&*ebi->tail(), &*ebi); @@ -394,12 +391,12 @@ bool DeadBranchElimPass::EraseDeadBlocks( ++ebi; } else if (unreachable_merges.count(&*ebi)) { if (ebi->begin() != ebi->tail() || - ebi->terminator()->opcode() != SpvOpUnreachable) { + ebi->terminator()->opcode() != spv::Op::OpUnreachable) { // Make unreachable, but leave the label. KillAllInsts(&*ebi, false); // Add unreachable terminator. ebi->AddInstruction( - MakeUnique(context(), SpvOpUnreachable, 0, 0, + MakeUnique(context(), spv::Op::OpUnreachable, 0, 0, std::initializer_list{})); context()->AnalyzeUses(ebi->terminator()); context()->set_instr_block(ebi->terminator(), &*ebi); @@ -465,7 +462,7 @@ void DeadBranchElimPass::FixBlockOrder() { }; // Structured order is more intuitive so use it where possible. - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { context()->ProcessReachableCallTree(reorder_structured); } else { context()->ProcessReachableCallTree(reorder_dominators); @@ -477,7 +474,8 @@ Pass::Status DeadBranchElimPass::Process() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; + if (ai.opcode() == spv::Op::OpGroupDecorate) + return Status::SuccessWithoutChange; // Process all entry point functions ProcessFunction pfn = [this](Function* fp) { return EliminateDeadBranches(fp); @@ -501,7 +499,7 @@ Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( Instruction* branch = start_block->terminator(); uint32_t next_block_id = 0; switch (branch->opcode()) { - case SpvOpBranchConditional: + case spv::Op::OpBranchConditional: next_block_id = start_block->MergeBlockIdIfAny(); if (next_block_id == 0) { // If a possible target is the |loop_merge_id| or |loop_continue_id|, @@ -530,7 +528,7 @@ Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( } } break; - case SpvOpSwitch: + case spv::Op::OpSwitch: next_block_id = start_block->MergeBlockIdIfAny(); if (next_block_id == 0) { // A switch with no merge instructions can have at most 5 targets: @@ -578,7 +576,7 @@ Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( // The fall through is case 3. } break; - case SpvOpBranch: + case spv::Op::OpBranch: // Need to check if this is the header of a loop nested in the // selection construct. next_block_id = start_block->MergeBlockIdIfAny(); diff --git a/3rdparty/spirv-tools/source/opt/dead_insert_elim_pass.cpp b/3rdparty/spirv-tools/source/opt/dead_insert_elim_pass.cpp index d877f0f96..a48690374 100644 --- a/3rdparty/spirv-tools/source/opt/dead_insert_elim_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/dead_insert_elim_pass.cpp @@ -23,32 +23,29 @@ namespace spvtools { namespace opt { - namespace { - -const uint32_t kTypeVectorCountInIdx = 1; -const uint32_t kTypeMatrixCountInIdx = 1; -const uint32_t kTypeArrayLengthIdInIdx = 1; -const uint32_t kTypeIntWidthInIdx = 0; -const uint32_t kConstantValueInIdx = 0; -const uint32_t kInsertObjectIdInIdx = 0; -const uint32_t kInsertCompositeIdInIdx = 1; - -} // anonymous namespace +constexpr uint32_t kTypeVectorCountInIdx = 1; +constexpr uint32_t kTypeMatrixCountInIdx = 1; +constexpr uint32_t kTypeArrayLengthIdInIdx = 1; +constexpr uint32_t kTypeIntWidthInIdx = 0; +constexpr uint32_t kConstantValueInIdx = 0; +constexpr uint32_t kInsertObjectIdInIdx = 0; +constexpr uint32_t kInsertCompositeIdInIdx = 1; +} // namespace uint32_t DeadInsertElimPass::NumComponents(Instruction* typeInst) { switch (typeInst->opcode()) { - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { return typeInst->GetSingleWordInOperand(kTypeVectorCountInIdx); } break; - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { return typeInst->GetSingleWordInOperand(kTypeMatrixCountInIdx); } break; - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { uint32_t lenId = typeInst->GetSingleWordInOperand(kTypeArrayLengthIdInIdx); Instruction* lenInst = get_def_use_mgr()->GetDef(lenId); - if (lenInst->opcode() != SpvOpConstant) return 0; + if (lenInst->opcode() != spv::Op::OpConstant) return 0; uint32_t lenTypeId = lenInst->type_id(); Instruction* lenTypeInst = get_def_use_mgr()->GetDef(lenTypeId); // TODO(greg-lunarg): Support non-32-bit array length @@ -56,7 +53,7 @@ uint32_t DeadInsertElimPass::NumComponents(Instruction* typeInst) { return 0; return lenInst->GetSingleWordInOperand(kConstantValueInIdx); } break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { return typeInst->NumInOperands(); } break; default: { return 0; } break; @@ -68,10 +65,10 @@ void DeadInsertElimPass::MarkInsertChain( uint32_t extOffset, std::unordered_set* visited_phis) { // Not currently optimizing array inserts. Instruction* typeInst = get_def_use_mgr()->GetDef(insertChain->type_id()); - if (typeInst->opcode() == SpvOpTypeArray) return; + if (typeInst->opcode() == spv::Op::OpTypeArray) return; // Insert chains are only composed of inserts and phis - if (insertChain->opcode() != SpvOpCompositeInsert && - insertChain->opcode() != SpvOpPhi) + if (insertChain->opcode() != spv::Op::OpCompositeInsert && + insertChain->opcode() != spv::Op::OpPhi) return; // If extract indices are empty, mark all subcomponents if type // is constant length. @@ -89,7 +86,7 @@ void DeadInsertElimPass::MarkInsertChain( } } Instruction* insInst = insertChain; - while (insInst->opcode() == SpvOpCompositeInsert) { + while (insInst->opcode() == spv::Op::OpCompositeInsert) { // If no extract indices, mark insert and inserted object (which might // also be an insert chain) and continue up the chain though the input // composite. @@ -139,7 +136,7 @@ void DeadInsertElimPass::MarkInsertChain( insInst = get_def_use_mgr()->GetDef(compId); } // If insert chain ended with phi, do recursive call on each operand - if (insInst->opcode() != SpvOpPhi) return; + if (insInst->opcode() != spv::Op::OpPhi) return; // Mark phi visited to prevent potential infinite loop. If phi is already // visited, return to avoid infinite loop. if (visited_phis->count(insInst->result_id()) != 0) return; @@ -179,17 +176,17 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { // Only process Inserts and composite Phis - SpvOp op = ii->opcode(); + spv::Op op = ii->opcode(); Instruction* typeInst = get_def_use_mgr()->GetDef(ii->type_id()); - if (op != SpvOpCompositeInsert && - (op != SpvOpPhi || !spvOpcodeIsComposite(typeInst->opcode()))) + if (op != spv::Op::OpCompositeInsert && + (op != spv::Op::OpPhi || !spvOpcodeIsComposite(typeInst->opcode()))) continue; // The marking algorithm can be expensive for large arrays and the // efficacy of eliminating dead inserts into arrays is questionable. // Skip optimizing array inserts for now. Just mark them live. // TODO(greg-lunarg): Eliminate dead array inserts - if (op == SpvOpCompositeInsert) { - if (typeInst->opcode() == SpvOpTypeArray) { + if (op == spv::Op::OpCompositeInsert) { + if (typeInst->opcode() == spv::Op::OpTypeArray) { liveInserts_.insert(ii->result_id()); continue; } @@ -198,11 +195,11 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { get_def_use_mgr()->ForEachUser(id, [&ii, this](Instruction* user) { if (user->IsCommonDebugInstr()) return; switch (user->opcode()) { - case SpvOpCompositeInsert: - case SpvOpPhi: + case spv::Op::OpCompositeInsert: + case spv::Op::OpPhi: // Use by insert or phi does not initiate marking break; - case SpvOpCompositeExtract: { + case spv::Op::OpCompositeExtract: { // Capture extract indices std::vector extIndices; uint32_t icnt = 0; @@ -226,7 +223,7 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { std::vector dead_instructions; for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { - if (ii->opcode() != SpvOpCompositeInsert) continue; + if (ii->opcode() != spv::Op::OpCompositeInsert) continue; const uint32_t id = ii->result_id(); if (liveInserts_.find(id) != liveInserts_.end()) continue; const uint32_t replId = diff --git a/3rdparty/spirv-tools/source/opt/dead_variable_elimination.cpp b/3rdparty/spirv-tools/source/opt/dead_variable_elimination.cpp index 283710684..e39132c22 100644 --- a/3rdparty/spirv-tools/source/opt/dead_variable_elimination.cpp +++ b/3rdparty/spirv-tools/source/opt/dead_variable_elimination.cpp @@ -33,7 +33,7 @@ Pass::Status DeadVariableElimination::Process() { // Get the reference count for all of the global OpVariable instructions. for (auto& inst : context()->types_values()) { - if (inst.opcode() != SpvOp::SpvOpVariable) { + if (inst.opcode() != spv::Op::OpVariable) { continue; } @@ -43,11 +43,11 @@ Pass::Status DeadVariableElimination::Process() { // Check the linkage. If it is exported, it could be reference somewhere // else, so we must keep the variable around. get_decoration_mgr()->ForEachDecoration( - result_id, SpvDecorationLinkageAttributes, + result_id, uint32_t(spv::Decoration::LinkageAttributes), [&count](const Instruction& linkage_instruction) { uint32_t last_operand = linkage_instruction.NumOperands() - 1; - if (linkage_instruction.GetSingleWordOperand(last_operand) == - SpvLinkageTypeExport) { + if (spv::LinkageType(linkage_instruction.GetSingleWordOperand( + last_operand)) == spv::LinkageType::Export) { count = kMustKeep; } }); @@ -57,7 +57,8 @@ Pass::Status DeadVariableElimination::Process() { // at the uses and count the number of real references. count = 0; get_def_use_mgr()->ForEachUser(result_id, [&count](Instruction* user) { - if (!IsAnnotationInst(user->opcode()) && user->opcode() != SpvOpName) { + if (!IsAnnotationInst(user->opcode()) && + user->opcode() != spv::Op::OpName) { ++count; } }); @@ -81,7 +82,7 @@ Pass::Status DeadVariableElimination::Process() { void DeadVariableElimination::DeleteVariable(uint32_t result_id) { Instruction* inst = get_def_use_mgr()->GetDef(result_id); - assert(inst->opcode() == SpvOpVariable && + assert(inst->opcode() == spv::Op::OpVariable && "Should not be trying to delete anything other than an OpVariable."); // Look for an initializer that references another variable. We need to know @@ -93,7 +94,7 @@ void DeadVariableElimination::DeleteVariable(uint32_t result_id) { // TODO: Handle OpSpecConstantOP which might be defined in terms of other // variables. Will probably require a unified dead code pass that does all // instruction types. (Issue 906) - if (initializer->opcode() == SpvOpVariable) { + if (initializer->opcode() == spv::Op::OpVariable) { uint32_t initializer_id = initializer->result_id(); size_t& count = reference_count_[initializer_id]; if (count != kMustKeep) { diff --git a/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp b/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp index 3585186f4..1e614c6ff 100644 --- a/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp +++ b/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp @@ -22,32 +22,31 @@ // Constants for OpenCL.DebugInfo.100 & NonSemantic.Shader.DebugInfo.100 // extension instructions. -static const uint32_t kOpLineOperandLineIndex = 1; -static const uint32_t kLineOperandIndexDebugFunction = 7; -static const uint32_t kLineOperandIndexDebugLexicalBlock = 5; -static const uint32_t kLineOperandIndexDebugLine = 5; -static const uint32_t kDebugFunctionOperandFunctionIndex = 13; -static const uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4; -static const uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5; -static const uint32_t kDebugFunctionOperandParentIndex = 9; -static const uint32_t kDebugTypeCompositeOperandParentIndex = 9; -static const uint32_t kDebugLexicalBlockOperandParentIndex = 7; -static const uint32_t kDebugInlinedAtOperandInlinedIndex = 6; -static const uint32_t kDebugExpressOperandOperationIndex = 4; -static const uint32_t kDebugDeclareOperandLocalVariableIndex = 4; -static const uint32_t kDebugDeclareOperandVariableIndex = 5; -static const uint32_t kDebugValueOperandExpressionIndex = 6; -static const uint32_t kDebugOperationOperandOperationIndex = 4; -static const uint32_t kOpVariableOperandStorageClassIndex = 2; -static const uint32_t kDebugLocalVariableOperandParentIndex = 9; -static const uint32_t kExtInstInstructionInIdx = 1; -static const uint32_t kDebugGlobalVariableOperandFlagsIndex = 12; -static const uint32_t kDebugLocalVariableOperandFlagsIndex = 10; - namespace spvtools { namespace opt { namespace analysis { namespace { +constexpr uint32_t kOpLineOperandLineIndex = 1; +constexpr uint32_t kLineOperandIndexDebugFunction = 7; +constexpr uint32_t kLineOperandIndexDebugLexicalBlock = 5; +constexpr uint32_t kLineOperandIndexDebugLine = 5; +constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13; +constexpr uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4; +constexpr uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5; +constexpr uint32_t kDebugFunctionOperandParentIndex = 9; +constexpr uint32_t kDebugTypeCompositeOperandParentIndex = 9; +constexpr uint32_t kDebugLexicalBlockOperandParentIndex = 7; +constexpr uint32_t kDebugInlinedAtOperandInlinedIndex = 6; +constexpr uint32_t kDebugExpressOperandOperationIndex = 4; +constexpr uint32_t kDebugDeclareOperandLocalVariableIndex = 4; +constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; +constexpr uint32_t kDebugValueOperandExpressionIndex = 6; +constexpr uint32_t kDebugOperationOperandOperationIndex = 4; +constexpr uint32_t kOpVariableOperandStorageClassIndex = 2; +constexpr uint32_t kDebugLocalVariableOperandParentIndex = 9; +constexpr uint32_t kExtInstInstructionInIdx = 1; +constexpr uint32_t kDebugGlobalVariableOperandFlagsIndex = 12; +constexpr uint32_t kDebugLocalVariableOperandFlagsIndex = 10; void SetInlinedOperand(Instruction* dbg_inlined_at, uint32_t inlined_operand) { assert(dbg_inlined_at); @@ -156,7 +155,8 @@ void DebugInfoManager::RegisterDbgDeclare(uint32_t var_id, uint32_t AddNewConstInGlobals(IRContext* context, uint32_t const_value) { uint32_t id = context->TakeNextId(); std::unique_ptr new_const(new Instruction( - context, SpvOpConstant, context->get_type_mgr()->GetUIntTypeId(), id, + context, spv::Op::OpConstant, context->get_type_mgr()->GetUIntTypeId(), + id, { {spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, {const_value}}, @@ -212,7 +212,7 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line, break; } } else { - if (line->opcode() == SpvOpLine) { + if (line->opcode() == spv::Op::OpLine) { line_number = line->GetSingleWordOperand(kOpLineOperandLineIndex); } else if (line->GetShader100DebugOpcode() == NonSemanticShaderDebugInfo100DebugLine) { @@ -230,18 +230,19 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line, // constants that may be generated here is likely not significant // and will likely be cleaned up in later passes. if (line_number_type == spv_operand_type_t::SPV_OPERAND_TYPE_ID && - line->opcode() == SpvOpLine) { + line->opcode() == spv::Op::OpLine) { if (!context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse) || !context()->AreAnalysesValid(IRContext::Analysis::kAnalysisConstants)) line_number = AddNewConstInGlobals(context(), line_number); else - line_number = context()->get_constant_mgr()->GetUIntConst(line_number); + line_number = + context()->get_constant_mgr()->GetUIntConstId(line_number); } } uint32_t result_id = context()->TakeNextId(); std::unique_ptr inlined_at(new Instruction( - context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {setId}}, @@ -334,8 +335,8 @@ Instruction* DebugInfoManager::GetDebugOperationWithDeref() { if (context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) { deref_operation = std::unique_ptr(new Instruction( - context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), - result_id, + context(), spv::Op::OpExtInst, + context()->get_type_mgr()->GetVoidTypeId(), result_id, { {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, @@ -344,11 +345,11 @@ Instruction* DebugInfoManager::GetDebugOperationWithDeref() { {static_cast(OpenCLDebugInfo100Deref)}}, })); } else { - uint32_t deref_id = context()->get_constant_mgr()->GetUIntConst( + uint32_t deref_id = context()->get_constant_mgr()->GetUIntConstId( NonSemanticShaderDebugInfo100Deref); deref_operation = std::unique_ptr( - new Instruction(context(), SpvOpExtInst, + new Instruction(context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -390,7 +391,7 @@ Instruction* DebugInfoManager::GetDebugInfoNone() { uint32_t result_id = context()->TakeNextId(); std::unique_ptr dbg_info_none_inst(new Instruction( - context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -414,7 +415,7 @@ Instruction* DebugInfoManager::GetEmptyDebugExpression() { uint32_t result_id = context()->TakeNextId(); std::unique_ptr empty_debug_expr(new Instruction( - context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -527,7 +528,7 @@ bool DebugInfoManager::IsDeclareVisibleToInstr(Instruction* dbg_declare, assert(scope != nullptr); std::vector scope_ids; - if (scope->opcode() == SpvOpPhi) { + if (scope->opcode() == spv::Op::OpPhi) { scope_ids.push_back(scope->GetDebugScope().GetLexicalScope()); for (uint32_t i = 0; i < scope->NumInOperands(); i += 2) { auto* value = context()->get_def_use_mgr()->GetDef( @@ -571,8 +572,8 @@ bool DebugInfoManager::AddDebugValueForVariable(Instruction* scope_and_line, // Avoid inserting the new DebugValue between OpPhi or OpVariable // instructions. Instruction* insert_before = insert_pos->NextNode(); - while (insert_before->opcode() == SpvOpPhi || - insert_before->opcode() == SpvOpVariable) { + while (insert_before->opcode() == spv::Op::OpPhi || + insert_before->opcode() == spv::Op::OpVariable) { insert_before = insert_before->NextNode(); } modified |= AddDebugValueForDecl(dbg_decl_or_val, value_id, insert_before, @@ -653,9 +654,10 @@ uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare( } auto* var = context()->get_def_use_mgr()->GetDef(var_id); - if (var->opcode() == SpvOpVariable && - SpvStorageClass(var->GetSingleWordOperand( - kOpVariableOperandStorageClassIndex)) == SpvStorageClassFunction) { + if (var->opcode() == spv::Op::OpVariable && + spv::StorageClass( + var->GetSingleWordOperand(kOpVariableOperandStorageClassIndex)) == + spv::StorageClass::Function) { return var_id; } return 0; @@ -762,8 +764,8 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable( CommonDebugInfoDebugGlobalVariable) { return; } - assert(local_var->opcode() == SpvOpVariable || - local_var->opcode() == SpvOpFunctionParameter); + assert(local_var->opcode() == spv::Op::OpVariable || + local_var->opcode() == spv::Op::OpFunctionParameter); // Convert |dbg_global_var| to DebugLocalVariable dbg_global_var->SetInOperand(kExtInstInstructionInIdx, @@ -780,7 +782,7 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable( // Create a DebugDeclare std::unique_ptr new_dbg_decl(new Instruction( - context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), context()->TakeNextId(), { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -794,7 +796,7 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable( })); // Must insert after all OpVariables in block Instruction* insert_before = local_var; - while (insert_before->opcode() == SpvOpVariable) + while (insert_before->opcode() == spv::Op::OpVariable) insert_before = insert_before->NextNode(); auto* added_dbg_decl = insert_before->InsertBefore(std::move(new_dbg_decl)); if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) diff --git a/3rdparty/spirv-tools/source/opt/decoration_manager.cpp b/3rdparty/spirv-tools/source/opt/decoration_manager.cpp index 2146c359d..1393d480e 100644 --- a/3rdparty/spirv-tools/source/opt/decoration_manager.cpp +++ b/3rdparty/spirv-tools/source/opt/decoration_manager.cpp @@ -22,6 +22,9 @@ #include "source/opt/ir_context.h" +namespace spvtools { +namespace opt { +namespace analysis { namespace { using InstructionVector = std::vector; using DecorationSet = std::set; @@ -49,10 +52,6 @@ bool IsSubset(const DecorationSet& a, const DecorationSet& b) { } } // namespace -namespace spvtools { -namespace opt { -namespace analysis { - bool DecorationManager::RemoveDecorationsFrom( uint32_t id, std::function pred) { bool was_modified = false; @@ -76,8 +75,8 @@ bool DecorationManager::RemoveDecorationsFrom( // applying the group. std::unordered_set indirect_decorations_to_remove; for (Instruction* inst : decorations_info.indirect_decorations) { - assert(inst->opcode() == SpvOpGroupDecorate || - inst->opcode() == SpvOpGroupMemberDecorate); + assert(inst->opcode() == spv::Op::OpGroupDecorate || + inst->opcode() == spv::Op::OpGroupMemberDecorate); std::vector group_decorations_to_keep; const uint32_t group_id = inst->GetSingleWordInOperand(0u); @@ -99,7 +98,8 @@ bool DecorationManager::RemoveDecorationsFrom( } // Otherwise, remove |id| from the targets of |group_id| - const uint32_t stride = inst->opcode() == SpvOpGroupDecorate ? 1u : 2u; + const uint32_t stride = + inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; for (uint32_t i = 1u; i < inst->NumInOperands();) { if (inst->GetSingleWordInOperand(i) != id) { i += stride; @@ -212,16 +212,16 @@ bool DecorationManager::HaveTheSameDecorations(uint32_t id1, } switch (inst->opcode()) { - case SpvOpDecorate: + case spv::Op::OpDecorate: decorate_set->emplace(std::move(decoration_payload)); break; - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: member_decorate_set->emplace(std::move(decoration_payload)); break; - case SpvOpDecorateId: + case spv::Op::OpDecorateId: decorate_id_set->emplace(std::move(decoration_payload)); break; - case SpvOpDecorateStringGOOGLE: + case spv::Op::OpDecorateStringGOOGLE: decorate_string_set->emplace(std::move(decoration_payload)); break; default: @@ -278,16 +278,16 @@ bool DecorationManager::HaveSubsetOfDecorations(uint32_t id1, } switch (inst->opcode()) { - case SpvOpDecorate: + case spv::Op::OpDecorate: decorate_set->emplace(std::move(decoration_payload)); break; - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: member_decorate_set->emplace(std::move(decoration_payload)); break; - case SpvOpDecorateId: + case spv::Op::OpDecorateId: decorate_id_set->emplace(std::move(decoration_payload)); break; - case SpvOpDecorateStringGOOGLE: + case spv::Op::OpDecorateStringGOOGLE: decorate_string_set->emplace(std::move(decoration_payload)); break; default: @@ -328,10 +328,10 @@ bool DecorationManager::AreDecorationsTheSame(const Instruction* inst1, const Instruction* inst2, bool ignore_target) const { switch (inst1->opcode()) { - case SpvOpDecorate: - case SpvOpMemberDecorate: - case SpvOpDecorateId: - case SpvOpDecorateStringGOOGLE: + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: break; default: return false; @@ -358,17 +358,18 @@ void DecorationManager::AnalyzeDecorations() { void DecorationManager::AddDecoration(Instruction* inst) { switch (inst->opcode()) { - case SpvOpDecorate: - case SpvOpDecorateId: - case SpvOpDecorateStringGOOGLE: - case SpvOpMemberDecorate: { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorate: { const auto target_id = inst->GetSingleWordInOperand(0u); id_to_decoration_insts_[target_id].direct_decorations.push_back(inst); break; } - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: { - const uint32_t start = inst->opcode() == SpvOpGroupDecorate ? 1u : 2u; + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: { + const uint32_t start = + inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; const uint32_t stride = start; for (uint32_t i = start; i < inst->NumInOperands(); i += stride) { const auto target_id = inst->GetSingleWordInOperand(i); @@ -384,7 +385,7 @@ void DecorationManager::AddDecoration(Instruction* inst) { } } -void DecorationManager::AddDecoration(SpvOp opcode, +void DecorationManager::AddDecoration(spv::Op opcode, std::vector opnds) { IRContext* ctx = module_->context(); std::unique_ptr newDecoOp( @@ -394,7 +395,7 @@ void DecorationManager::AddDecoration(SpvOp opcode, void DecorationManager::AddDecoration(uint32_t inst_id, uint32_t decoration) { AddDecoration( - SpvOpDecorate, + spv::Op::OpDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}}); } @@ -402,7 +403,7 @@ void DecorationManager::AddDecoration(uint32_t inst_id, uint32_t decoration) { void DecorationManager::AddDecorationVal(uint32_t inst_id, uint32_t decoration, uint32_t decoration_value) { AddDecoration( - SpvOpDecorate, + spv::Op::OpDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -413,7 +414,7 @@ void DecorationManager::AddMemberDecoration(uint32_t inst_id, uint32_t member, uint32_t decoration, uint32_t decoration_value) { AddDecoration( - SpvOpMemberDecorate, + spv::Op::OpMemberDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {member}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}, @@ -436,9 +437,10 @@ std::vector DecorationManager::InternalGetDecorationsFor( [include_linkage, &decorations](const std::vector& direct_decorations) { for (Instruction* inst : direct_decorations) { - const bool is_linkage = inst->opcode() == SpvOpDecorate && - inst->GetSingleWordInOperand(1u) == - SpvDecorationLinkageAttributes; + const bool is_linkage = + inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(inst->GetSingleWordInOperand(1u)) == + spv::Decoration::LinkageAttributes; if (include_linkage || !is_linkage) decorations.push_back(inst); } }; @@ -462,14 +464,14 @@ bool DecorationManager::WhileEachDecoration( std::function f) { for (const Instruction* inst : GetDecorationsFor(id, true)) { switch (inst->opcode()) { - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: if (inst->GetSingleWordInOperand(2) == decoration) { if (!f(*inst)) return false; } break; - case SpvOpDecorate: - case SpvOpDecorateId: - case SpvOpDecorateStringGOOGLE: + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: if (inst->GetSingleWordInOperand(1) == decoration) { if (!f(*inst)) return false; } @@ -523,14 +525,14 @@ void DecorationManager::CloneDecorations(uint32_t from, uint32_t to) { decoration_list->second.indirect_decorations; for (Instruction* inst : indirect_decorations) { switch (inst->opcode()) { - case SpvOpGroupDecorate: + case spv::Op::OpGroupDecorate: context->ForgetUses(inst); // add |to| to list of decorated id's inst->AddOperand( Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to})); context->AnalyzeUses(inst); break; - case SpvOpGroupMemberDecorate: { + case spv::Op::OpGroupMemberDecorate: { context->ForgetUses(inst); // for each (id == from), add (to, literal) as operands const uint32_t num_operands = inst->NumOperands(); @@ -554,13 +556,13 @@ void DecorationManager::CloneDecorations(uint32_t from, uint32_t to) { void DecorationManager::CloneDecorations( uint32_t from, uint32_t to, - const std::vector& decorations_to_copy) { + const std::vector& decorations_to_copy) { const auto decoration_list = id_to_decoration_insts_.find(from); if (decoration_list == id_to_decoration_insts_.end()) return; auto context = module_->context(); for (Instruction* inst : decoration_list->second.direct_decorations) { if (std::find(decorations_to_copy.begin(), decorations_to_copy.end(), - inst->GetSingleWordInOperand(1)) == + spv::Decoration(inst->GetSingleWordInOperand(1))) == decorations_to_copy.end()) { continue; } @@ -579,11 +581,11 @@ void DecorationManager::CloneDecorations( decoration_list->second.indirect_decorations; for (Instruction* inst : indirect_decorations) { switch (inst->opcode()) { - case SpvOpGroupDecorate: + case spv::Op::OpGroupDecorate: CloneDecorations(inst->GetSingleWordInOperand(0), to, decorations_to_copy); break; - case SpvOpGroupMemberDecorate: { + case spv::Op::OpGroupMemberDecorate: { assert(false && "The source id is not suppose to be a type."); break; } @@ -599,18 +601,19 @@ void DecorationManager::RemoveDecoration(Instruction* inst) { }; switch (inst->opcode()) { - case SpvOpDecorate: - case SpvOpDecorateId: - case SpvOpDecorateStringGOOGLE: - case SpvOpMemberDecorate: { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorate: { const auto target_id = inst->GetSingleWordInOperand(0u); auto const iter = id_to_decoration_insts_.find(target_id); if (iter == id_to_decoration_insts_.end()) return; remove_from_container(iter->second.direct_decorations); } break; - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: { - const uint32_t stride = inst->opcode() == SpvOpGroupDecorate ? 1u : 2u; + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: { + const uint32_t stride = + inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; for (uint32_t i = 1u; i < inst->NumInOperands(); i += stride) { const auto target_id = inst->GetSingleWordInOperand(i); auto const iter = id_to_decoration_insts_.find(target_id); diff --git a/3rdparty/spirv-tools/source/opt/decoration_manager.h b/3rdparty/spirv-tools/source/opt/decoration_manager.h index fe78f2ce6..1a0d1b183 100644 --- a/3rdparty/spirv-tools/source/opt/decoration_manager.h +++ b/3rdparty/spirv-tools/source/opt/decoration_manager.h @@ -71,14 +71,14 @@ class DecorationManager { bool include_linkage); std::vector GetDecorationsFor(uint32_t id, bool include_linkage) const; - // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate - // instructions that apply the same decorations but to different IDs, still - // count as being the same. + // Returns whether two IDs have the same decorations. Two + // spv::Op::OpGroupDecorate instructions that apply the same decorations but + // to different IDs, still count as being the same. bool HaveTheSameDecorations(uint32_t id1, uint32_t id2) const; - // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate - // instructions that apply the same decorations but to different IDs, still - // count as being the same. + // Returns whether two IDs have the same decorations. Two + // spv::Op::OpGroupDecorate instructions that apply the same decorations but + // to different IDs, still count as being the same. bool HaveSubsetOfDecorations(uint32_t id1, uint32_t id2) const; // Returns whether the two decorations instructions are the same and are @@ -123,14 +123,15 @@ class DecorationManager { // Same as above, but only clone the decoration if the decoration operand is // in |decorations_to_copy|. This function has the extra restriction that // |from| and |to| must not be an object, not a type. - void CloneDecorations(uint32_t from, uint32_t to, - const std::vector& decorations_to_copy); + void CloneDecorations( + uint32_t from, uint32_t to, + const std::vector& decorations_to_copy); // Informs the decoration manager of a new decoration that it needs to track. void AddDecoration(Instruction* inst); // Add decoration with |opcode| and operands |opnds|. - void AddDecoration(SpvOp opcode, const std::vector opnds); + void AddDecoration(spv::Op opcode, const std::vector opnds); // Add |decoration| of |inst_id| to module. void AddDecoration(uint32_t inst_id, uint32_t decoration); @@ -195,9 +196,9 @@ class DecorationManager { // Mapping from ids to the instructions applying a decoration to those ids. // In other words, for each id you get all decoration instructions - // referencing that id, be it directly (SpvOpDecorate, SpvOpMemberDecorate - // and SpvOpDecorateId), or indirectly (SpvOpGroupDecorate, - // SpvOpMemberGroupDecorate). + // referencing that id, be it directly (spv::Op::OpDecorate, + // spv::Op::OpMemberDecorate and spv::Op::OpDecorateId), or indirectly + // (spv::Op::OpGroupDecorate, spv::Op::OpMemberGroupDecorate). std::unordered_map id_to_decoration_insts_; // The enclosing module. Module* module_; diff --git a/3rdparty/spirv-tools/source/opt/desc_sroa.cpp b/3rdparty/spirv-tools/source/opt/desc_sroa.cpp index b130ca806..8da0c864f 100644 --- a/3rdparty/spirv-tools/source/opt/desc_sroa.cpp +++ b/3rdparty/spirv-tools/source/opt/desc_sroa.cpp @@ -22,8 +22,9 @@ namespace opt { namespace { bool IsDecorationBinding(Instruction* inst) { - if (inst->opcode() != SpvOpDecorate) return false; - return inst->GetSingleWordInOperand(1u) == SpvDecorationBinding; + if (inst->opcode() != spv::Op::OpDecorate) return false; + return spv::Decoration(inst->GetSingleWordInOperand(1u)) == + spv::Decoration::Binding; } } // namespace @@ -56,7 +57,7 @@ bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) { bool failed = !get_def_use_mgr()->WhileEachUser( var->result_id(), [this, &access_chain_work_list, &load_work_list](Instruction* use) { - if (use->opcode() == SpvOpName) { + if (use->opcode() == spv::Op::OpName) { return true; } @@ -65,11 +66,11 @@ bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) { } switch (use->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: access_chain_work_list.push_back(use); return true; - case SpvOpLoad: + case spv::Op::OpLoad: load_work_list.push_back(use); return true; default: @@ -184,7 +185,7 @@ void DescriptorScalarReplacement::CopyDecorationsForNewVariable( // Handle OpMemberDecorate instructions. for (auto old_decoration : get_decoration_mgr()->GetDecorationsFor( old_var_type->result_id(), true)) { - assert(old_decoration->opcode() == SpvOpMemberDecorate); + assert(old_decoration->opcode() == spv::Op::OpMemberDecorate); if (old_decoration->GetSingleWordInOperand(1u) != index) continue; CreateNewDecorationForMemberDecorate(old_decoration, new_var_id); } @@ -212,8 +213,8 @@ uint32_t DescriptorScalarReplacement::GetNewBindingForElement( void DescriptorScalarReplacement::CreateNewDecorationForNewVariable( Instruction* old_decoration, uint32_t new_var_id, uint32_t new_binding) { - assert(old_decoration->opcode() == SpvOpDecorate || - old_decoration->opcode() == SpvOpDecorateString); + assert(old_decoration->opcode() == spv::Op::OpDecorate || + old_decoration->opcode() == spv::Op::OpDecorateString); std::unique_ptr new_decoration(old_decoration->Clone(context())); new_decoration->SetInOperand(0, {new_var_id}); @@ -231,25 +232,25 @@ void DescriptorScalarReplacement::CreateNewDecorationForMemberDecorate( auto new_decorate_operand_end = old_member_decoration->end(); operands.insert(operands.end(), new_decorate_operand_begin, new_decorate_operand_end); - get_decoration_mgr()->AddDecoration(SpvOpDecorate, std::move(operands)); + get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, std::move(operands)); } uint32_t DescriptorScalarReplacement::CreateReplacementVariable( Instruction* var, uint32_t idx) { // The storage class for the new variable is the same as the original. - SpvStorageClass storage_class = - static_cast(var->GetSingleWordInOperand(0)); + spv::StorageClass storage_class = + static_cast(var->GetSingleWordInOperand(0)); // The type for the new variable will be a pointer to type of the elements of // the array. uint32_t ptr_type_id = var->type_id(); Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == SpvOpTypePointer && + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && "Variable should be a pointer to an array or structure."); uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1); Instruction* pointee_type_inst = get_def_use_mgr()->GetDef(pointee_type_id); - const bool is_array = pointee_type_inst->opcode() == SpvOpTypeArray; - const bool is_struct = pointee_type_inst->opcode() == SpvOpTypeStruct; + const bool is_array = pointee_type_inst->opcode() == spv::Op::OpTypeArray; + const bool is_struct = pointee_type_inst->opcode() == spv::Op::OpTypeStruct; assert((is_array || is_struct) && "Variable should be a pointer to an array or structure."); @@ -263,7 +264,7 @@ uint32_t DescriptorScalarReplacement::CreateReplacementVariable( // Create the variable. uint32_t id = TakeNextId(); std::unique_ptr variable( - new Instruction(context(), SpvOpVariable, ptr_element_type_id, id, + new Instruction(context(), spv::Op::OpVariable, ptr_element_type_id, id, std::initializer_list{ {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(storage_class)}}})); @@ -293,7 +294,7 @@ uint32_t DescriptorScalarReplacement::CreateReplacementVariable( } std::unique_ptr new_name(new Instruction( - context(), SpvOpName, 0, 0, + context(), spv::Op::OpName, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {id}}, {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}})); @@ -315,14 +316,14 @@ uint32_t DescriptorScalarReplacement::GetNumBindingsUsedByType( Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); // If it's a pointer, look at the underlying type. - if (type_inst->opcode() == SpvOpTypePointer) { + if (type_inst->opcode() == spv::Op::OpTypePointer) { type_id = type_inst->GetSingleWordInOperand(1); type_inst = get_def_use_mgr()->GetDef(type_id); } // Arrays consume N*M binding numbers where N is the array length, and M is // the number of bindings used by each array element. - if (type_inst->opcode() == SpvOpTypeArray) { + if (type_inst->opcode() == spv::Op::OpTypeArray) { uint32_t element_type_id = type_inst->GetSingleWordInOperand(0); uint32_t length_id = type_inst->GetSingleWordInOperand(1); const analysis::Constant* length_const = @@ -335,7 +336,7 @@ uint32_t DescriptorScalarReplacement::GetNumBindingsUsedByType( // The number of bindings consumed by a structure is the sum of the bindings // used by its members. - if (type_inst->opcode() == SpvOpTypeStruct && + if (type_inst->opcode() == spv::Op::OpTypeStruct && !descsroautil::IsTypeOfStructuredBuffer(context(), type_inst)) { uint32_t sum = 0; for (uint32_t i = 0; i < type_inst->NumInOperands(); i++) @@ -353,12 +354,12 @@ bool DescriptorScalarReplacement::ReplaceLoadedValue(Instruction* var, // |value| is the OpLoad instruction that has loaded |var|. // The function expects all users of |value| to be OpCompositeExtract // instructions. Otherwise the function returns false with an error message. - assert(value->opcode() == SpvOpLoad); + assert(value->opcode() == spv::Op::OpLoad); assert(value->GetSingleWordInOperand(0) == var->result_id()); std::vector work_list; bool failed = !get_def_use_mgr()->WhileEachUser( value->result_id(), [this, &work_list](Instruction* use) { - if (use->opcode() != SpvOpCompositeExtract) { + if (use->opcode() != spv::Op::OpCompositeExtract) { context()->EmitErrorMessage( "Variable cannot be replaced: invalid instruction", use); return false; @@ -384,7 +385,7 @@ bool DescriptorScalarReplacement::ReplaceLoadedValue(Instruction* var, bool DescriptorScalarReplacement::ReplaceCompositeExtract( Instruction* var, Instruction* extract) { - assert(extract->opcode() == SpvOpCompositeExtract); + assert(extract->opcode() == spv::Op::OpCompositeExtract); // We're currently only supporting extractions of one index at a time. If we // need to, we can handle cases with multiple indexes in the future. if (extract->NumInOperands() != 2) { @@ -400,7 +401,7 @@ bool DescriptorScalarReplacement::ReplaceCompositeExtract( // OpCompositeExtract. uint32_t load_id = TakeNextId(); std::unique_ptr load( - new Instruction(context(), SpvOpLoad, extract->type_id(), load_id, + new Instruction(context(), spv::Op::OpLoad, extract->type_id(), load_id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {replacement_var}}})); Instruction* load_instr = load.get(); diff --git a/3rdparty/spirv-tools/source/opt/desc_sroa_util.cpp b/3rdparty/spirv-tools/source/opt/desc_sroa_util.cpp index 1954e2cc3..dba3de9c0 100644 --- a/3rdparty/spirv-tools/source/opt/desc_sroa_util.cpp +++ b/3rdparty/spirv-tools/source/opt/desc_sroa_util.cpp @@ -17,12 +17,11 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kOpAccessChainInOperandIndexes = 1; +constexpr uint32_t kOpAccessChainInOperandIndexes = 1; // Returns the length of array type |type|. uint32_t GetLengthOfArrayType(IRContext* context, Instruction* type) { - assert(type->opcode() == SpvOpTypeArray && "type must be array"); + assert(type->opcode() == spv::Op::OpTypeArray && "type must be array"); uint32_t length_id = type->GetSingleWordInOperand(1); const analysis::Constant* length_const = context->get_constant_mgr()->FindDeclaredConstant(length_id); @@ -35,20 +34,20 @@ uint32_t GetLengthOfArrayType(IRContext* context, Instruction* type) { namespace descsroautil { bool IsDescriptorArray(IRContext* context, Instruction* var) { - if (var->opcode() != SpvOpVariable) { + if (var->opcode() != spv::Op::OpVariable) { return false; } uint32_t ptr_type_id = var->type_id(); Instruction* ptr_type_inst = context->get_def_use_mgr()->GetDef(ptr_type_id); - if (ptr_type_inst->opcode() != SpvOpTypePointer) { + if (ptr_type_inst->opcode() != spv::Op::OpTypePointer) { return false; } uint32_t var_type_id = ptr_type_inst->GetSingleWordInOperand(1); Instruction* var_type_inst = context->get_def_use_mgr()->GetDef(var_type_id); - if (var_type_inst->opcode() != SpvOpTypeArray && - var_type_inst->opcode() != SpvOpTypeStruct) { + if (var_type_inst->opcode() != spv::Op::OpTypeArray && + var_type_inst->opcode() != spv::Op::OpTypeStruct) { return false; } @@ -59,23 +58,23 @@ bool IsDescriptorArray(IRContext* context, Instruction* var) { } if (!context->get_decoration_mgr()->HasDecoration( - var->result_id(), SpvDecorationDescriptorSet)) { + var->result_id(), uint32_t(spv::Decoration::DescriptorSet))) { return false; } - return context->get_decoration_mgr()->HasDecoration(var->result_id(), - SpvDecorationBinding); + return context->get_decoration_mgr()->HasDecoration( + var->result_id(), uint32_t(spv::Decoration::Binding)); } bool IsTypeOfStructuredBuffer(IRContext* context, const Instruction* type) { - if (type->opcode() != SpvOpTypeStruct) { + if (type->opcode() != spv::Op::OpTypeStruct) { return false; } // All buffers have offset decorations for members of their structure types. // This is how we distinguish it from a structure of descriptors. - return context->get_decoration_mgr()->HasDecoration(type->result_id(), - SpvDecorationOffset); + return context->get_decoration_mgr()->HasDecoration( + type->result_id(), uint32_t(spv::Decoration::Offset)); } const analysis::Constant* GetAccessChainIndexAsConst( @@ -99,15 +98,15 @@ uint32_t GetNumberOfElementsForArrayOrStruct(IRContext* context, Instruction* var) { uint32_t ptr_type_id = var->type_id(); Instruction* ptr_type_inst = context->get_def_use_mgr()->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == SpvOpTypePointer && + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && "Variable should be a pointer to an array or structure."); uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1); Instruction* pointee_type_inst = context->get_def_use_mgr()->GetDef(pointee_type_id); - if (pointee_type_inst->opcode() == SpvOpTypeArray) { + if (pointee_type_inst->opcode() == spv::Op::OpTypeArray) { return GetLengthOfArrayType(context, pointee_type_inst); } - assert(pointee_type_inst->opcode() == SpvOpTypeStruct && + assert(pointee_type_inst->opcode() == spv::Op::OpTypeStruct && "Variable should be a pointer to an array or structure."); return pointee_type_inst->NumInOperands(); } diff --git a/3rdparty/spirv-tools/source/opt/dominator_analysis.cpp b/3rdparty/spirv-tools/source/opt/dominator_analysis.cpp index b692d26a2..eb6dfc9e0 100644 --- a/3rdparty/spirv-tools/source/opt/dominator_analysis.cpp +++ b/3rdparty/spirv-tools/source/opt/dominator_analysis.cpp @@ -64,7 +64,7 @@ bool DominatorAnalysisBase::Dominates(Instruction* a, Instruction* b) const { // We handle OpLabel instructions explicitly since they are not stored in the // instruction list. - if (current->opcode() == SpvOpLabel) { + if (current->opcode() == spv::Op::OpLabel) { return true; } diff --git a/3rdparty/spirv-tools/source/opt/dominator_tree.cpp b/3rdparty/spirv-tools/source/opt/dominator_tree.cpp index 2680be2af..3c161a9b2 100644 --- a/3rdparty/spirv-tools/source/opt/dominator_tree.cpp +++ b/3rdparty/spirv-tools/source/opt/dominator_tree.cpp @@ -55,8 +55,8 @@ namespace { // called on each node traversed BEFORE their children. template -static void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, - PreLambda pre, PostLambda post) { +void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, + PreLambda pre, PostLambda post) { auto no_terminal_blocks = [](const BBType*) { return false; }; CFA::DepthFirstTraversal(bb, successors, pre, post, no_terminal_blocks); @@ -73,9 +73,8 @@ static void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, // PostLambda - Lamdba matching the signature of 'void (const BBType*)' will be // called on each node traversed after their children. template -static void DepthFirstSearchPostOrder(const BBType* bb, - SuccessorLambda successors, - PostLambda post) { +void DepthFirstSearchPostOrder(const BBType* bb, SuccessorLambda successors, + PostLambda post) { // Ignore preorder operation. auto nop_preorder = [](const BBType*) {}; DepthFirstSearch(bb, successors, nop_preorder, post); diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp b/3rdparty/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp index d368bd145..d02151560 100644 --- a/3rdparty/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp @@ -40,7 +40,7 @@ Pass::Status EliminateDeadConstantPass::Process() { context()->get_def_use_mgr()->ForEachUse( const_id, [&count](Instruction* user, uint32_t index) { (void)index; - SpvOp op = user->opcode(); + spv::Op op = user->opcode(); if (!(IsAnnotationInst(op) || IsDebug1Inst(op) || IsDebug2Inst(op) || IsDebug3Inst(op))) { ++count; @@ -59,9 +59,9 @@ Pass::Status EliminateDeadConstantPass::Process() { Instruction* inst = *working_list.begin(); // Back propagate if the instruction contains IDs in its operands. switch (inst->opcode()) { - case SpvOp::SpvOpConstantComposite: - case SpvOp::SpvOpSpecConstantComposite: - case SpvOp::SpvOpSpecConstantOp: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantOp: for (uint32_t i = 0; i < inst->NumInOperands(); i++) { // SpecConstantOp instruction contains 'opcode' as its operand. Need // to exclude such operands when decreasing uses. diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_functions_util.cpp b/3rdparty/spirv-tools/source/opt/eliminate_dead_functions_util.cpp index 1379120ff..cf7f92f55 100644 --- a/3rdparty/spirv-tools/source/opt/eliminate_dead_functions_util.cpp +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_functions_util.cpp @@ -28,12 +28,12 @@ Module::iterator EliminateFunction(IRContext* context, ->ForEachInst( [context, first_func, func_iter, &seen_func_end, &to_kill](Instruction* inst) { - if (inst->opcode() == SpvOpFunctionEnd) { + if (inst->opcode() == spv::Op::OpFunctionEnd) { seen_func_end = true; } // Move non-semantic instructions to the previous function or // global values if this is the first function. - if (seen_func_end && inst->opcode() == SpvOpExtInst) { + if (seen_func_end && inst->opcode() == spv::Op::OpExtInst) { assert(inst->IsNonSemanticInstruction()); if (to_kill.find(inst) != to_kill.end()) return; std::unique_ptr clone(inst->Clone(context)); diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.cpp b/3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.cpp deleted file mode 100644 index aa2776bbd..000000000 --- a/3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "source/opt/eliminate_dead_input_components_pass.h" - -#include -#include - -#include "source/opt/instruction.h" -#include "source/opt/ir_builder.h" -#include "source/opt/ir_context.h" -#include "source/util/bit_vector.h" - -namespace { - -const uint32_t kAccessChainBaseInIdx = 0; -const uint32_t kAccessChainIndex0InIdx = 1; -const uint32_t kConstantValueInIdx = 0; -const uint32_t kVariableStorageClassInIdx = 0; - -} // namespace - -namespace spvtools { -namespace opt { - -Pass::Status EliminateDeadInputComponentsPass::Process() { - // Current functionality assumes shader capability - if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) - return Status::SuccessWithoutChange; - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - bool modified = false; - std::vector> arrays_to_change; - for (auto& var : context()->types_values()) { - if (var.opcode() != SpvOpVariable) { - continue; - } - analysis::Type* var_type = type_mgr->GetType(var.type_id()); - analysis::Pointer* ptr_type = var_type->AsPointer(); - if (ptr_type == nullptr) { - continue; - } - if (ptr_type->storage_class() != SpvStorageClassInput) { - continue; - } - const analysis::Array* arr_type = ptr_type->pointee_type()->AsArray(); - if (arr_type != nullptr) { - unsigned arr_len_id = arr_type->LengthId(); - Instruction* arr_len_inst = def_use_mgr->GetDef(arr_len_id); - if (arr_len_inst->opcode() != SpvOpConstant) { - continue; - } - // SPIR-V requires array size is >= 1, so this works for signed or - // unsigned size - unsigned original_max = - arr_len_inst->GetSingleWordInOperand(kConstantValueInIdx) - 1; - unsigned max_idx = FindMaxIndex(var, original_max); - if (max_idx != original_max) { - ChangeArrayLength(var, max_idx + 1); - modified = true; - } - continue; - } - const analysis::Struct* struct_type = ptr_type->pointee_type()->AsStruct(); - if (struct_type == nullptr) continue; - const auto elt_types = struct_type->element_types(); - unsigned original_max = static_cast(elt_types.size()) - 1; - unsigned max_idx = FindMaxIndex(var, original_max); - if (max_idx != original_max) { - ChangeStructLength(var, max_idx + 1); - modified = true; - } - } - - return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; -} - -unsigned EliminateDeadInputComponentsPass::FindMaxIndex(Instruction& var, - unsigned original_max) { - unsigned max = 0; - bool seen_non_const_ac = false; - assert(var.opcode() == SpvOpVariable && "must be variable"); - context()->get_def_use_mgr()->WhileEachUser( - var.result_id(), [&max, &seen_non_const_ac, var, this](Instruction* use) { - auto use_opcode = use->opcode(); - if (use_opcode == SpvOpLoad || use_opcode == SpvOpCopyMemory || - use_opcode == SpvOpCopyMemorySized || - use_opcode == SpvOpCopyObject) { - seen_non_const_ac = true; - return false; - } - if (use->opcode() != SpvOpAccessChain && - use->opcode() != SpvOpInBoundsAccessChain) { - return true; - } - // OpAccessChain with no indices currently not optimized - if (use->NumInOperands() == 1) { - seen_non_const_ac = true; - return false; - } - unsigned base_id = use->GetSingleWordInOperand(kAccessChainBaseInIdx); - USE_ASSERT(base_id == var.result_id() && "unexpected base"); - unsigned idx_id = use->GetSingleWordInOperand(kAccessChainIndex0InIdx); - Instruction* idx_inst = context()->get_def_use_mgr()->GetDef(idx_id); - if (idx_inst->opcode() != SpvOpConstant) { - seen_non_const_ac = true; - return false; - } - unsigned value = idx_inst->GetSingleWordInOperand(kConstantValueInIdx); - if (value > max) max = value; - return true; - }); - return seen_non_const_ac ? original_max : max; -} - -void EliminateDeadInputComponentsPass::ChangeArrayLength(Instruction& arr_var, - unsigned length) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::Pointer* ptr_type = - type_mgr->GetType(arr_var.type_id())->AsPointer(); - const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray(); - assert(arr_ty && "expecting array type"); - uint32_t length_id = const_mgr->GetUIntConst(length); - analysis::Array new_arr_ty(arr_ty->element_type(), - arr_ty->GetConstantLengthInfo(length_id, length)); - analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty); - analysis::Pointer new_ptr_ty(reg_new_arr_ty, SpvStorageClassInput); - analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); - uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); - arr_var.SetResultType(new_ptr_ty_id); - def_use_mgr->AnalyzeInstUse(&arr_var); - // Move arr_var after its new type to preserve order - USE_ASSERT(arr_var.GetSingleWordInOperand(kVariableStorageClassInIdx) != - SpvStorageClassFunction && - "cannot move Function variable"); - Instruction* new_ptr_ty_inst = def_use_mgr->GetDef(new_ptr_ty_id); - arr_var.RemoveFromList(); - arr_var.InsertAfter(new_ptr_ty_inst); -} - -void EliminateDeadInputComponentsPass::ChangeStructLength( - Instruction& struct_var, unsigned length) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::Pointer* ptr_type = - type_mgr->GetType(struct_var.type_id())->AsPointer(); - const analysis::Struct* struct_ty = ptr_type->pointee_type()->AsStruct(); - assert(struct_ty && "expecting struct type"); - const auto orig_elt_types = struct_ty->element_types(); - std::vector new_elt_types; - for (unsigned u = 0; u < length; ++u) - new_elt_types.push_back(orig_elt_types[u]); - analysis::Struct new_struct_ty(new_elt_types); - analysis::Type* reg_new_struct_ty = - type_mgr->GetRegisteredType(&new_struct_ty); - uint32_t new_struct_ty_id = type_mgr->GetTypeInstruction(reg_new_struct_ty); - uint32_t old_struct_ty_id = type_mgr->GetTypeInstruction(struct_ty); - analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); - deco_mgr->CloneDecorations(old_struct_ty_id, new_struct_ty_id); - analysis::Pointer new_ptr_ty(reg_new_struct_ty, SpvStorageClassInput); - analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); - uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); - struct_var.SetResultType(new_ptr_ty_id); - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - def_use_mgr->AnalyzeInstUse(&struct_var); - // Move struct_var after its new type to preserve order - USE_ASSERT(struct_var.GetSingleWordInOperand(kVariableStorageClassInIdx) != - SpvStorageClassFunction && - "cannot move Function variable"); - Instruction* new_ptr_ty_inst = def_use_mgr->GetDef(new_ptr_ty_id); - struct_var.RemoveFromList(); - struct_var.InsertAfter(new_ptr_ty_inst); -} - -} // namespace opt -} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp b/3rdparty/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp new file mode 100644 index 000000000..916fc27a3 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp @@ -0,0 +1,258 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_io_components_pass.h" + +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kAccessChainBaseInIdx = 0; +constexpr uint32_t kAccessChainIndex0InIdx = 1; +constexpr uint32_t kAccessChainIndex1InIdx = 2; +constexpr uint32_t kConstantValueInIdx = 0; +} // namespace + +Pass::Status EliminateDeadIOComponentsPass::Process() { + // Only process input and output variables + if (elim_sclass_ != spv::StorageClass::Input && + elim_sclass_ != spv::StorageClass::Output) { + if (consumer()) { + std::string message = + "EliminateDeadIOComponentsPass only valid for input and output " + "variables."; + consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); + } + return Status::Failure; + } + // If safe mode, only process Input variables in vertex shader + const auto stage = context()->GetStage(); + if (safe_mode_ && !(stage == spv::ExecutionModel::Vertex && + elim_sclass_ == spv::StorageClass::Input)) + return Status::SuccessWithoutChange; + // Current functionality assumes shader capability. + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + // Current functionality assumes vert, frag, tesc, tese or geom shader. + // TODO(issue #4988): Add GLCompute. + if (stage != spv::ExecutionModel::Vertex && + stage != spv::ExecutionModel::Fragment && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::Geometry) + return Status::SuccessWithoutChange; + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + bool modified = false; + std::vector vars_to_move; + for (auto& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type == nullptr) { + continue; + } + const auto sclass = ptr_type->storage_class(); + if (sclass != elim_sclass_) { + continue; + } + // For tesc, or input variables in tese or geom shaders, + // there is a outer per-vertex-array that must be ignored + // for the purposes of this analysis/optimization. Do the + // analysis on the inner type in these cases. + bool skip_first_index = false; + auto core_type = ptr_type->pointee_type(); + if (stage == spv::ExecutionModel::TessellationControl || + (sclass == spv::StorageClass::Input && + (stage == spv::ExecutionModel::TessellationEvaluation || + stage == spv::ExecutionModel::Geometry))) { + auto arr_type = core_type->AsArray(); + if (!arr_type) continue; + core_type = arr_type->element_type(); + skip_first_index = true; + } + const analysis::Array* arr_type = core_type->AsArray(); + if (arr_type != nullptr) { + // Only process array if input of vertex shader, or output of + // fragment shader. Otherwise, if one shader has a runtime index and the + // other does not, interface incompatibility can occur. + if (!((sclass == spv::StorageClass::Input && + stage == spv::ExecutionModel::Vertex) || + (sclass == spv::StorageClass::Output && + stage == spv::ExecutionModel::Fragment))) + continue; + unsigned arr_len_id = arr_type->LengthId(); + Instruction* arr_len_inst = def_use_mgr->GetDef(arr_len_id); + if (arr_len_inst->opcode() != spv::Op::OpConstant) { + continue; + } + // SPIR-V requires array size is >= 1, so this works for signed or + // unsigned size. + unsigned original_max = + arr_len_inst->GetSingleWordInOperand(kConstantValueInIdx) - 1; + unsigned max_idx = FindMaxIndex(var, original_max); + if (max_idx != original_max) { + ChangeArrayLength(var, max_idx + 1); + vars_to_move.push_back(&var); + modified = true; + } + continue; + } + const analysis::Struct* struct_type = core_type->AsStruct(); + if (struct_type == nullptr) continue; + const auto elt_types = struct_type->element_types(); + unsigned original_max = static_cast(elt_types.size()) - 1; + unsigned max_idx = FindMaxIndex(var, original_max, skip_first_index); + if (max_idx != original_max) { + ChangeIOVarStructLength(var, max_idx + 1); + vars_to_move.push_back(&var); + modified = true; + } + } + + // Move changed vars after their new type instruction to preserve backward + // referencing. + for (auto var : vars_to_move) { + auto type_id = var->type_id(); + auto type_inst = def_use_mgr->GetDef(type_id); + var->RemoveFromList(); + var->InsertAfter(type_inst); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +unsigned EliminateDeadIOComponentsPass::FindMaxIndex( + const Instruction& var, const unsigned original_max, + const bool skip_first_index) { + unsigned max = 0; + bool seen_non_const_ac = false; + assert(var.opcode() == spv::Op::OpVariable && "must be variable"); + context()->get_def_use_mgr()->WhileEachUser( + var.result_id(), [&max, &seen_non_const_ac, var, skip_first_index, + this](Instruction* use) { + auto use_opcode = use->opcode(); + if (use_opcode == spv::Op::OpLoad || use_opcode == spv::Op::OpStore || + use_opcode == spv::Op::OpCopyMemory || + use_opcode == spv::Op::OpCopyMemorySized || + use_opcode == spv::Op::OpCopyObject) { + seen_non_const_ac = true; + return false; + } + if (use->opcode() != spv::Op::OpAccessChain && + use->opcode() != spv::Op::OpInBoundsAccessChain) { + return true; + } + // OpAccessChain with no indices currently not optimized + if (use->NumInOperands() == 1 || + (skip_first_index && use->NumInOperands() == 2)) { + seen_non_const_ac = true; + return false; + } + const unsigned base_id = + use->GetSingleWordInOperand(kAccessChainBaseInIdx); + USE_ASSERT(base_id == var.result_id() && "unexpected base"); + const unsigned in_idx = skip_first_index ? kAccessChainIndex1InIdx + : kAccessChainIndex0InIdx; + const unsigned idx_id = use->GetSingleWordInOperand(in_idx); + Instruction* idx_inst = context()->get_def_use_mgr()->GetDef(idx_id); + if (idx_inst->opcode() != spv::Op::OpConstant) { + seen_non_const_ac = true; + return false; + } + unsigned value = idx_inst->GetSingleWordInOperand(kConstantValueInIdx); + if (value > max) max = value; + return true; + }); + return seen_non_const_ac ? original_max : max; +} + +void EliminateDeadIOComponentsPass::ChangeArrayLength(Instruction& arr_var, + unsigned length) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::Pointer* ptr_type = + type_mgr->GetType(arr_var.type_id())->AsPointer(); + const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray(); + assert(arr_ty && "expecting array type"); + uint32_t length_id = const_mgr->GetUIntConstId(length); + analysis::Array new_arr_ty(arr_ty->element_type(), + arr_ty->GetConstantLengthInfo(length_id, length)); + analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty); + analysis::Pointer new_ptr_ty(reg_new_arr_ty, ptr_type->storage_class()); + analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); + uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); + arr_var.SetResultType(new_ptr_ty_id); + def_use_mgr->AnalyzeInstUse(&arr_var); +} + +void EliminateDeadIOComponentsPass::ChangeIOVarStructLength(Instruction& io_var, + unsigned length) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Pointer* ptr_type = + type_mgr->GetType(io_var.type_id())->AsPointer(); + auto core_type = ptr_type->pointee_type(); + // Check for per-vertex-array of struct from tesc, tese and geom and grab + // embedded struct type. + const auto arr_type = core_type->AsArray(); + if (arr_type) core_type = arr_type->element_type(); + const analysis::Struct* struct_ty = core_type->AsStruct(); + assert(struct_ty && "expecting struct type"); + const auto orig_elt_types = struct_ty->element_types(); + std::vector new_elt_types; + for (unsigned u = 0; u < length; ++u) + new_elt_types.push_back(orig_elt_types[u]); + analysis::Struct new_struct_ty(new_elt_types); + uint32_t old_struct_ty_id = type_mgr->GetTypeInstruction(struct_ty); + std::vector decorations = + context()->get_decoration_mgr()->GetDecorationsFor(old_struct_ty_id, + true); + for (auto dec : decorations) { + if (dec->opcode() == spv::Op::OpMemberDecorate) { + uint32_t midx = dec->GetSingleWordInOperand(1); + if (midx >= length) continue; + } + type_mgr->AttachDecoration(*dec, &new_struct_ty); + } + // Clone name instructions for new struct type + analysis::Type* reg_new_str_ty = type_mgr->GetRegisteredType(&new_struct_ty); + uint32_t new_struct_ty_id = type_mgr->GetTypeInstruction(reg_new_str_ty); + context()->CloneNames(old_struct_ty_id, new_struct_ty_id, length); + // Attach new type to var + analysis::Type* reg_new_var_ty = reg_new_str_ty; + if (arr_type) { + analysis::Array new_arr_ty(reg_new_var_ty, arr_type->length_info()); + reg_new_var_ty = type_mgr->GetRegisteredType(&new_arr_ty); + } + analysis::Pointer new_ptr_ty(reg_new_var_ty, elim_sclass_); + analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); + uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); + io_var.SetResultType(new_ptr_ty_id); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->AnalyzeInstUse(&io_var); +} + +} // namespace opt +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.h b/3rdparty/spirv-tools/source/opt/eliminate_dead_io_components_pass.h similarity index 69% rename from 3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.h rename to 3rdparty/spirv-tools/source/opt/eliminate_dead_io_components_pass.h index a3a133c2b..ef4dfb717 100644 --- a/3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.h +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_io_components_pass.h @@ -26,14 +26,15 @@ namespace spvtools { namespace opt { // See optimizer.hpp for documentation. -class EliminateDeadInputComponentsPass : public Pass { +class EliminateDeadIOComponentsPass : public Pass { public: - explicit EliminateDeadInputComponentsPass() {} + explicit EliminateDeadIOComponentsPass(spv::StorageClass elim_sclass, + bool safe_mode = true) + : elim_sclass_(elim_sclass), safe_mode_(safe_mode) {} const char* name() const override { return "eliminate-dead-input-components"; } - Status Process() override; // Return the mask of preserved Analyses. @@ -50,13 +51,22 @@ class EliminateDeadInputComponentsPass : public Pass { // Find the max constant used to index the variable declared by |var| // through OpAccessChain or OpInBoundsAccessChain. If any non-constant // indices or non-Op*AccessChain use of |var|, return |original_max|. - unsigned FindMaxIndex(Instruction& var, unsigned original_max); + unsigned FindMaxIndex(const Instruction& var, const unsigned original_max, + const bool skip_first_index = false); // Change the length of the array |inst| to |length| void ChangeArrayLength(Instruction& inst, unsigned length); - // Change the length of the struct |struct_var| to |length| - void ChangeStructLength(Instruction& struct_var, unsigned length); + // Change the length of the struct in |io_var| to |length|. |io_var| + // is either the struct or a per-vertex-array of the struct. + void ChangeIOVarStructLength(Instruction& io_var, unsigned length); + + // Storage class to be optimized. Must be Input or Output. + spv::StorageClass elim_sclass_; + + // Only make changes that will not cause interface incompatibility if done + // standalone. Currently this is only Input variables in vertex shaders. + bool safe_mode_; }; } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_members_pass.cpp b/3rdparty/spirv-tools/source/opt/eliminate_dead_members_pass.cpp index 52aca5254..1c98502e2 100644 --- a/3rdparty/spirv-tools/source/opt/eliminate_dead_members_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_members_pass.cpp @@ -17,17 +17,16 @@ #include "ir_builder.h" #include "source/opt/ir_context.h" +namespace spvtools { +namespace opt { namespace { -const uint32_t kRemovedMember = 0xFFFFFFFF; -const uint32_t kSpecConstOpOpcodeIdx = 0; +constexpr uint32_t kRemovedMember = 0xFFFFFFFF; +constexpr uint32_t kSpecConstOpOpcodeIdx = 0; constexpr uint32_t kArrayElementTypeIdx = 0; } // namespace -namespace spvtools { -namespace opt { - Pass::Status EliminateDeadMembersPass::Process() { - if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) return Status::SuccessWithoutChange; FindLiveMembers(); @@ -41,27 +40,27 @@ void EliminateDeadMembersPass::FindLiveMembers() { // Until we have implemented the rewriting of OpSpecConsantOp instructions, // we have to mark them as fully used just to be safe. for (auto& inst : get_module()->types_values()) { - if (inst.opcode() == SpvOpSpecConstantOp) { - switch (inst.GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) { - case SpvOpCompositeExtract: + if (inst.opcode() == spv::Op::OpSpecConstantOp) { + switch (spv::Op(inst.GetSingleWordInOperand(kSpecConstOpOpcodeIdx))) { + case spv::Op::OpCompositeExtract: MarkMembersAsLiveForExtract(&inst); break; - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: // Nothing specific to do. break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: assert(false && "Not implemented yet."); break; default: break; } - } else if (inst.opcode() == SpvOpVariable) { - switch (inst.GetSingleWordInOperand(0)) { - case SpvStorageClassInput: - case SpvStorageClassOutput: + } else if (inst.opcode() == spv::Op::OpVariable) { + switch (spv::StorageClass(inst.GetSingleWordInOperand(0))) { + case spv::StorageClass::Input: + case spv::StorageClass::Output: MarkPointeeTypeAsFullUsed(inst.type_id()); break; default: @@ -86,34 +85,34 @@ void EliminateDeadMembersPass::FindLiveMembers(const Function& function) { void EliminateDeadMembersPass::FindLiveMembers(const Instruction* inst) { switch (inst->opcode()) { - case SpvOpStore: + case spv::Op::OpStore: MarkMembersAsLiveForStore(inst); break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: MarkMembersAsLiveForCopyMemory(inst); break; - case SpvOpCompositeExtract: + case spv::Op::OpCompositeExtract: MarkMembersAsLiveForExtract(inst); break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: MarkMembersAsLiveForAccessChain(inst); break; - case SpvOpReturnValue: + case spv::Op::OpReturnValue: // This should be an issue only if we are returning from the entry point. // However, for now I will keep it more conservative because functions are // often inlined leaving only the entry points. MarkOperandTypeAsFullyUsed(inst, 0); break; - case SpvOpArrayLength: + case spv::Op::OpArrayLength: MarkMembersAsLiveForArrayLength(inst); break; - case SpvOpLoad: - case SpvOpCompositeInsert: - case SpvOpCompositeConstruct: + case spv::Op::OpLoad: + case spv::Op::OpCompositeInsert: + case spv::Op::OpCompositeConstruct: break; default: // This path is here for safety. All instructions that can reference @@ -131,7 +130,7 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForStore( // memory that is read outside of the shader. Other passes can remove all // store to memory that is not visible outside of the shader, so we do not // complicate the code for now. - assert(inst->opcode() == SpvOpStore); + assert(inst->opcode() == spv::Op::OpStore); uint32_t object_id = inst->GetSingleWordInOperand(1); Instruction* object_inst = context()->get_def_use_mgr()->GetDef(object_id); uint32_t object_type_id = object_inst->type_id(); @@ -143,15 +142,15 @@ void EliminateDeadMembersPass::MarkTypeAsFullyUsed(uint32_t type_id) { assert(type_inst != nullptr); switch (type_inst->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: // Mark every member and its type as fully used. for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { used_members_[type_id].insert(i); MarkTypeAsFullyUsed(type_inst->GetSingleWordInOperand(i)); } break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: MarkTypeAsFullyUsed( type_inst->GetSingleWordInOperand(kArrayElementTypeIdx)); break; @@ -162,7 +161,7 @@ void EliminateDeadMembersPass::MarkTypeAsFullyUsed(uint32_t type_id) { void EliminateDeadMembersPass::MarkPointeeTypeAsFullUsed(uint32_t ptr_type_id) { Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == SpvOpTypePointer); + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer); MarkTypeAsFullyUsed(ptr_type_inst->GetSingleWordInOperand(1)); } @@ -178,12 +177,13 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForCopyMemory( void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( const Instruction* inst) { - assert(inst->opcode() == SpvOpCompositeExtract || - (inst->opcode() == SpvOpSpecConstantOp && - inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx) == - SpvOpCompositeExtract)); + assert(inst->opcode() == spv::Op::OpCompositeExtract || + (inst->opcode() == spv::Op::OpSpecConstantOp && + spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == + spv::Op::OpCompositeExtract)); - uint32_t first_operand = (inst->opcode() == SpvOpSpecConstantOp ? 1 : 0); + uint32_t first_operand = + (inst->opcode() == spv::Op::OpSpecConstantOp ? 1 : 0); uint32_t composite_id = inst->GetSingleWordInOperand(first_operand); Instruction* composite_inst = get_def_use_mgr()->GetDef(composite_id); uint32_t type_id = composite_inst->type_id(); @@ -192,14 +192,14 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); uint32_t member_idx = inst->GetSingleWordInOperand(i); switch (type_inst->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: used_members_[type_id].insert(member_idx); type_id = type_inst->GetSingleWordInOperand(member_idx); break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: - case SpvOpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -210,10 +210,10 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( const Instruction* inst) { - assert(inst->opcode() == SpvOpAccessChain || - inst->opcode() == SpvOpInBoundsAccessChain || - inst->opcode() == SpvOpPtrAccessChain || - inst->opcode() == SpvOpInBoundsPtrAccessChain); + assert(inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain || + inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain); uint32_t pointer_id = inst->GetSingleWordInOperand(0); Instruction* pointer_inst = get_def_use_mgr()->GetDef(pointer_id); @@ -225,14 +225,14 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( // For a pointer access chain, we need to skip the |element| index. It is not // a reference to the member of a struct, and it does not change the type. - uint32_t i = (inst->opcode() == SpvOpAccessChain || - inst->opcode() == SpvOpInBoundsAccessChain + uint32_t i = (inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain ? 1 : 2); for (; i < inst->NumInOperands(); ++i) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const analysis::IntConstant* member_idx = const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i)) ->AsIntConstant(); @@ -242,10 +242,10 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( used_members_[type_id].insert(index); type_id = type_inst->GetSingleWordInOperand(index); } break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: - case SpvOpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -263,7 +263,7 @@ void EliminateDeadMembersPass::MarkOperandTypeAsFullyUsed( void EliminateDeadMembersPass::MarkMembersAsLiveForArrayLength( const Instruction* inst) { - assert(inst->opcode() == SpvOpArrayLength); + assert(inst->opcode() == spv::Op::OpArrayLength); uint32_t object_id = inst->GetSingleWordInOperand(0); Instruction* object_inst = get_def_use_mgr()->GetDef(object_id); uint32_t pointer_type_id = object_inst->type_id(); @@ -278,7 +278,7 @@ bool EliminateDeadMembersPass::RemoveDeadMembers() { // First update all of the OpTypeStruct instructions. get_module()->ForEachInst([&modified, this](Instruction* inst) { switch (inst->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: modified |= UpdateOpTypeStruct(inst); break; default: @@ -289,47 +289,47 @@ bool EliminateDeadMembersPass::RemoveDeadMembers() { // Now update all of the instructions that reference the OpTypeStructs. get_module()->ForEachInst([&modified, this](Instruction* inst) { switch (inst->opcode()) { - case SpvOpMemberName: + case spv::Op::OpMemberName: modified |= UpdateOpMemberNameOrDecorate(inst); break; - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: modified |= UpdateOpMemberNameOrDecorate(inst); break; - case SpvOpGroupMemberDecorate: + case spv::Op::OpGroupMemberDecorate: modified |= UpdateOpGroupMemberDecorate(inst); break; - case SpvOpSpecConstantComposite: - case SpvOpConstantComposite: - case SpvOpCompositeConstruct: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpConstantComposite: + case spv::Op::OpCompositeConstruct: modified |= UpdateConstantComposite(inst); break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: modified |= UpdateAccessChain(inst); break; - case SpvOpCompositeExtract: + case spv::Op::OpCompositeExtract: modified |= UpdateCompsiteExtract(inst); break; - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: modified |= UpdateCompositeInsert(inst); break; - case SpvOpArrayLength: + case spv::Op::OpArrayLength: modified |= UpdateOpArrayLength(inst); break; - case SpvOpSpecConstantOp: - switch (inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) { - case SpvOpCompositeExtract: + case spv::Op::OpSpecConstantOp: + switch (spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx))) { + case spv::Op::OpCompositeExtract: modified |= UpdateCompsiteExtract(inst); break; - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: modified |= UpdateCompositeInsert(inst); break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: assert(false && "Not implemented yet."); break; default: @@ -344,7 +344,7 @@ bool EliminateDeadMembersPass::RemoveDeadMembers() { } bool EliminateDeadMembersPass::UpdateOpTypeStruct(Instruction* inst) { - assert(inst->opcode() == SpvOpTypeStruct); + assert(inst->opcode() == spv::Op::OpTypeStruct); const auto& live_members = used_members_[inst->result_id()]; if (live_members.size() == inst->NumInOperands()) { @@ -362,8 +362,8 @@ bool EliminateDeadMembersPass::UpdateOpTypeStruct(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateOpMemberNameOrDecorate(Instruction* inst) { - assert(inst->opcode() == SpvOpMemberName || - inst->opcode() == SpvOpMemberDecorate); + assert(inst->opcode() == spv::Op::OpMemberName || + inst->opcode() == spv::Op::OpMemberDecorate); uint32_t type_id = inst->GetSingleWordInOperand(0); auto live_members = used_members_.find(type_id); @@ -388,7 +388,7 @@ bool EliminateDeadMembersPass::UpdateOpMemberNameOrDecorate(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateOpGroupMemberDecorate(Instruction* inst) { - assert(inst->opcode() == SpvOpGroupMemberDecorate); + assert(inst->opcode() == spv::Op::OpGroupMemberDecorate); bool modified = false; @@ -429,9 +429,9 @@ bool EliminateDeadMembersPass::UpdateOpGroupMemberDecorate(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateConstantComposite(Instruction* inst) { - assert(inst->opcode() == SpvOpSpecConstantComposite || - inst->opcode() == SpvOpConstantComposite || - inst->opcode() == SpvOpCompositeConstruct); + assert(inst->opcode() == spv::Op::OpSpecConstantComposite || + inst->opcode() == spv::Op::OpConstantComposite || + inst->opcode() == spv::Op::OpCompositeConstruct); uint32_t type_id = inst->type_id(); bool modified = false; @@ -450,10 +450,10 @@ bool EliminateDeadMembersPass::UpdateConstantComposite(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { - assert(inst->opcode() == SpvOpAccessChain || - inst->opcode() == SpvOpInBoundsAccessChain || - inst->opcode() == SpvOpPtrAccessChain || - inst->opcode() == SpvOpInBoundsPtrAccessChain); + assert(inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain || + inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain); uint32_t pointer_id = inst->GetSingleWordInOperand(0); Instruction* pointer_inst = get_def_use_mgr()->GetDef(pointer_id); @@ -467,8 +467,8 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { new_operands.emplace_back(inst->GetInOperand(0)); // For pointer access chains we want to copy the element operand. - if (inst->opcode() == SpvOpPtrAccessChain || - inst->opcode() == SpvOpInBoundsPtrAccessChain) { + if (inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { new_operands.emplace_back(inst->GetInOperand(1)); } @@ -476,7 +476,7 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { i < inst->NumInOperands(); ++i) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const analysis::IntConstant* member_idx = const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i)) ->AsIntConstant(); @@ -501,10 +501,10 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { // index. type_id = type_inst->GetSingleWordInOperand(new_member_idx); } break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: - case SpvOpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: new_operands.emplace_back(inst->GetInOperand(i)); type_id = type_inst->GetSingleWordInOperand(0); break; @@ -539,13 +539,13 @@ uint32_t EliminateDeadMembersPass::GetNewMemberIndex(uint32_t type_id, } bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { - assert(inst->opcode() == SpvOpCompositeExtract || - (inst->opcode() == SpvOpSpecConstantOp && - inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx) == - SpvOpCompositeExtract)); + assert(inst->opcode() == spv::Op::OpCompositeExtract || + (inst->opcode() == spv::Op::OpSpecConstantOp && + spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == + spv::Op::OpCompositeExtract)); uint32_t first_operand = 0; - if (inst->opcode() == SpvOpSpecConstantOp) { + if (inst->opcode() == spv::Op::OpSpecConstantOp) { first_operand = 1; } uint32_t object_id = inst->GetSingleWordInOperand(first_operand); @@ -569,15 +569,15 @@ bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: // The type will have already been rewritten, so use the new member // index. type_id = type_inst->GetSingleWordInOperand(new_member_idx); break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: - case SpvOpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -594,13 +594,13 @@ bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) { - assert(inst->opcode() == SpvOpCompositeInsert || - (inst->opcode() == SpvOpSpecConstantOp && - inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx) == - SpvOpCompositeInsert)); + assert(inst->opcode() == spv::Op::OpCompositeInsert || + (inst->opcode() == spv::Op::OpSpecConstantOp && + spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == + spv::Op::OpCompositeInsert)); uint32_t first_operand = 0; - if (inst->opcode() == SpvOpSpecConstantOp) { + if (inst->opcode() == spv::Op::OpSpecConstantOp) { first_operand = 1; } @@ -630,15 +630,15 @@ bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: // The type will have already been rewritten, so use the new member // index. type_id = type_inst->GetSingleWordInOperand(new_member_idx); break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: - case SpvOpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp b/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp new file mode 100644 index 000000000..f2f64f812 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp @@ -0,0 +1,237 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_output_stores_pass.h" + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kDecorationLocationInIdx = 2; +constexpr uint32_t kOpDecorateMemberMemberInIdx = 1; +constexpr uint32_t kOpDecorateBuiltInLiteralInIdx = 2; +constexpr uint32_t kOpDecorateMemberBuiltInLiteralInIdx = 3; +constexpr uint32_t kOpAccessChainIdx0InIdx = 1; +constexpr uint32_t kOpConstantValueInIdx = 0; +} // namespace + +Pass::Status EliminateDeadOutputStoresPass::Process() { + // Current functionality assumes shader capability + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + Pass::Status status = DoDeadOutputStoreElimination(); + return status; +} + +void EliminateDeadOutputStoresPass::InitializeElimination() { + kill_list_.clear(); +} + +bool EliminateDeadOutputStoresPass::IsLiveBuiltin(uint32_t bi) { + return live_builtins_->find(bi) != live_builtins_->end(); +} + +bool EliminateDeadOutputStoresPass::AnyLocsAreLive(uint32_t start, + uint32_t count) { + auto finish = start + count; + for (uint32_t u = start; u < finish; ++u) { + if (live_locs_->find(u) != live_locs_->end()) return true; + } + return false; +} + +void EliminateDeadOutputStoresPass::KillAllStoresOfRef(Instruction* ref) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + if (ref->opcode() == spv::Op::OpStore) { + kill_list_.push_back(ref); + return; + } + assert((ref->opcode() == spv::Op::OpAccessChain || + ref->opcode() == spv::Op::OpInBoundsAccessChain) && + "unexpected use of output variable"); + def_use_mgr->ForEachUser(ref, [this](Instruction* user) { + if (user->opcode() == spv::Op::OpStore) kill_list_.push_back(user); + }); +} + +void EliminateDeadOutputStoresPass::KillAllDeadStoresOfLocRef( + Instruction* ref, Instruction* var) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + analysis::LivenessManager* live_mgr = context()->get_liveness_mgr(); + // Find variable location if present. + uint32_t start_loc = 0; + auto var_id = var->result_id(); + bool no_loc = deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Location), + [&start_loc](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); + start_loc = deco.GetSingleWordInOperand(kDecorationLocationInIdx); + return false; + }); + // Find patch decoration if present + bool is_patch = !deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Patch), [](const Instruction& deco) { + if (deco.opcode() != spv::Op::OpDecorate) + assert(false && "unexpected decoration"); + return false; + }); + // Compute offset and final type of reference. If no location found + // or any stored locations are live, return without removing stores. + auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); + assert(ptr_type && "unexpected var type"); + auto var_type = ptr_type->pointee_type(); + uint32_t ref_loc = start_loc; + auto curr_type = var_type; + if (ref->opcode() == spv::Op::OpAccessChain || + ref->opcode() == spv::Op::OpInBoundsAccessChain) { + live_mgr->AnalyzeAccessChainLoc(ref, &curr_type, &ref_loc, &no_loc, + is_patch, /* input */ false); + } + if (no_loc || AnyLocsAreLive(ref_loc, live_mgr->GetLocSize(curr_type))) + return; + // Kill all stores based on this reference + KillAllStoresOfRef(ref); +} + +void EliminateDeadOutputStoresPass::KillAllDeadStoresOfBuiltinRef( + Instruction* ref, Instruction* var) { + auto deco_mgr = context()->get_decoration_mgr(); + auto def_use_mgr = context()->get_def_use_mgr(); + auto type_mgr = context()->get_type_mgr(); + auto live_mgr = context()->get_liveness_mgr(); + // Search for builtin decoration of base variable + uint32_t builtin = uint32_t(spv::BuiltIn::Max); + auto var_id = var->result_id(); + (void)deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::BuiltIn), + [&builtin](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); + builtin = deco.GetSingleWordInOperand(kOpDecorateBuiltInLiteralInIdx); + return false; + }); + // If analyzed builtin and not live, kill stores. + if (builtin != uint32_t(spv::BuiltIn::Max)) { + if (live_mgr->IsAnalyzedBuiltin(builtin) && !IsLiveBuiltin(builtin)) + KillAllStoresOfRef(ref); + return; + } + // Search for builtin decoration on indexed member + auto ref_op = ref->opcode(); + if (ref_op != spv::Op::OpAccessChain && + ref_op != spv::Op::OpInBoundsAccessChain) { + return; + } + uint32_t in_idx = kOpAccessChainIdx0InIdx; + analysis::Type* var_type = type_mgr->GetType(var->type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + auto curr_type = ptr_type->pointee_type(); + auto arr_type = curr_type->AsArray(); + if (arr_type) { + curr_type = arr_type->element_type(); + ++in_idx; + } + auto str_type = curr_type->AsStruct(); + auto str_type_id = type_mgr->GetId(str_type); + auto member_idx_id = ref->GetSingleWordInOperand(in_idx); + auto member_idx_inst = def_use_mgr->GetDef(member_idx_id); + assert(member_idx_inst->opcode() == spv::Op::OpConstant && + "unexpected non-constant index"); + auto ac_idx = member_idx_inst->GetSingleWordInOperand(kOpConstantValueInIdx); + (void)deco_mgr->WhileEachDecoration( + str_type_id, uint32_t(spv::Decoration::BuiltIn), + [ac_idx, &builtin](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpMemberDecorate && + "unexpected decoration"); + auto deco_idx = + deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx); + if (deco_idx == ac_idx) { + builtin = + deco.GetSingleWordInOperand(kOpDecorateMemberBuiltInLiteralInIdx); + return false; + } + return true; + }); + assert(builtin != uint32_t(spv::BuiltIn::Max) && "builtin not found"); + // If analyzed builtin and not live, kill stores. + if (live_mgr->IsAnalyzedBuiltin(builtin) && !IsLiveBuiltin(builtin)) + KillAllStoresOfRef(ref); +} + +Pass::Status EliminateDeadOutputStoresPass::DoDeadOutputStoreElimination() { + // Current implementation only supports vert, tesc, tese, geom shaders + auto stage = context()->GetStage(); + if (stage != spv::ExecutionModel::Vertex && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::Geometry) + return Status::Failure; + InitializeElimination(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + // Process all output variables + for (auto& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type->storage_class() != spv::StorageClass::Output) { + continue; + } + // If builtin decoration on variable, process as builtin. + auto var_id = var.result_id(); + bool is_builtin = false; + if (deco_mgr->HasDecoration(var_id, uint32_t(spv::Decoration::BuiltIn))) { + is_builtin = true; + } else { + // If interface block with builtin members, process as builtin. + // Strip off outer array type if present. + auto curr_type = ptr_type->pointee_type(); + auto arr_type = curr_type->AsArray(); + if (arr_type) curr_type = arr_type->element_type(); + auto str_type = curr_type->AsStruct(); + if (str_type) { + auto str_type_id = type_mgr->GetId(str_type); + if (deco_mgr->HasDecoration(str_type_id, + uint32_t(spv::Decoration::BuiltIn))) + is_builtin = true; + } + } + // For each store or access chain using var, if dead builtin or all its + // locations are dead, kill store or all access chain's stores + def_use_mgr->ForEachUser( + var_id, [this, &var, is_builtin](Instruction* user) { + auto op = user->opcode(); + if (op == spv::Op::OpEntryPoint || op == spv::Op::OpName || + op == spv::Op::OpDecorate) + return; + if (is_builtin) + KillAllDeadStoresOfBuiltinRef(user, &var); + else + KillAllDeadStoresOfLocRef(user, &var); + }); + } + for (auto& kinst : kill_list_) context()->KillInst(kinst); + + return kill_list_.empty() ? Status::SuccessWithoutChange + : Status::SuccessWithChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h b/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h new file mode 100644 index 000000000..13785f349 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h @@ -0,0 +1,87 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class EliminateDeadOutputStoresPass : public Pass { + public: + explicit EliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins) + : live_locs_(live_locs), live_builtins_(live_builtins) {} + + const char* name() const override { return "eliminate-dead-output-stores"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Initialize elimination + void InitializeElimination(); + + // Do dead output store analysis + Status DoDeadOutputStoreAnalysis(); + + // Do dead output store analysis + Status DoDeadOutputStoreElimination(); + + // Mark all locations live + void MarkAllLocsLive(); + + // Kill all stores resulting from |ref|. + void KillAllStoresOfRef(Instruction* ref); + + // Kill all dead stores resulting from |user| of loc-based |var|. + void KillAllDeadStoresOfLocRef(Instruction* user, Instruction* var); + + // Kill all dead stores resulting from |user| of builtin |var|. + void KillAllDeadStoresOfBuiltinRef(Instruction* user, Instruction* var); + + // Return true if any of |count| locations starting at location |start| are + // live. + bool AnyLocsAreLive(uint32_t start, uint32_t count); + + // Return true if builtin |bi| is live. + bool IsLiveBuiltin(uint32_t bi); + + std::unordered_set* live_locs_; + std::unordered_set* live_builtins_; + + std::vector kill_list_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ diff --git a/3rdparty/spirv-tools/source/opt/feature_manager.cpp b/3rdparty/spirv-tools/source/opt/feature_manager.cpp index a59027167..2a1c00664 100644 --- a/3rdparty/spirv-tools/source/opt/feature_manager.cpp +++ b/3rdparty/spirv-tools/source/opt/feature_manager.cpp @@ -36,7 +36,7 @@ void FeatureManager::AddExtensions(Module* module) { } void FeatureManager::AddExtension(Instruction* ext) { - assert(ext->opcode() == SpvOpExtension && + assert(ext->opcode() == spv::Op::OpExtension && "Expecting an extension instruction."); const std::string name = ext->GetInOperand(0u).AsString(); @@ -51,27 +51,27 @@ void FeatureManager::RemoveExtension(Extension ext) { extensions_.Remove(ext); } -void FeatureManager::AddCapability(SpvCapability cap) { +void FeatureManager::AddCapability(spv::Capability cap) { if (capabilities_.Contains(cap)) return; capabilities_.Add(cap); spv_operand_desc desc = {}; - if (SPV_SUCCESS == - grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) { + if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + uint32_t(cap), &desc)) { CapabilitySet(desc->numCapabilities, desc->capabilities) - .ForEach([this](SpvCapability c) { AddCapability(c); }); + .ForEach([this](spv::Capability c) { AddCapability(c); }); } } -void FeatureManager::RemoveCapability(SpvCapability cap) { +void FeatureManager::RemoveCapability(spv::Capability cap) { if (!capabilities_.Contains(cap)) return; capabilities_.Remove(cap); } void FeatureManager::AddCapabilities(Module* module) { for (Instruction& inst : module->capabilities()) { - AddCapability(static_cast(inst.GetSingleWordInOperand(0))); + AddCapability(static_cast(inst.GetSingleWordInOperand(0))); } } diff --git a/3rdparty/spirv-tools/source/opt/feature_manager.h b/3rdparty/spirv-tools/source/opt/feature_manager.h index 68c8e9a23..b96988de4 100644 --- a/3rdparty/spirv-tools/source/opt/feature_manager.h +++ b/3rdparty/spirv-tools/source/opt/feature_manager.h @@ -34,12 +34,12 @@ class FeatureManager { void RemoveExtension(Extension extension); // Returns true if |cap| is an enabled capability in the module. - bool HasCapability(SpvCapability cap) const { + bool HasCapability(spv::Capability cap) const { return capabilities_.Contains(cap); } // Removes the given |capability| from the current FeatureManager. - void RemoveCapability(SpvCapability capability); + void RemoveCapability(spv::Capability capability); // Analyzes |module| and records enabled extensions and capabilities. void Analyze(Module* module); @@ -66,7 +66,7 @@ class FeatureManager { // Adds the given |capability| and all implied capabilities into the current // FeatureManager. - void AddCapability(SpvCapability capability); + void AddCapability(spv::Capability capability); // Add the extension |ext| to the feature manager. void AddExtension(Instruction* ext); diff --git a/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp b/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp index d140fb4b0..f3486bed3 100644 --- a/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp +++ b/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp @@ -29,7 +29,7 @@ Pass::Status FixFuncCallArgumentsPass::Process() { if (ModuleHasASingleFunction()) return Status::SuccessWithoutChange; for (auto& func : *get_module()) { func.ForEachInst([this, &modified](Instruction* inst) { - if (inst->opcode() == SpvOpFunctionCall) { + if (inst->opcode() == spv::Op::OpFunctionCall) { modified |= FixFuncCallArguments(inst); } }); @@ -44,7 +44,7 @@ bool FixFuncCallArgumentsPass::FixFuncCallArguments( Operand& op = func_call_inst->GetInOperand(i); if (op.type != SPV_OPERAND_TYPE_ID) continue; Instruction* operand_inst = get_def_use_mgr()->GetDef(op.AsId()); - if (operand_inst->opcode() == SpvOpAccessChain) { + if (operand_inst->opcode() == spv::Op::OpAccessChain) { uint32_t var_id = ReplaceAccessChainFuncCallArguments(func_call_inst, operand_inst); func_call_inst->SetInOperand(i, {var_id}); @@ -71,10 +71,11 @@ uint32_t FixFuncCallArgumentsPass::ReplaceAccessChainFuncCallArguments( Instruction* op_type = get_def_use_mgr()->GetDef(op_ptr_type->GetSingleWordInOperand(1)); uint32_t varType = context()->get_type_mgr()->FindPointerToType( - op_type->result_id(), SpvStorageClassFunction); + op_type->result_id(), spv::StorageClass::Function); // Create new variable builder.SetInsertPoint(variable_insertion_point); - Instruction* var = builder.AddVariable(varType, SpvStorageClassFunction); + Instruction* var = + builder.AddVariable(varType, uint32_t(spv::StorageClass::Function)); // Load access chain to the new variable before function call builder.SetInsertPoint(func_call_inst); diff --git a/3rdparty/spirv-tools/source/opt/fix_storage_class.cpp b/3rdparty/spirv-tools/source/opt/fix_storage_class.cpp index 04eb1326c..5597e825b 100644 --- a/3rdparty/spirv-tools/source/opt/fix_storage_class.cpp +++ b/3rdparty/spirv-tools/source/opt/fix_storage_class.cpp @@ -26,7 +26,7 @@ Pass::Status FixStorageClass::Process() { bool modified = false; get_module()->ForEachInst([this, &modified](Instruction* inst) { - if (inst->opcode() == SpvOpVariable) { + if (inst->opcode() == spv::Op::OpVariable) { std::set seen; std::vector> uses; get_def_use_mgr()->ForEachUse(inst, @@ -37,7 +37,7 @@ Pass::Status FixStorageClass::Process() { for (auto& use : uses) { modified |= PropagateStorageClass( use.first, - static_cast(inst->GetSingleWordInOperand(0)), + static_cast(inst->GetSingleWordInOperand(0)), &seen); assert(seen.empty() && "Seen was not properly reset."); modified |= @@ -50,14 +50,14 @@ Pass::Status FixStorageClass::Process() { } bool FixStorageClass::PropagateStorageClass(Instruction* inst, - SpvStorageClass storage_class, + spv::StorageClass storage_class, std::set* seen) { if (!IsPointerResultType(inst)) { return false; } if (IsPointerToStorageClass(inst, storage_class)) { - if (inst->opcode() == SpvOpPhi) { + if (inst->opcode() == spv::Op::OpPhi) { if (!seen->insert(inst->result_id()).second) { return false; } @@ -71,34 +71,34 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst, modified |= PropagateStorageClass(use, storage_class, seen); } - if (inst->opcode() == SpvOpPhi) { + if (inst->opcode() == spv::Op::OpPhi) { seen->erase(inst->result_id()); } return modified; } switch (inst->opcode()) { - case SpvOpAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpCopyObject: - case SpvOpPhi: - case SpvOpSelect: + case spv::Op::OpAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpCopyObject: + case spv::Op::OpPhi: + case spv::Op::OpSelect: FixInstructionStorageClass(inst, storage_class, seen); return true; - case SpvOpFunctionCall: + case spv::Op::OpFunctionCall: // We cannot be sure of the actual connection between the storage class // of the parameter and the storage class of the result, so we should not // do anything. If the result type needs to be fixed, the function call // should be inlined. return false; - case SpvOpImageTexelPointer: - case SpvOpLoad: - case SpvOpStore: - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: - case SpvOpVariable: - case SpvOpBitcast: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpLoad: + case spv::Op::OpStore: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + case spv::Op::OpVariable: + case spv::Op::OpBitcast: // Nothing to change for these opcode. The result type is the same // regardless of the storage class of the operand. return false; @@ -109,9 +109,9 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst, } } -void FixStorageClass::FixInstructionStorageClass(Instruction* inst, - SpvStorageClass storage_class, - std::set* seen) { +void FixStorageClass::FixInstructionStorageClass( + Instruction* inst, spv::StorageClass storage_class, + std::set* seen) { assert(IsPointerResultType(inst) && "The result type of the instruction must be a pointer."); @@ -126,10 +126,10 @@ void FixStorageClass::FixInstructionStorageClass(Instruction* inst, } void FixStorageClass::ChangeResultStorageClass( - Instruction* inst, SpvStorageClass storage_class) const { + Instruction* inst, spv::StorageClass storage_class) const { analysis::TypeManager* type_mgr = context()->get_type_mgr(); Instruction* result_type_inst = get_def_use_mgr()->GetDef(inst->type_id()); - assert(result_type_inst->opcode() == SpvOpTypePointer); + assert(result_type_inst->opcode() == spv::Op::OpTypePointer); uint32_t pointee_type_id = result_type_inst->GetSingleWordInOperand(1); uint32_t new_result_type_id = type_mgr->FindPointerToType(pointee_type_id, storage_class); @@ -147,7 +147,7 @@ bool FixStorageClass::IsPointerResultType(Instruction* inst) { } bool FixStorageClass::IsPointerToStorageClass(Instruction* inst, - SpvStorageClass storage_class) { + spv::StorageClass storage_class) { analysis::TypeManager* type_mgr = context()->get_type_mgr(); analysis::Type* pType = type_mgr->GetType(inst->type_id()); const analysis::Pointer* result_type = pType->AsPointer(); @@ -180,39 +180,39 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, // particular type, then we want find that type. uint32_t new_type_id = 0; switch (inst->opcode()) { - case SpvOpAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: if (op_idx == 2) { new_type_id = WalkAccessChainType(inst, type_id); } break; - case SpvOpCopyObject: + case spv::Op::OpCopyObject: new_type_id = type_id; break; - case SpvOpPhi: + case spv::Op::OpPhi: if (seen->insert(inst->result_id()).second) { new_type_id = type_id; } break; - case SpvOpSelect: + case spv::Op::OpSelect: if (op_idx > 2) { new_type_id = type_id; } break; - case SpvOpFunctionCall: + case spv::Op::OpFunctionCall: // We cannot be sure of the actual connection between the type // of the parameter and the type of the result, so we should not // do anything. If the result type needs to be fixed, the function call // should be inlined. return false; - case SpvOpLoad: { + case spv::Op::OpLoad: { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); new_type_id = type_inst->GetSingleWordInOperand(1); break; } - case SpvOpStore: { + case spv::Op::OpStore: { uint32_t obj_id = inst->GetSingleWordInOperand(1); Instruction* obj_inst = get_def_use_mgr()->GetDef(obj_id); uint32_t obj_type_id = obj_inst->type_id(); @@ -237,18 +237,18 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, context()->UpdateDefUse(inst); } } break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: // TODO: May need to expand the copy as we do with the stores. break; - case SpvOpCompositeConstruct: - case SpvOpCompositeExtract: - case SpvOpCompositeInsert: + case spv::Op::OpCompositeConstruct: + case spv::Op::OpCompositeExtract: + case spv::Op::OpCompositeInsert: // TODO: DXC does not seem to generate code that will require changes to // these opcode. The can be implemented when they come up. break; - case SpvOpImageTexelPointer: - case SpvOpBitcast: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpBitcast: // Nothing to change for these opcode. The result type is the same // regardless of the type of the operand. return false; @@ -278,7 +278,7 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, PropagateType(use.first, new_type_id, use.second, seen); } - if (inst->opcode() == SpvOpPhi) { + if (inst->opcode() == spv::Op::OpPhi) { seen->erase(inst->result_id()); } } @@ -288,12 +288,12 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { uint32_t start_idx = 0; switch (inst->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: start_idx = 1; break; - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: start_idx = 2; break; default: @@ -302,19 +302,19 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { } Instruction* orig_type_inst = get_def_use_mgr()->GetDef(id); - assert(orig_type_inst->opcode() == SpvOpTypePointer); + assert(orig_type_inst->opcode() == spv::Op::OpTypePointer); id = orig_type_inst->GetSingleWordInOperand(1); for (uint32_t i = start_idx; i < inst->NumInOperands(); ++i) { Instruction* type_inst = get_def_use_mgr()->GetDef(id); switch (type_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeMatrix: - case SpvOpTypeVector: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: id = type_inst->GetSingleWordInOperand(0); break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const analysis::Constant* index_const = context()->get_constant_mgr()->FindDeclaredConstant( inst->GetSingleWordInOperand(i)); @@ -330,8 +330,8 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { } return context()->get_type_mgr()->FindPointerToType( - id, - static_cast(orig_type_inst->GetSingleWordInOperand(0))); + id, static_cast( + orig_type_inst->GetSingleWordInOperand(0))); } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/fix_storage_class.h b/3rdparty/spirv-tools/source/opt/fix_storage_class.h index e72e864a6..6c67acd37 100644 --- a/3rdparty/spirv-tools/source/opt/fix_storage_class.h +++ b/3rdparty/spirv-tools/source/opt/fix_storage_class.h @@ -48,7 +48,7 @@ class FixStorageClass : public Pass { // appropriate, and propagates the change to the users of |inst| as well. // Returns true of any changes were made. // |seen| is used to track OpPhi instructions that should not be processed. - bool PropagateStorageClass(Instruction* inst, SpvStorageClass storage_class, + bool PropagateStorageClass(Instruction* inst, spv::StorageClass storage_class, std::set* seen); // Changes the storage class of the result of |inst| to |storage_class|. @@ -58,13 +58,13 @@ class FixStorageClass : public Pass { // |seen| is used to track OpPhi instructions that should not be processed by // |PropagateStorageClass| void FixInstructionStorageClass(Instruction* inst, - SpvStorageClass storage_class, + spv::StorageClass storage_class, std::set* seen); // Changes the storage class of the result of |inst| to |storage_class|. The // result type of |inst| must be a pointer. void ChangeResultStorageClass(Instruction* inst, - SpvStorageClass storage_class) const; + spv::StorageClass storage_class) const; // Returns true if the result type of |inst| is a pointer. bool IsPointerResultType(Instruction* inst); @@ -72,7 +72,7 @@ class FixStorageClass : public Pass { // Returns true if the result of |inst| is a pointer to storage class // |storage_class|. bool IsPointerToStorageClass(Instruction* inst, - SpvStorageClass storage_class); + spv::StorageClass storage_class); // Change |inst| to match that operand |op_idx| now has type |type_id|, and // adjust any uses of |inst| accordingly. Returns true if the code changed. diff --git a/3rdparty/spirv-tools/source/opt/flatten_decoration_pass.cpp b/3rdparty/spirv-tools/source/opt/flatten_decoration_pass.cpp index f4de9116f..c878c097e 100644 --- a/3rdparty/spirv-tools/source/opt/flatten_decoration_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/flatten_decoration_pass.cpp @@ -49,16 +49,16 @@ Pass::Status FlattenDecorationPass::Process() { // Rely on unordered_map::operator[] to create its entries on first access. for (const auto& inst : annotations) { switch (inst.opcode()) { - case SpvOp::SpvOpDecorationGroup: + case spv::Op::OpDecorationGroup: group_ids.insert(inst.result_id()); break; - case SpvOp::SpvOpGroupDecorate: { + case spv::Op::OpGroupDecorate: { Words& words = normal_uses[inst.GetSingleWordInOperand(0)]; for (uint32_t i = 1; i < inst.NumInOperandWords(); i++) { words.push_back(inst.GetSingleWordInOperand(i)); } } break; - case SpvOp::SpvOpGroupMemberDecorate: { + case spv::Op::OpGroupMemberDecorate: { Words& words = member_uses[inst.GetSingleWordInOperand(0)]; for (uint32_t i = 1; i < inst.NumInOperandWords(); i++) { words.push_back(inst.GetSingleWordInOperand(i)); @@ -77,12 +77,12 @@ Pass::Status FlattenDecorationPass::Process() { // Should we replace this instruction? bool replace = false; switch (inst_iter->opcode()) { - case SpvOp::SpvOpDecorationGroup: - case SpvOp::SpvOpGroupDecorate: - case SpvOp::SpvOpGroupMemberDecorate: + case spv::Op::OpDecorationGroup: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: replace = true; break; - case SpvOp::SpvOpDecorate: { + case spv::Op::OpDecorate: { // If this decoration targets a group, then replace it // by sets of normal and member decorations. const uint32_t group = inst_iter->GetSingleWordOperand(0); @@ -115,7 +115,7 @@ Pass::Status FlattenDecorationPass::Process() { operands.insert(operands.end(), decoration_operands_iter, inst_iter->end()); std::unique_ptr new_inst(new Instruction( - context(), SpvOp::SpvOpMemberDecorate, 0, 0, operands)); + context(), spv::Op::OpMemberDecorate, 0, 0, operands)); inst_iter = inst_iter.InsertBefore(std::move(new_inst)); ++inst_iter; replace = true; @@ -146,7 +146,7 @@ Pass::Status FlattenDecorationPass::Process() { if (!group_ids.empty()) { for (auto debug_inst_iter = context()->debug2_begin(); debug_inst_iter != context()->debug2_end();) { - if (debug_inst_iter->opcode() == SpvOp::SpvOpName) { + if (debug_inst_iter->opcode() == spv::Op::OpName) { const uint32_t target = debug_inst_iter->GetSingleWordOperand(0); if (group_ids.count(target)) { debug_inst_iter = debug_inst_iter.Erase(); diff --git a/3rdparty/spirv-tools/source/opt/fold.cpp b/3rdparty/spirv-tools/source/opt/fold.cpp index 315741ad7..3c234c4e3 100644 --- a/3rdparty/spirv-tools/source/opt/fold.cpp +++ b/3rdparty/spirv-tools/source/opt/fold.cpp @@ -42,23 +42,24 @@ namespace { } // namespace -uint32_t InstructionFolder::UnaryOperate(SpvOp opcode, uint32_t operand) const { +uint32_t InstructionFolder::UnaryOperate(spv::Op opcode, + uint32_t operand) const { switch (opcode) { // Arthimetics - case SpvOp::SpvOpSNegate: { + case spv::Op::OpSNegate: { int32_t s_operand = static_cast(operand); if (s_operand == std::numeric_limits::min()) { return s_operand; } return -s_operand; } - case SpvOp::SpvOpNot: + case spv::Op::OpNot: return ~operand; - case SpvOp::SpvOpLogicalNot: + case spv::Op::OpLogicalNot: return !static_cast(operand); - case SpvOp::SpvOpUConvert: + case spv::Op::OpUConvert: return operand; - case SpvOp::SpvOpSConvert: + case spv::Op::OpSConvert: return operand; default: assert(false && @@ -67,31 +68,31 @@ uint32_t InstructionFolder::UnaryOperate(SpvOp opcode, uint32_t operand) const { } } -uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, +uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, uint32_t b) const { switch (opcode) { // Arthimetics - case SpvOp::SpvOpIAdd: + case spv::Op::OpIAdd: return a + b; - case SpvOp::SpvOpISub: + case spv::Op::OpISub: return a - b; - case SpvOp::SpvOpIMul: + case spv::Op::OpIMul: return a * b; - case SpvOp::SpvOpUDiv: + case spv::Op::OpUDiv: if (b != 0) { return a / b; } else { // Dividing by 0 is undefined, so we will just pick 0. return 0; } - case SpvOp::SpvOpSDiv: + case spv::Op::OpSDiv: if (b != 0u) { return (static_cast(a)) / (static_cast(b)); } else { // Dividing by 0 is undefined, so we will just pick 0. return 0; } - case SpvOp::SpvOpSRem: { + case spv::Op::OpSRem: { // The sign of non-zero result comes from the first operand: a. This is // guaranteed by C++11 rules for integer division operator. The division // result is rounded toward zero, so the result of '%' has the sign of @@ -103,10 +104,10 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, return 0; } } - case SpvOp::SpvOpSMod: { + case spv::Op::OpSMod: { // The sign of non-zero result comes from the second operand: b if (b != 0u) { - int32_t rem = BinaryOperate(SpvOp::SpvOpSRem, a, b); + int32_t rem = BinaryOperate(spv::Op::OpSRem, a, b); int32_t b_prim = static_cast(b); return (rem + b_prim) % b_prim; } else { @@ -114,7 +115,7 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, return 0; } } - case SpvOp::SpvOpUMod: + case spv::Op::OpUMod: if (b != 0u) { return (a % b); } else { @@ -123,7 +124,7 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, } // Shifting - case SpvOp::SpvOpShiftRightLogical: + case spv::Op::OpShiftRightLogical: if (b >= 32) { // This is undefined behaviour when |b| > 32. Choose 0 for consistency. // When |b| == 32, doing the shift in C++ in undefined, but the result @@ -131,7 +132,7 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, return 0; } return a >> b; - case SpvOp::SpvOpShiftRightArithmetic: + case spv::Op::OpShiftRightArithmetic: if (b > 32) { // This is undefined behaviour. Choose 0 for consistency. return 0; @@ -146,7 +147,7 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, } } return (static_cast(a)) >> b; - case SpvOp::SpvOpShiftLeftLogical: + case spv::Op::OpShiftLeftLogical: if (b >= 32) { // This is undefined behaviour when |b| > 32. Choose 0 for consistency. // When |b| == 32, doing the shift in C++ in undefined, but the result @@ -156,43 +157,43 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, return a << b; // Bitwise operations - case SpvOp::SpvOpBitwiseOr: + case spv::Op::OpBitwiseOr: return a | b; - case SpvOp::SpvOpBitwiseAnd: + case spv::Op::OpBitwiseAnd: return a & b; - case SpvOp::SpvOpBitwiseXor: + case spv::Op::OpBitwiseXor: return a ^ b; // Logical - case SpvOp::SpvOpLogicalEqual: + case spv::Op::OpLogicalEqual: return (static_cast(a)) == (static_cast(b)); - case SpvOp::SpvOpLogicalNotEqual: + case spv::Op::OpLogicalNotEqual: return (static_cast(a)) != (static_cast(b)); - case SpvOp::SpvOpLogicalOr: + case spv::Op::OpLogicalOr: return (static_cast(a)) || (static_cast(b)); - case SpvOp::SpvOpLogicalAnd: + case spv::Op::OpLogicalAnd: return (static_cast(a)) && (static_cast(b)); // Comparison - case SpvOp::SpvOpIEqual: + case spv::Op::OpIEqual: return a == b; - case SpvOp::SpvOpINotEqual: + case spv::Op::OpINotEqual: return a != b; - case SpvOp::SpvOpULessThan: + case spv::Op::OpULessThan: return a < b; - case SpvOp::SpvOpSLessThan: + case spv::Op::OpSLessThan: return (static_cast(a)) < (static_cast(b)); - case SpvOp::SpvOpUGreaterThan: + case spv::Op::OpUGreaterThan: return a > b; - case SpvOp::SpvOpSGreaterThan: + case spv::Op::OpSGreaterThan: return (static_cast(a)) > (static_cast(b)); - case SpvOp::SpvOpULessThanEqual: + case spv::Op::OpULessThanEqual: return a <= b; - case SpvOp::SpvOpSLessThanEqual: + case spv::Op::OpSLessThanEqual: return (static_cast(a)) <= (static_cast(b)); - case SpvOp::SpvOpUGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: return a >= b; - case SpvOp::SpvOpSGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: return (static_cast(a)) >= (static_cast(b)); default: assert(false && @@ -201,10 +202,10 @@ uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, } } -uint32_t InstructionFolder::TernaryOperate(SpvOp opcode, uint32_t a, uint32_t b, - uint32_t c) const { +uint32_t InstructionFolder::TernaryOperate(spv::Op opcode, uint32_t a, + uint32_t b, uint32_t c) const { switch (opcode) { - case SpvOp::SpvOpSelect: + case spv::Op::OpSelect: return (static_cast(a)) ? b : c; default: assert(false && @@ -214,7 +215,7 @@ uint32_t InstructionFolder::TernaryOperate(SpvOp opcode, uint32_t a, uint32_t b, } uint32_t InstructionFolder::OperateWords( - SpvOp opcode, const std::vector& operand_words) const { + spv::Op opcode, const std::vector& operand_words) const { switch (operand_words.size()) { case 1: return UnaryOperate(opcode, operand_words.front()); @@ -233,7 +234,7 @@ bool InstructionFolder::FoldInstructionInternal(Instruction* inst) const { auto identity_map = [](uint32_t id) { return id; }; Instruction* folded_inst = FoldInstructionToConstant(inst, identity_map); if (folded_inst != nullptr) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {folded_inst->result_id()}}}); return true; } @@ -256,7 +257,7 @@ bool InstructionFolder::FoldInstructionInternal(Instruction* inst) const { // result in 32 bit word. Scalar constants with longer than 32-bit width are // not accepted in this function. uint32_t InstructionFolder::FoldScalars( - SpvOp opcode, + spv::Op opcode, const std::vector& operands) const { assert(IsFoldableOpcode(opcode) && "Unhandled instruction opcode in FoldScalars"); @@ -282,7 +283,7 @@ uint32_t InstructionFolder::FoldScalars( bool InstructionFolder::FoldBinaryIntegerOpToConstant( Instruction* inst, const std::function& id_map, uint32_t* result) const { - SpvOp opcode = inst->opcode(); + spv::Op opcode = inst->opcode(); analysis::ConstantManager* const_manger = context_->get_constant_mgr(); uint32_t ids[2]; @@ -300,7 +301,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( switch (opcode) { // Arthimetics - case SpvOp::SpvOpIMul: + case spv::Op::OpIMul: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr && constants[i]->IsZero()) { *result = 0; @@ -308,11 +309,11 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( } } break; - case SpvOp::SpvOpUDiv: - case SpvOp::SpvOpSDiv: - case SpvOp::SpvOpSRem: - case SpvOp::SpvOpSMod: - case SpvOp::SpvOpUMod: + case spv::Op::OpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpSRem: + case spv::Op::OpSMod: + case spv::Op::OpUMod: // This changes undefined behaviour (ie divide by 0) into a 0. for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr && constants[i]->IsZero()) { @@ -323,8 +324,8 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( break; // Shifting - case SpvOp::SpvOpShiftRightLogical: - case SpvOp::SpvOpShiftLeftLogical: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftLeftLogical: if (constants[1] != nullptr) { // When shifting by a value larger than the size of the result, the // result is undefined. We are setting the undefined behaviour to a @@ -339,7 +340,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( break; // Bitwise operations - case SpvOp::SpvOpBitwiseOr: + case spv::Op::OpBitwiseOr: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { // TODO: Change the mask against a value based on the bit width of the @@ -353,7 +354,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( } } break; - case SpvOp::SpvOpBitwiseAnd: + case spv::Op::OpBitwiseAnd: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { if (constants[i]->IsZero()) { @@ -365,7 +366,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( break; // Comparison - case SpvOp::SpvOpULessThan: + case spv::Op::OpULessThan: if (constants[0] != nullptr && constants[0]->GetU32BitValue() == UINT32_MAX) { *result = false; @@ -376,7 +377,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpSLessThan: + case spv::Op::OpSLessThan: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MAX) { *result = false; @@ -388,7 +389,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpUGreaterThan: + case spv::Op::OpUGreaterThan: if (constants[0] != nullptr && constants[0]->IsZero()) { *result = false; return true; @@ -399,7 +400,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpSGreaterThan: + case spv::Op::OpSGreaterThan: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MIN) { *result = false; @@ -411,7 +412,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpULessThanEqual: + case spv::Op::OpULessThanEqual: if (constants[0] != nullptr && constants[0]->IsZero()) { *result = true; return true; @@ -422,7 +423,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpSLessThanEqual: + case spv::Op::OpSLessThanEqual: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MIN) { *result = true; @@ -434,7 +435,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpUGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: if (constants[0] != nullptr && constants[0]->GetU32BitValue() == UINT32_MAX) { *result = true; @@ -445,7 +446,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case SpvOp::SpvOpSGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MAX) { *result = true; @@ -466,7 +467,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( bool InstructionFolder::FoldBinaryBooleanOpToConstant( Instruction* inst, const std::function& id_map, uint32_t* result) const { - SpvOp opcode = inst->opcode(); + spv::Op opcode = inst->opcode(); analysis::ConstantManager* const_manger = context_->get_constant_mgr(); uint32_t ids[2]; @@ -484,7 +485,7 @@ bool InstructionFolder::FoldBinaryBooleanOpToConstant( switch (opcode) { // Logical - case SpvOp::SpvOpLogicalOr: + case spv::Op::OpLogicalOr: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { if (constants[i]->value()) { @@ -494,7 +495,7 @@ bool InstructionFolder::FoldBinaryBooleanOpToConstant( } } break; - case SpvOp::SpvOpLogicalAnd: + case spv::Op::OpLogicalAnd: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { if (!constants[i]->value()) { @@ -526,7 +527,7 @@ bool InstructionFolder::FoldIntegerOpToConstant( } std::vector InstructionFolder::FoldVectors( - SpvOp opcode, uint32_t num_dims, + spv::Op opcode, uint32_t num_dims, const std::vector& operands) const { assert(IsFoldableOpcode(opcode) && "Unhandled instruction opcode in FoldVectors"); @@ -570,44 +571,44 @@ std::vector InstructionFolder::FoldVectors( return result; } -bool InstructionFolder::IsFoldableOpcode(SpvOp opcode) const { +bool InstructionFolder::IsFoldableOpcode(spv::Op opcode) const { // NOTE: Extend to more opcodes as new cases are handled in the folder // functions. switch (opcode) { - case SpvOp::SpvOpBitwiseAnd: - case SpvOp::SpvOpBitwiseOr: - case SpvOp::SpvOpBitwiseXor: - case SpvOp::SpvOpIAdd: - case SpvOp::SpvOpIEqual: - case SpvOp::SpvOpIMul: - case SpvOp::SpvOpINotEqual: - case SpvOp::SpvOpISub: - case SpvOp::SpvOpLogicalAnd: - case SpvOp::SpvOpLogicalEqual: - case SpvOp::SpvOpLogicalNot: - case SpvOp::SpvOpLogicalNotEqual: - case SpvOp::SpvOpLogicalOr: - case SpvOp::SpvOpNot: - case SpvOp::SpvOpSDiv: - case SpvOp::SpvOpSelect: - case SpvOp::SpvOpSGreaterThan: - case SpvOp::SpvOpSGreaterThanEqual: - case SpvOp::SpvOpShiftLeftLogical: - case SpvOp::SpvOpShiftRightArithmetic: - case SpvOp::SpvOpShiftRightLogical: - case SpvOp::SpvOpSLessThan: - case SpvOp::SpvOpSLessThanEqual: - case SpvOp::SpvOpSMod: - case SpvOp::SpvOpSNegate: - case SpvOp::SpvOpSRem: - case SpvOp::SpvOpSConvert: - case SpvOp::SpvOpUConvert: - case SpvOp::SpvOpUDiv: - case SpvOp::SpvOpUGreaterThan: - case SpvOp::SpvOpUGreaterThanEqual: - case SpvOp::SpvOpULessThan: - case SpvOp::SpvOpULessThanEqual: - case SpvOp::SpvOpUMod: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpIAdd: + case spv::Op::OpIEqual: + case spv::Op::OpIMul: + case spv::Op::OpINotEqual: + case spv::Op::OpISub: + case spv::Op::OpLogicalAnd: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNot: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpNot: + case spv::Op::OpSDiv: + case spv::Op::OpSelect: + case spv::Op::OpSGreaterThan: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpSLessThan: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpSMod: + case spv::Op::OpSNegate: + case spv::Op::OpSRem: + case spv::Op::OpSConvert: + case spv::Op::OpUConvert: + case spv::Op::OpUDiv: + case spv::Op::OpUGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpUMod: return true; default: return false; @@ -685,11 +686,11 @@ Instruction* InstructionFolder::FoldInstructionToConstant( bool InstructionFolder::IsFoldableType(Instruction* type_inst) const { // Support 32-bit integers. - if (type_inst->opcode() == SpvOpTypeInt) { + if (type_inst->opcode() == spv::Op::OpTypeInt) { return type_inst->GetSingleWordInOperand(0) == 32; } // Support booleans. - if (type_inst->opcode() == SpvOpTypeBool) { + if (type_inst->opcode() == spv::Op::OpTypeBool) { return true; } // Nothing else yet. @@ -699,7 +700,7 @@ bool InstructionFolder::IsFoldableType(Instruction* type_inst) const { bool InstructionFolder::FoldInstruction(Instruction* inst) const { bool modified = false; Instruction* folded_inst(inst); - while (folded_inst->opcode() != SpvOpCopyObject && + while (folded_inst->opcode() != spv::Op::OpCopyObject && FoldInstructionInternal(&*folded_inst)) { modified = true; } diff --git a/3rdparty/spirv-tools/source/opt/fold.h b/3rdparty/spirv-tools/source/opt/fold.h index 9e7c4705e..9a131d0df 100644 --- a/3rdparty/spirv-tools/source/opt/fold.h +++ b/3rdparty/spirv-tools/source/opt/fold.h @@ -55,7 +55,7 @@ class InstructionFolder { // IsFoldableOpcode test. If any error occurs during folding, the folder will // fail with a call to assert. uint32_t FoldScalars( - SpvOp opcode, + spv::Op opcode, const std::vector& operands) const; // Returns the result of performing an operation with the given |opcode| over @@ -72,12 +72,12 @@ class InstructionFolder { // IsFoldableOpcode test. If any error occurs during folding, the folder will // fail with a call to assert. std::vector FoldVectors( - SpvOp opcode, uint32_t num_dims, + spv::Op opcode, uint32_t num_dims, const std::vector& operands) const; // Returns true if |opcode| represents an operation handled by FoldScalars or // FoldVectors. - bool IsFoldableOpcode(SpvOp opcode) const; + bool IsFoldableOpcode(spv::Op opcode) const; // Returns true if |cst| is supported by FoldScalars and FoldVectors. bool IsFoldableConstant(const analysis::Constant* cst) const; @@ -126,22 +126,22 @@ class InstructionFolder { // Returns the single-word result from performing the given unary operation on // the operand value which is passed in as a 32-bit word. - uint32_t UnaryOperate(SpvOp opcode, uint32_t operand) const; + uint32_t UnaryOperate(spv::Op opcode, uint32_t operand) const; // Returns the single-word result from performing the given binary operation // on the operand values which are passed in as two 32-bit word. - uint32_t BinaryOperate(SpvOp opcode, uint32_t a, uint32_t b) const; + uint32_t BinaryOperate(spv::Op opcode, uint32_t a, uint32_t b) const; // Returns the single-word result from performing the given ternary operation // on the operand values which are passed in as three 32-bit word. - uint32_t TernaryOperate(SpvOp opcode, uint32_t a, uint32_t b, + uint32_t TernaryOperate(spv::Op opcode, uint32_t a, uint32_t b, uint32_t c) const; // Returns the single-word result from performing the given operation on the // operand words. This only works with 32-bit operations and uses boolean // convention that 0u is false, and anything else is boolean true. // TODO(qining): Support operands other than 32-bit wide. - uint32_t OperateWords(SpvOp opcode, + uint32_t OperateWords(spv::Op opcode, const std::vector& operand_words) const; bool FoldInstructionInternal(Instruction* inst) const; diff --git a/3rdparty/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp b/3rdparty/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp index 7a5187010..132be0c4b 100644 --- a/3rdparty/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp @@ -66,14 +66,14 @@ Pass::Status FoldSpecConstantOpAndCompositePass::Process() { if (const_mgr->GetType(inst) && !const_mgr->GetType(inst)->decoration_empty()) continue; - switch (SpvOp opcode = inst->opcode()) { + switch (spv::Op opcode = inst->opcode()) { // Records the values of Normal Constants. - case SpvOp::SpvOpConstantTrue: - case SpvOp::SpvOpConstantFalse: - case SpvOp::SpvOpConstant: - case SpvOp::SpvOpConstantNull: - case SpvOp::SpvOpConstantComposite: - case SpvOp::SpvOpSpecConstantComposite: { + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpConstant: + case spv::Op::OpConstantNull: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: { // A Constant instance will be created if the given instruction is a // Normal Constant whose value(s) are fixed. Note that for a composite // Spec Constant defined with OpSpecConstantComposite instruction, if @@ -84,8 +84,8 @@ Pass::Status FoldSpecConstantOpAndCompositePass::Process() { if (auto const_value = const_mgr->GetConstantFromInst(inst)) { // Need to replace the OpSpecConstantComposite instruction with a // corresponding OpConstantComposite instruction. - if (opcode == SpvOp::SpvOpSpecConstantComposite) { - inst->SetOpcode(SpvOp::SpvOpConstantComposite); + if (opcode == spv::Op::OpSpecConstantComposite) { + inst->SetOpcode(spv::Op::OpConstantComposite); modified = true; } const_mgr->MapConstantToInst(const_value, inst); @@ -99,7 +99,7 @@ Pass::Status FoldSpecConstantOpAndCompositePass::Process() { // Constants will be added to id_to_const_val_ and const_val_to_id_ so // that we can use the new Normal Constants when folding following Spec // Constants. - case SpvOp::SpvOpSpecConstantOp: + case spv::Op::OpSpecConstantOp: modified |= ProcessOpSpecConstantOp(&inst_iter); break; default: @@ -118,11 +118,11 @@ bool FoldSpecConstantOpAndCompositePass::ProcessOpSpecConstantOp( "The first in-operand of OpSpecConstantOp instruction must be of " "SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER type"); - switch (static_cast(inst->GetSingleWordInOperand(0))) { - case SpvOp::SpvOpCompositeExtract: - case SpvOp::SpvOpVectorShuffle: - case SpvOp::SpvOpCompositeInsert: - case SpvOp::SpvOpQuantizeToF16: + switch (static_cast(inst->GetSingleWordInOperand(0))) { + case spv::Op::OpCompositeExtract: + case spv::Op::OpVectorShuffle: + case spv::Op::OpCompositeInsert: + case spv::Op::OpQuantizeToF16: folded_inst = FoldWithInstructionFolder(pos); break; default: @@ -165,7 +165,7 @@ Instruction* FoldSpecConstantOpAndCompositePass::FoldWithInstructionFolder( // instruction and pass it to the instruction folder. std::unique_ptr inst((*inst_iter_ptr)->Clone(context())); inst->SetOpcode( - static_cast((*inst_iter_ptr)->GetSingleWordInOperand(0))); + static_cast((*inst_iter_ptr)->GetSingleWordInOperand(0))); inst->RemoveOperand(2); // We want the current instruction to be replaced by an |OpConstant*| @@ -289,7 +289,7 @@ Instruction* FoldSpecConstantOpAndCompositePass::DoComponentWiseOperation( const Instruction* inst = &**pos; analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); const analysis::Type* result_type = const_mgr->GetType(inst); - SpvOp spec_opcode = static_cast(inst->GetSingleWordInOperand(0)); + spv::Op spec_opcode = static_cast(inst->GetSingleWordInOperand(0)); // Check and collect operands. std::vector operands; diff --git a/3rdparty/spirv-tools/source/opt/folding_rules.cpp b/3rdparty/spirv-tools/source/opt/folding_rules.cpp index 3d803addc..1a4c03d7e 100644 --- a/3rdparty/spirv-tools/source/opt/folding_rules.cpp +++ b/3rdparty/spirv-tools/source/opt/folding_rules.cpp @@ -27,15 +27,15 @@ namespace spvtools { namespace opt { namespace { -const uint32_t kExtractCompositeIdInIdx = 0; -const uint32_t kInsertObjectIdInIdx = 0; -const uint32_t kInsertCompositeIdInIdx = 1; -const uint32_t kExtInstSetIdInIdx = 0; -const uint32_t kExtInstInstructionInIdx = 1; -const uint32_t kFMixXIdInIdx = 2; -const uint32_t kFMixYIdInIdx = 3; -const uint32_t kFMixAIdInIdx = 4; -const uint32_t kStoreObjectInIdx = 1; +constexpr uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kInsertObjectIdInIdx = 0; +constexpr uint32_t kInsertCompositeIdInIdx = 1; +constexpr uint32_t kExtInstSetIdInIdx = 0; +constexpr uint32_t kExtInstInstructionInIdx = 1; +constexpr uint32_t kFMixXIdInIdx = 2; +constexpr uint32_t kFMixYIdInIdx = 3; +constexpr uint32_t kFMixAIdInIdx = 4; +constexpr uint32_t kStoreObjectInIdx = 1; // Some image instructions may contain an "image operands" argument. // Returns the operand index for the "image operands". @@ -43,33 +43,33 @@ const uint32_t kStoreObjectInIdx = 1; int32_t ImageOperandsMaskInOperandIndex(Instruction* inst) { const auto opcode = inst->opcode(); switch (opcode) { - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleExplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageFetch: - case SpvOpImageRead: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleExplicitLod: - case SpvOpImageSparseSampleProjImplicitLod: - case SpvOpImageSparseSampleProjExplicitLod: - case SpvOpImageSparseFetch: - case SpvOpImageSparseRead: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageFetch: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseRead: return inst->NumOperands() > 4 ? 2 : -1; - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleDrefExplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageGather: - case SpvOpImageDrefGather: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: - case SpvOpImageSparseSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleProjDrefExplicitLod: - case SpvOpImageSparseGather: - case SpvOpImageSparseDrefGather: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: return inst->NumOperands() > 5 ? 3 : -1; - case SpvOpImageWrite: + case spv::Op::OpImageWrite: return inst->NumOperands() > 3 ? 3 : -1; default: return -1; @@ -304,7 +304,7 @@ uint32_t Reciprocal(analysis::ConstantManager* const_mgr, FoldingRule ReciprocalFDiv() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv); + assert(inst->opcode() == spv::Op::OpFDiv); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -333,7 +333,7 @@ FoldingRule ReciprocalFDiv() { // Don't fold a null constant. return false; } - inst->SetOpcode(SpvOpFMul); + inst->SetOpcode(spv::Op::OpFMul); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0u)}}, {SPV_OPERAND_TYPE_ID, {id}}}); @@ -348,7 +348,8 @@ FoldingRule ReciprocalFDiv() { FoldingRule MergeNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate); + assert(inst->opcode() == spv::Op::OpFNegate || + inst->opcode() == spv::Op::OpSNegate); (void)constants; const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -362,7 +363,7 @@ FoldingRule MergeNegateArithmetic() { if (op_inst->opcode() == inst->opcode()) { // Elide negates. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(0u)}}}); return true; @@ -382,7 +383,8 @@ FoldingRule MergeNegateArithmetic() { FoldingRule MergeNegateMulDivArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate); + assert(inst->opcode() == spv::Op::OpFNegate || + inst->opcode() == spv::Op::OpSNegate); (void)constants; analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = @@ -398,9 +400,10 @@ FoldingRule MergeNegateMulDivArithmetic() { uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; - SpvOp opcode = op_inst->opcode(); - if (opcode == SpvOpFMul || opcode == SpvOpFDiv || opcode == SpvOpIMul || - opcode == SpvOpSDiv || opcode == SpvOpUDiv) { + spv::Op opcode = op_inst->opcode(); + if (opcode == spv::Op::OpFMul || opcode == spv::Op::OpFDiv || + opcode == spv::Op::OpIMul || opcode == spv::Op::OpSDiv || + opcode == spv::Op::OpUDiv) { std::vector op_constants = const_mgr->GetOperandConstants(op_inst); // Merge negate into mul or div if one operand is constant. @@ -413,7 +416,8 @@ FoldingRule MergeNegateMulDivArithmetic() { : op_inst->GetSingleWordInOperand(1u); // Change this instruction to a mul/div. inst->SetOpcode(op_inst->opcode()); - if (opcode == SpvOpFDiv || opcode == SpvOpUDiv || opcode == SpvOpSDiv) { + if (opcode == spv::Op::OpFDiv || opcode == spv::Op::OpUDiv || + opcode == spv::Op::OpSDiv) { uint32_t op0 = zero_is_variable ? non_const_id : neg_id; uint32_t op1 = zero_is_variable ? neg_id : non_const_id; inst->SetInOperands( @@ -440,7 +444,8 @@ FoldingRule MergeNegateMulDivArithmetic() { FoldingRule MergeNegateAddSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate); + assert(inst->opcode() == spv::Op::OpFNegate || + inst->opcode() == spv::Op::OpSNegate); (void)constants; analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = @@ -456,14 +461,16 @@ FoldingRule MergeNegateAddSubArithmetic() { uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; - if (op_inst->opcode() == SpvOpFAdd || op_inst->opcode() == SpvOpFSub || - op_inst->opcode() == SpvOpIAdd || op_inst->opcode() == SpvOpISub) { + if (op_inst->opcode() == spv::Op::OpFAdd || + op_inst->opcode() == spv::Op::OpFSub || + op_inst->opcode() == spv::Op::OpIAdd || + op_inst->opcode() == spv::Op::OpISub) { std::vector op_constants = const_mgr->GetOperandConstants(op_inst); if (op_constants[0] || op_constants[1]) { bool zero_is_variable = op_constants[0] == nullptr; - bool is_add = (op_inst->opcode() == SpvOpFAdd) || - (op_inst->opcode() == SpvOpIAdd); + bool is_add = (op_inst->opcode() == spv::Op::OpFAdd) || + (op_inst->opcode() == spv::Op::OpIAdd); bool swap_operands = !is_add || zero_is_variable; bool negate_const = is_add; const analysis::Constant* c = ConstInput(op_constants); @@ -481,7 +488,8 @@ FoldingRule MergeNegateAddSubArithmetic() { uint32_t op1 = zero_is_variable ? const_id : op_inst->GetSingleWordInOperand(1u); if (swap_operands) std::swap(op0, op1); - inst->SetOpcode(HasFloatingPoint(type) ? SpvOpFSub : SpvOpISub); + inst->SetOpcode(HasFloatingPoint(type) ? spv::Op::OpFSub + : spv::Op::OpISub); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {op0}}, {SPV_OPERAND_TYPE_ID, {op1}}}); return true; @@ -512,7 +520,7 @@ bool HasZero(const analysis::Constant* c) { // id. Returns 0 if the result is not a valid value. The input types must be // Float. uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, - SpvOp opcode, + spv::Op opcode, const analysis::Constant* input1, const analysis::Constant* input2) { const analysis::Type* type = input1->type(); @@ -535,17 +543,17 @@ uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, } \ static_assert(true, "require extra semicolon") switch (opcode) { - case SpvOpFMul: + case spv::Op::OpFMul: FOLD_OP(*); break; - case SpvOpFDiv: + case spv::Op::OpFDiv: if (HasZero(input2)) return 0; FOLD_OP(/); break; - case SpvOpFAdd: + case spv::Op::OpFAdd: FOLD_OP(+); break; - case SpvOpFSub: + case spv::Op::OpFSub: FOLD_OP(-); break; default: @@ -561,7 +569,8 @@ uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, // id. Returns 0 if the result is not a valid value. The input types must be // Integers. uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, - SpvOp opcode, const analysis::Constant* input1, + spv::Op opcode, + const analysis::Constant* input1, const analysis::Constant* input2) { assert(input1->type()->AsInteger()); const analysis::Integer* type = input1->type()->AsInteger(); @@ -582,17 +591,17 @@ uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, } \ static_assert(true, "require extra semicolon") switch (opcode) { - case SpvOpIMul: + case spv::Op::OpIMul: FOLD_OP(*); break; - case SpvOpSDiv: - case SpvOpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpUDiv: assert(false && "Should not merge integer division"); break; - case SpvOpIAdd: + case spv::Op::OpIAdd: FOLD_OP(+); break; - case SpvOpISub: + case spv::Op::OpISub: FOLD_OP(-); break; default: @@ -607,7 +616,7 @@ uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, // Performs |input1| |opcode| |input2| and returns the merged constant result // id. Returns 0 if the result is not a valid value. The input types must be // Integers, Floats or Vectors of such. -uint32_t PerformOperation(analysis::ConstantManager* const_mgr, SpvOp opcode, +uint32_t PerformOperation(analysis::ConstantManager* const_mgr, spv::Op opcode, const analysis::Constant* input1, const analysis::Constant* input2) { assert(input1 && input2); @@ -667,7 +676,8 @@ uint32_t PerformOperation(analysis::ConstantManager* const_mgr, SpvOp opcode, FoldingRule MergeMulMulArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul); + assert(inst->opcode() == spv::Op::OpFMul || + inst->opcode() == spv::Op::OpIMul); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -719,7 +729,7 @@ FoldingRule MergeMulMulArithmetic() { FoldingRule MergeMulDivArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFMul); + assert(inst->opcode() == spv::Op::OpFMul); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); @@ -733,10 +743,10 @@ FoldingRule MergeMulDivArithmetic() { for (uint32_t i = 0; i < 2; i++) { uint32_t op_id = inst->GetSingleWordInOperand(i); Instruction* op_inst = def_use_mgr->GetDef(op_id); - if (op_inst->opcode() == SpvOpFDiv) { + if (op_inst->opcode() == spv::Op::OpFDiv) { if (op_inst->GetSingleWordInOperand(1) == inst->GetSingleWordInOperand(1 - i)) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(0)}}}); return true; @@ -749,7 +759,7 @@ FoldingRule MergeMulDivArithmetic() { Instruction* other_inst = NonConstInput(context, constants[0], inst); if (!other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFDiv) { + if (other_inst->opcode() == spv::Op::OpFDiv) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -793,7 +803,8 @@ FoldingRule MergeMulDivArithmetic() { FoldingRule MergeMulNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul); + assert(inst->opcode() == spv::Op::OpFMul || + inst->opcode() == spv::Op::OpIMul); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -809,8 +820,8 @@ FoldingRule MergeMulNegateArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFNegate || - other_inst->opcode() == SpvOpSNegate) { + if (other_inst->opcode() == spv::Op::OpFNegate || + other_inst->opcode() == spv::Op::OpSNegate) { uint32_t neg_id = NegateConstant(const_mgr, const_input1); inst->SetInOperands( @@ -833,7 +844,7 @@ FoldingRule MergeMulNegateArithmetic() { FoldingRule MergeDivDivArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv); + assert(inst->opcode() == spv::Op::OpFDiv); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -856,10 +867,10 @@ FoldingRule MergeDivDivArithmetic() { bool other_first_is_variable = other_constants[0] == nullptr; - SpvOp merge_op = inst->opcode(); + spv::Op merge_op = inst->opcode(); if (other_first_is_variable) { // Constants magnify. - merge_op = SpvOpFMul; + merge_op = spv::Op::OpFMul; } // This is an x / (*) case. Swap the inputs. Doesn't harm multiply @@ -873,10 +884,10 @@ FoldingRule MergeDivDivArithmetic() { ? other_inst->GetSingleWordInOperand(0u) : other_inst->GetSingleWordInOperand(1u); - SpvOp op = inst->opcode(); + spv::Op op = inst->opcode(); if (!first_is_variable && !other_first_is_variable) { // Effectively div of 1/x, so change to multiply. - op = SpvOpFMul; + op = spv::Op::OpFMul; } uint32_t op1 = merged_id; @@ -904,7 +915,7 @@ FoldingRule MergeDivDivArithmetic() { FoldingRule MergeDivMulArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv); + assert(inst->opcode() == spv::Op::OpFDiv); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -918,11 +929,11 @@ FoldingRule MergeDivMulArithmetic() { uint32_t op_id = inst->GetSingleWordInOperand(0); Instruction* op_inst = def_use_mgr->GetDef(op_id); - if (op_inst->opcode() == SpvOpFMul) { + if (op_inst->opcode() == spv::Op::OpFMul) { for (uint32_t i = 0; i < 2; i++) { if (op_inst->GetSingleWordInOperand(i) == inst->GetSingleWordInOperand(1)) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(1 - i)}}}); return true; @@ -936,7 +947,7 @@ FoldingRule MergeDivMulArithmetic() { if (!other_inst->IsFloatingPointFoldingAllowed()) return false; bool first_is_variable = constants[0] == nullptr; - if (other_inst->opcode() == SpvOpFMul) { + if (other_inst->opcode() == spv::Op::OpFMul) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -976,7 +987,7 @@ FoldingRule MergeDivMulArithmetic() { FoldingRule MergeDivNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv); + assert(inst->opcode() == spv::Op::OpFDiv); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); if (!inst->IsFloatingPointFoldingAllowed()) return false; @@ -986,7 +997,7 @@ FoldingRule MergeDivNegateArithmetic() { if (!other_inst->IsFloatingPointFoldingAllowed()) return false; bool first_is_variable = constants[0] == nullptr; - if (other_inst->opcode() == SpvOpFNegate) { + if (other_inst->opcode() == spv::Op::OpFNegate) { uint32_t neg_id = NegateConstant(const_mgr, const_input1); if (first_is_variable) { @@ -1012,7 +1023,8 @@ FoldingRule MergeDivNegateArithmetic() { FoldingRule MergeAddNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); bool uses_float = HasFloatingPoint(type); @@ -1024,9 +1036,10 @@ FoldingRule MergeAddNegateArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpSNegate || - other_inst->opcode() == SpvOpFNegate) { - inst->SetOpcode(HasFloatingPoint(type) ? SpvOpFSub : SpvOpISub); + if (other_inst->opcode() == spv::Op::OpSNegate || + other_inst->opcode() == spv::Op::OpFNegate) { + inst->SetOpcode(HasFloatingPoint(type) ? spv::Op::OpFSub + : spv::Op::OpISub); uint32_t const_id = constants[0] ? inst->GetSingleWordInOperand(0u) : inst->GetSingleWordInOperand(1u); inst->SetInOperands( @@ -1045,7 +1058,8 @@ FoldingRule MergeAddNegateArithmetic() { FoldingRule MergeSubNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub); + assert(inst->opcode() == spv::Op::OpFSub || + inst->opcode() == spv::Op::OpISub); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -1061,15 +1075,15 @@ FoldingRule MergeSubNegateArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpSNegate || - other_inst->opcode() == SpvOpFNegate) { + if (other_inst->opcode() == spv::Op::OpSNegate || + other_inst->opcode() == spv::Op::OpFNegate) { uint32_t op1 = 0; uint32_t op2 = 0; - SpvOp opcode = inst->opcode(); + spv::Op opcode = inst->opcode(); if (constants[0] != nullptr) { op1 = other_inst->GetSingleWordInOperand(0u); op2 = inst->GetSingleWordInOperand(0u); - opcode = HasFloatingPoint(type) ? SpvOpFAdd : SpvOpIAdd; + opcode = HasFloatingPoint(type) ? spv::Op::OpFAdd : spv::Op::OpIAdd; } else { op1 = NegateConstant(const_mgr, const_input1); op2 = other_inst->GetSingleWordInOperand(0u); @@ -1093,7 +1107,8 @@ FoldingRule MergeSubNegateArithmetic() { FoldingRule MergeAddAddArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1109,8 +1124,8 @@ FoldingRule MergeAddAddArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFAdd || - other_inst->opcode() == SpvOpIAdd) { + if (other_inst->opcode() == spv::Op::OpFAdd || + other_inst->opcode() == spv::Op::OpIAdd) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1140,7 +1155,8 @@ FoldingRule MergeAddAddArithmetic() { FoldingRule MergeAddSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1156,15 +1172,15 @@ FoldingRule MergeAddSubArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFSub || - other_inst->opcode() == SpvOpISub) { + if (other_inst->opcode() == spv::Op::OpFSub || + other_inst->opcode() == spv::Op::OpISub) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); if (!const_input2) return false; bool first_is_variable = other_constants[0] == nullptr; - SpvOp op = inst->opcode(); + spv::Op op = inst->opcode(); uint32_t op1 = 0; uint32_t op2 = 0; if (first_is_variable) { @@ -1199,7 +1215,8 @@ FoldingRule MergeAddSubArithmetic() { FoldingRule MergeSubAddArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub); + assert(inst->opcode() == spv::Op::OpFSub || + inst->opcode() == spv::Op::OpISub); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1215,8 +1232,8 @@ FoldingRule MergeSubAddArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFAdd || - other_inst->opcode() == SpvOpIAdd) { + if (other_inst->opcode() == spv::Op::OpFAdd || + other_inst->opcode() == spv::Op::OpIAdd) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1231,7 +1248,7 @@ FoldingRule MergeSubAddArithmetic() { // Subtract the constants. uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(), const_input1, const_input2); - SpvOp op = inst->opcode(); + spv::Op op = inst->opcode(); uint32_t op1 = 0; uint32_t op2 = 0; if (constants[0] == nullptr) { @@ -1264,7 +1281,8 @@ FoldingRule MergeSubAddArithmetic() { FoldingRule MergeSubSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub); + assert(inst->opcode() == spv::Op::OpFSub || + inst->opcode() == spv::Op::OpISub); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1280,8 +1298,8 @@ FoldingRule MergeSubSubArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFSub || - other_inst->opcode() == SpvOpISub) { + if (other_inst->opcode() == spv::Op::OpFSub || + other_inst->opcode() == spv::Op::OpISub) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1292,9 +1310,9 @@ FoldingRule MergeSubSubArithmetic() { // Merge the constants. uint32_t merged_id = 0; - SpvOp merge_op = inst->opcode(); + spv::Op merge_op = inst->opcode(); if (other_constants[0] == nullptr) { - merge_op = uses_float ? SpvOpFAdd : SpvOpIAdd; + merge_op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd; } else if (constants[0] == nullptr) { std::swap(const_input1, const_input2); } @@ -1302,10 +1320,10 @@ FoldingRule MergeSubSubArithmetic() { PerformOperation(const_mgr, merge_op, const_input1, const_input2); if (merged_id == 0) return false; - SpvOp op = inst->opcode(); + spv::Op op = inst->opcode(); if (constants[0] != nullptr && other_constants[0] != nullptr) { // Change the operation. - op = uses_float ? SpvOpFAdd : SpvOpIAdd; + op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd; } uint32_t op1 = 0; @@ -1333,13 +1351,14 @@ bool MergeGenericAddendSub(uint32_t addend, uint32_t sub, Instruction* inst) { IRContext* context = inst->context(); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); Instruction* sub_inst = def_use_mgr->GetDef(sub); - if (sub_inst->opcode() != SpvOpFSub && sub_inst->opcode() != SpvOpISub) + if (sub_inst->opcode() != spv::Op::OpFSub && + sub_inst->opcode() != spv::Op::OpISub) return false; - if (sub_inst->opcode() == SpvOpFSub && + if (sub_inst->opcode() == spv::Op::OpFSub && !sub_inst->IsFloatingPointFoldingAllowed()) return false; if (addend != sub_inst->GetSingleWordInOperand(1)) return false; - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {sub_inst->GetSingleWordInOperand(0)}}}); context->UpdateDefUse(inst); @@ -1355,7 +1374,8 @@ bool MergeGenericAddendSub(uint32_t addend, uint32_t sub, Instruction* inst) { FoldingRule MergeGenericAddSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); bool uses_float = HasFloatingPoint(type); @@ -1383,7 +1403,8 @@ bool FactorAddMulsOpnds(uint32_t factor0_0, uint32_t factor0_1, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); Instruction* new_add_inst = ir_builder.AddBinaryOp( inst->type_id(), inst->opcode(), factor0_1, factor1_1); - inst->SetOpcode(inst->opcode() == SpvOpFAdd ? SpvOpFMul : SpvOpIMul); + inst->SetOpcode(inst->opcode() == spv::Op::OpFAdd ? spv::Op::OpFMul + : spv::Op::OpIMul); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {factor0_0}}, {SPV_OPERAND_TYPE_ID, {new_add_inst->result_id()}}}); context->UpdateDefUse(inst); @@ -1395,7 +1416,8 @@ bool FactorAddMulsOpnds(uint32_t factor0_0, uint32_t factor0_1, FoldingRule FactorAddMuls() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); bool uses_float = HasFloatingPoint(type); @@ -1404,13 +1426,13 @@ FoldingRule FactorAddMuls() { analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); uint32_t add_op0 = inst->GetSingleWordInOperand(0); Instruction* add_op0_inst = def_use_mgr->GetDef(add_op0); - if (add_op0_inst->opcode() != SpvOpFMul && - add_op0_inst->opcode() != SpvOpIMul) + if (add_op0_inst->opcode() != spv::Op::OpFMul && + add_op0_inst->opcode() != spv::Op::OpIMul) return false; uint32_t add_op1 = inst->GetSingleWordInOperand(1); Instruction* add_op1_inst = def_use_mgr->GetDef(add_op1); - if (add_op1_inst->opcode() != SpvOpFMul && - add_op1_inst->opcode() != SpvOpIMul) + if (add_op1_inst->opcode() != spv::Op::OpFMul && + add_op1_inst->opcode() != spv::Op::OpIMul) return false; // Only perform this optimization if both of the muls only have one use. @@ -1418,7 +1440,7 @@ FoldingRule FactorAddMuls() { if (def_use_mgr->NumUses(add_op0_inst) > 1) return false; if (def_use_mgr->NumUses(add_op1_inst) > 1) return false; - if (add_op0_inst->opcode() == SpvOpFMul && + if (add_op0_inst->opcode() == spv::Op::OpFMul && (!add_op0_inst->IsFloatingPointFoldingAllowed() || !add_op1_inst->IsFloatingPointFoldingAllowed())) return false; @@ -1457,7 +1479,7 @@ void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); operands.push_back({SPV_OPERAND_TYPE_ID, {a}}); - inst->SetOpcode(SpvOpExtInst); + inst->SetOpcode(spv::Op::OpExtInst); inst->SetInOperands(std::move(operands)); } @@ -1468,7 +1490,7 @@ void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { // a + (x * y) = Fma x y a bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpFAdd); + assert(inst->opcode() == spv::Op::OpFAdd); if (!inst->IsFloatingPointFoldingAllowed()) { return false; @@ -1479,7 +1501,7 @@ bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, uint32_t op_id = inst->GetSingleWordInOperand(i); Instruction* op_inst = def_use_mgr->GetDef(op_id); - if (op_inst->opcode() != SpvOpFMul) { + if (op_inst->opcode() != spv::Op::OpFMul) { continue; } @@ -1514,7 +1536,7 @@ void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, sub->context(), sub, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - Instruction* neg = ir_builder.AddUnaryOp(sub->type_id(), SpvOpFNegate, + Instruction* neg = ir_builder.AddUnaryOp(sub->type_id(), spv::Op::OpFNegate, negate_addition ? a : x); uint32_t neg_op = neg->result_id(); // -a : -x @@ -1525,7 +1547,7 @@ void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); operands.push_back({SPV_OPERAND_TYPE_ID, {negate_addition ? neg_op : a}}); - sub->SetOpcode(SpvOpExtInst); + sub->SetOpcode(spv::Op::OpExtInst); sub->SetInOperands(std::move(operands)); } @@ -1536,7 +1558,7 @@ void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, // a - (x * y) = Fma -x y a bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, const std::vector&) { - assert(sub->opcode() == SpvOpFSub); + assert(sub->opcode() == spv::Op::OpFSub); if (!sub->IsFloatingPointFoldingAllowed()) { return false; @@ -1547,7 +1569,7 @@ bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, uint32_t op_id = sub->GetSingleWordInOperand(i); Instruction* mul = def_use_mgr->GetDef(op_id); - if (mul->opcode() != SpvOpFMul) { + if (mul->opcode() != spv::Op::OpFMul) { continue; } @@ -1567,7 +1589,8 @@ bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, FoldingRule IntMultipleBy1() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpIMul && "Wrong opcode. Should be OpIMul."); + assert(inst->opcode() == spv::Op::OpIMul && + "Wrong opcode. Should be OpIMul."); for (uint32_t i = 0; i < 2; i++) { if (constants[i] == nullptr) { continue; @@ -1579,7 +1602,7 @@ FoldingRule IntMultipleBy1() { bool is_one = (width == 32) ? int_constant->GetU32BitValue() == 1u : int_constant->GetU64BitValue() == 1ull; if (is_one) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1 - i)}}}); return true; @@ -1596,7 +1619,7 @@ FoldingRule IntMultipleBy1() { uint32_t GetNumOfElementsContributedByOperand(IRContext* context, const Instruction* inst, uint32_t index) { - assert(inst->opcode() == SpvOpCompositeConstruct); + assert(inst->opcode() == spv::Op::OpCompositeConstruct); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -1627,7 +1650,7 @@ uint32_t GetNumOfElementsContributedByOperand(IRContext* context, // out-of-bounds. |inst| must be an |OpCompositeConstruct| instruction. std::vector GetExtractOperandsForElementOfCompositeConstruct( IRContext* context, const Instruction* inst, uint32_t result_index) { - assert(inst->opcode() == SpvOpCompositeConstruct); + assert(inst->opcode() == spv::Op::OpCompositeConstruct); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -1666,7 +1689,7 @@ bool CompositeConstructFeedingExtract( const std::vector&) { // If the input to an OpCompositeExtract is an OpCompositeConstruct, // then we can simply use the appropriate element in the construction. - assert(inst->opcode() == SpvOpCompositeExtract && + assert(inst->opcode() == spv::Op::OpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); @@ -1678,7 +1701,7 @@ bool CompositeConstructFeedingExtract( uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* cinst = def_use_mgr->GetDef(cid); - if (cinst->opcode() != SpvOpCompositeConstruct) { + if (cinst->opcode() != spv::Op::OpCompositeConstruct) { return false; } @@ -1700,7 +1723,7 @@ bool CompositeConstructFeedingExtract( if (operands.size() == 1) { // If there were no extra indices, then we have the final object. No need // to extract any more. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); } inst->SetInOperands(std::move(operands)); @@ -1738,8 +1761,8 @@ const analysis::Type* GetElementType(uint32_t type_id, bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { assert(inst_1->opcode() == inst_2->opcode() && "Expecting the opcodes to be the same."); - assert((inst_1->opcode() == SpvOpCompositeInsert || - inst_1->opcode() == SpvOpCompositeExtract) && + assert((inst_1->opcode() == spv::Op::OpCompositeInsert || + inst_1->opcode() == spv::Op::OpCompositeExtract) && "Instructions must be OpCompositeInsert or OpCompositeExtract."); if (inst_1->NumInOperands() != inst_2->NumInOperands()) { @@ -1747,7 +1770,7 @@ bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { } uint32_t first_index_position = - (inst_1->opcode() == SpvOpCompositeInsert ? 2 : 1); + (inst_1->opcode() == spv::Op::OpCompositeInsert ? 2 : 1); for (uint32_t i = first_index_position; i < inst_1->NumInOperands() - 1; i++) { if (inst_1->GetSingleWordInOperand(i) != @@ -1766,7 +1789,7 @@ bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { bool CompositeExtractFeedingConstruct( IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpCompositeConstruct && + assert(inst->opcode() == spv::Op::OpCompositeConstruct && "Wrong opcode. Should be OpCompositeConstruct."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); uint32_t original_id = 0; @@ -1788,7 +1811,7 @@ bool CompositeExtractFeedingConstruct( first_element_inst = element_inst; } - if (element_inst->opcode() != SpvOpCompositeExtract) { + if (element_inst->opcode() != spv::Op::OpCompositeExtract) { return false; } @@ -1828,14 +1851,14 @@ bool CompositeExtractFeedingConstruct( if (first_element_inst->NumInOperands() == 2) { // Simplify by using the original object. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {original_id}}}); return true; } // Copies the original id and all indexes except for the last to the new // extract instruction. - inst->SetOpcode(SpvOpCompositeExtract); + inst->SetOpcode(spv::Op::OpCompositeExtract); inst->SetInOperands(std::vector(first_element_inst->begin() + 2, first_element_inst->end() - 1)); return true; @@ -1844,13 +1867,13 @@ bool CompositeExtractFeedingConstruct( FoldingRule InsertFeedingExtract() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpCompositeExtract && + assert(inst->opcode() == spv::Op::OpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* cinst = def_use_mgr->GetDef(cid); - if (cinst->opcode() != SpvOpCompositeInsert) { + if (cinst->opcode() != spv::Op::OpCompositeInsert) { return false; } @@ -1870,7 +1893,7 @@ FoldingRule InsertFeedingExtract() { // We are extracting the element that was inserted. if (i == inst->NumInOperands() && i + 1 == cinst->NumInOperands()) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {cinst->GetSingleWordInOperand(kInsertObjectIdInIdx)}}}); @@ -1919,14 +1942,14 @@ FoldingRule InsertFeedingExtract() { FoldingRule VectorShuffleFeedingExtract() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpCompositeExtract && + assert(inst->opcode() == spv::Op::OpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* cinst = def_use_mgr->GetDef(cid); - if (cinst->opcode() != SpvOpVectorShuffle) { + if (cinst->opcode() != spv::Op::OpVectorShuffle) { return false; } @@ -1947,7 +1970,7 @@ FoldingRule VectorShuffleFeedingExtract() { // Extracting an undefined value so fold this extract into an undef. const uint32_t undef_literal_value = 0xffffffff; if (new_index == undef_literal_value) { - inst->SetOpcode(SpvOpUndef); + inst->SetOpcode(spv::Op::OpUndef); inst->SetInOperands({}); return true; } @@ -1975,7 +1998,7 @@ FoldingRule VectorShuffleFeedingExtract() { FoldingRule FMixFeedingExtract() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpCompositeExtract && + assert(inst->opcode() == spv::Op::OpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1984,7 +2007,7 @@ FoldingRule FMixFeedingExtract() { inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* composite_inst = def_use_mgr->GetDef(composite_id); - if (composite_inst->opcode() != SpvOpExtInst) { + if (composite_inst->opcode() != spv::Op::OpExtInst) { return false; } @@ -2004,7 +2027,7 @@ FoldingRule FMixFeedingExtract() { a->SetInOperand(kExtractCompositeIdInIdx, {a_id}); context->get_instruction_folder().FoldInstruction(a.get()); - if (a->opcode() != SpvOpCopyObject) { + if (a->opcode() != spv::Op::OpCopyObject) { return false; } @@ -2066,7 +2089,7 @@ std::map GetInsertedValues(Instruction* inst) { analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr(); std::map values_inserted; Instruction* current_inst = inst; - while (current_inst->opcode() == SpvOpCompositeInsert) { + while (current_inst->opcode() == spv::Op::OpCompositeInsert) { if (current_inst->NumInOperands() > inst->NumInOperands()) { // This is the catch the case // %2 = OpCompositeInsert %m2x2int %v2int_1_0 %m2x2int_undef 0 @@ -2108,7 +2131,7 @@ bool DoInsertedValuesCoverEntireObject( // Returns the type of the element that immediately contains the element being // inserted by the OpCompositeInsert instruction |inst|. const analysis::Type* GetContainerType(Instruction* inst) { - assert(inst->opcode() == SpvOpCompositeInsert); + assert(inst->opcode() == spv::Op::OpCompositeInsert); analysis::TypeManager* type_mgr = inst->context()->get_type_mgr(); return GetElementType(inst->type_id(), inst->begin() + 4, inst->end() - 1, type_mgr); @@ -2140,7 +2163,7 @@ Instruction* BuildCompositeConstruct( // instruction is replaced with an OpCopyObject instead. void InsertConstructedObject(Instruction* inst, const Instruction* construct) { if (inst->NumInOperands() == 3) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {construct->result_id()}}}); } else { inst->SetInOperand(kInsertObjectIdInIdx, {construct->result_id()}); @@ -2153,7 +2176,7 @@ void InsertConstructedObject(Instruction* inst, const Instruction* construct) { bool CompositeInsertToCompositeConstruct( IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpCompositeInsert && + assert(inst->opcode() == spv::Op::OpCompositeInsert && "Wrong opcode. Should be OpCompositeInsert."); if (inst->NumInOperands() < 3) return false; @@ -2179,7 +2202,8 @@ FoldingRule RedundantPhi() { // itself, can be replaced by the value itself. return [](IRContext*, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpPhi && "Wrong opcode. Should be OpPhi."); + assert(inst->opcode() == spv::Op::OpPhi && + "Wrong opcode. Should be OpPhi."); uint32_t incoming_value = 0; @@ -2203,7 +2227,7 @@ FoldingRule RedundantPhi() { } // We have a single incoming value. Simplify using that value. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {incoming_value}}}); return true; }; @@ -2212,7 +2236,7 @@ FoldingRule RedundantPhi() { FoldingRule BitCastScalarOrVector() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpBitcast && constants.size() == 1); + assert(inst->opcode() == spv::Op::OpBitcast && constants.size() == 1); if (constants[0] == nullptr) return false; const analysis::Type* type = @@ -2232,7 +2256,7 @@ FoldingRule BitCastScalarOrVector() { auto new_feeder_id = const_mgr->GetDefiningInstruction(bitcasted_constant, inst->type_id()) ->result_id(); - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {new_feeder_id}}}); return true; }; @@ -2243,7 +2267,7 @@ FoldingRule RedundantSelect() { // constant can be replaced by one of the values return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpSelect && + assert(inst->opcode() == spv::Op::OpSelect && "Wrong opcode. Should be OpSelect."); assert(inst->NumInOperands() == 3); assert(constants.size() == 3); @@ -2253,14 +2277,14 @@ FoldingRule RedundantSelect() { if (true_id == false_id) { // Both results are the same, condition doesn't matter - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {true_id}}}); return true; } else if (constants[0]) { const analysis::Type* type = constants[0]->type(); if (type->AsBool()) { // Scalar constant value, select the corresponding value. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); if (constants[0]->AsNullConstant() || !constants[0]->AsBoolConstant()->value()) { inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {false_id}}}); @@ -2272,7 +2296,7 @@ FoldingRule RedundantSelect() { assert(type->AsVector()); if (constants[0]->AsNullConstant()) { // All values come from false id. - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {false_id}}}); return true; } else { @@ -2299,7 +2323,7 @@ FoldingRule RedundantSelect() { } } - inst->SetOpcode(SpvOpVectorShuffle); + inst->SetOpcode(spv::Op::OpVectorShuffle); inst->SetInOperands(std::move(ops)); return true; } @@ -2359,7 +2383,8 @@ FloatConstantKind getFloatConstantKind(const analysis::Constant* constant) { FoldingRule RedundantFAdd() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFAdd && "Wrong opcode. Should be OpFAdd."); + assert(inst->opcode() == spv::Op::OpFAdd && + "Wrong opcode. Should be OpFAdd."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2370,7 +2395,7 @@ FoldingRule RedundantFAdd() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero || kind1 == FloatConstantKind::Zero) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand( kind0 == FloatConstantKind::Zero ? 1 : 0)}}}); @@ -2384,7 +2409,8 @@ FoldingRule RedundantFAdd() { FoldingRule RedundantFSub() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFSub && "Wrong opcode. Should be OpFSub."); + assert(inst->opcode() == spv::Op::OpFSub && + "Wrong opcode. Should be OpFSub."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2395,14 +2421,14 @@ FoldingRule RedundantFSub() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero) { - inst->SetOpcode(SpvOpFNegate); + inst->SetOpcode(spv::Op::OpFNegate); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1)}}}); return true; } if (kind1 == FloatConstantKind::Zero) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); return true; @@ -2415,7 +2441,8 @@ FoldingRule RedundantFSub() { FoldingRule RedundantFMul() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFMul && "Wrong opcode. Should be OpFMul."); + assert(inst->opcode() == spv::Op::OpFMul && + "Wrong opcode. Should be OpFMul."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2426,7 +2453,7 @@ FoldingRule RedundantFMul() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero || kind1 == FloatConstantKind::Zero) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand( kind0 == FloatConstantKind::Zero ? 0 : 1)}}}); @@ -2434,7 +2461,7 @@ FoldingRule RedundantFMul() { } if (kind0 == FloatConstantKind::One || kind1 == FloatConstantKind::One) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand( kind0 == FloatConstantKind::One ? 1 : 0)}}}); @@ -2448,7 +2475,8 @@ FoldingRule RedundantFMul() { FoldingRule RedundantFDiv() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv && "Wrong opcode. Should be OpFDiv."); + assert(inst->opcode() == spv::Op::OpFDiv && + "Wrong opcode. Should be OpFDiv."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2459,14 +2487,14 @@ FoldingRule RedundantFDiv() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); return true; } if (kind1 == FloatConstantKind::One) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); return true; @@ -2479,7 +2507,7 @@ FoldingRule RedundantFDiv() { FoldingRule RedundantFMix() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpExtInst && + assert(inst->opcode() == spv::Op::OpExtInst && "Wrong opcode. Should be OpExtInst."); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2497,7 +2525,7 @@ FoldingRule RedundantFMix() { FloatConstantKind kind4 = getFloatConstantKind(constants[4]); if (kind4 == FloatConstantKind::Zero || kind4 == FloatConstantKind::One) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(kind4 == FloatConstantKind::Zero @@ -2515,7 +2543,8 @@ FoldingRule RedundantFMix() { FoldingRule RedundantIAdd() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpIAdd && "Wrong opcode. Should be OpIAdd."); + assert(inst->opcode() == spv::Op::OpIAdd && + "Wrong opcode. Should be OpIAdd."); uint32_t operand = std::numeric_limits::max(); const analysis::Type* operand_type = nullptr; @@ -2531,9 +2560,9 @@ FoldingRule RedundantIAdd() { const analysis::Type* inst_type = context->get_type_mgr()->GetType(inst->type_id()); if (inst_type->IsSame(operand_type)) { - inst->SetOpcode(SpvOpCopyObject); + inst->SetOpcode(spv::Op::OpCopyObject); } else { - inst->SetOpcode(SpvOpBitcast); + inst->SetOpcode(spv::Op::OpBitcast); } inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {operand}}}); return true; @@ -2547,7 +2576,8 @@ FoldingRule RedundantIAdd() { FoldingRule DotProductDoingExtract() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpDot && "Wrong opcode. Should be OpDot."); + assert(inst->opcode() == spv::Op::OpDot && + "Wrong opcode. Should be OpDot."); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -2573,7 +2603,7 @@ FoldingRule DotProductDoingExtract() { std::vector components; components = constants[i]->GetVectorComponents(const_mgr); - const uint32_t kNotFound = std::numeric_limits::max(); + constexpr uint32_t kNotFound = std::numeric_limits::max(); uint32_t component_with_one = kNotFound; bool all_others_zero = true; @@ -2606,7 +2636,7 @@ FoldingRule DotProductDoingExtract() { operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {component_with_one}}); - inst->SetOpcode(SpvOpCompositeExtract); + inst->SetOpcode(spv::Op::OpCompositeExtract); inst->SetInOperands(std::move(operands)); return true; } @@ -2621,20 +2651,22 @@ FoldingRule DotProductDoingExtract() { FoldingRule StoringUndef() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpStore && "Wrong opcode. Should be OpStore."); + assert(inst->opcode() == spv::Op::OpStore && + "Wrong opcode. Should be OpStore."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); // If this is a volatile store, the store cannot be removed. if (inst->NumInOperands() == 3) { - if (inst->GetSingleWordInOperand(2) & SpvMemoryAccessVolatileMask) { + if (inst->GetSingleWordInOperand(2) & + uint32_t(spv::MemoryAccessMask::Volatile)) { return false; } } uint32_t object_id = inst->GetSingleWordInOperand(kStoreObjectInIdx); Instruction* object_inst = def_use_mgr->GetDef(object_id); - if (object_inst->opcode() == SpvOpUndef) { + if (object_inst->opcode() == spv::Op::OpUndef) { inst->ToNop(); return true; } @@ -2645,7 +2677,7 @@ FoldingRule StoringUndef() { FoldingRule VectorShuffleFeedingShuffle() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpVectorShuffle && + assert(inst->opcode() == spv::Op::OpVectorShuffle && "Wrong opcode. Should be OpVectorShuffle."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); @@ -2658,13 +2690,13 @@ FoldingRule VectorShuffleFeedingShuffle() { uint32_t op0_length = op0_type->element_count(); bool feeder_is_op0 = true; - if (feeding_shuffle_inst->opcode() != SpvOpVectorShuffle) { + if (feeding_shuffle_inst->opcode() != spv::Op::OpVectorShuffle) { feeding_shuffle_inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(1)); feeder_is_op0 = false; } - if (feeding_shuffle_inst->opcode() != SpvOpVectorShuffle) { + if (feeding_shuffle_inst->opcode() != spv::Op::OpVectorShuffle) { return false; } @@ -2775,7 +2807,7 @@ FoldingRule VectorShuffleFeedingShuffle() { FoldingRule RemoveRedundantOperands() { return [](IRContext*, Instruction* inst, const std::vector&) { - assert(inst->opcode() == SpvOpEntryPoint && + assert(inst->opcode() == spv::Op::OpEntryPoint && "Wrong opcode. Should be OpEntryPoint."); bool has_redundant_operand = false; std::unordered_set seen_operands; @@ -2808,46 +2840,52 @@ FoldingRule UpdateImageOperands() { const std::vector& constants) { const auto opcode = inst->opcode(); (void)opcode; - assert((opcode == SpvOpImageSampleImplicitLod || - opcode == SpvOpImageSampleExplicitLod || - opcode == SpvOpImageSampleDrefImplicitLod || - opcode == SpvOpImageSampleDrefExplicitLod || - opcode == SpvOpImageSampleProjImplicitLod || - opcode == SpvOpImageSampleProjExplicitLod || - opcode == SpvOpImageSampleProjDrefImplicitLod || - opcode == SpvOpImageSampleProjDrefExplicitLod || - opcode == SpvOpImageFetch || opcode == SpvOpImageGather || - opcode == SpvOpImageDrefGather || opcode == SpvOpImageRead || - opcode == SpvOpImageWrite || - opcode == SpvOpImageSparseSampleImplicitLod || - opcode == SpvOpImageSparseSampleExplicitLod || - opcode == SpvOpImageSparseSampleDrefImplicitLod || - opcode == SpvOpImageSparseSampleDrefExplicitLod || - opcode == SpvOpImageSparseSampleProjImplicitLod || - opcode == SpvOpImageSparseSampleProjExplicitLod || - opcode == SpvOpImageSparseSampleProjDrefImplicitLod || - opcode == SpvOpImageSparseSampleProjDrefExplicitLod || - opcode == SpvOpImageSparseFetch || - opcode == SpvOpImageSparseGather || - opcode == SpvOpImageSparseDrefGather || - opcode == SpvOpImageSparseRead) && + assert((opcode == spv::Op::OpImageSampleImplicitLod || + opcode == spv::Op::OpImageSampleExplicitLod || + opcode == spv::Op::OpImageSampleDrefImplicitLod || + opcode == spv::Op::OpImageSampleDrefExplicitLod || + opcode == spv::Op::OpImageSampleProjImplicitLod || + opcode == spv::Op::OpImageSampleProjExplicitLod || + opcode == spv::Op::OpImageSampleProjDrefImplicitLod || + opcode == spv::Op::OpImageSampleProjDrefExplicitLod || + opcode == spv::Op::OpImageFetch || + opcode == spv::Op::OpImageGather || + opcode == spv::Op::OpImageDrefGather || + opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || + opcode == spv::Op::OpImageSparseSampleImplicitLod || + opcode == spv::Op::OpImageSparseSampleExplicitLod || + opcode == spv::Op::OpImageSparseSampleDrefImplicitLod || + opcode == spv::Op::OpImageSparseSampleDrefExplicitLod || + opcode == spv::Op::OpImageSparseSampleProjImplicitLod || + opcode == spv::Op::OpImageSparseSampleProjExplicitLod || + opcode == spv::Op::OpImageSparseSampleProjDrefImplicitLod || + opcode == spv::Op::OpImageSparseSampleProjDrefExplicitLod || + opcode == spv::Op::OpImageSparseFetch || + opcode == spv::Op::OpImageSparseGather || + opcode == spv::Op::OpImageSparseDrefGather || + opcode == spv::Op::OpImageSparseRead) && "Wrong opcode. Should be an image instruction."); int32_t operand_index = ImageOperandsMaskInOperandIndex(inst); if (operand_index >= 0) { auto image_operands = inst->GetSingleWordInOperand(operand_index); - if (image_operands & SpvImageOperandsOffsetMask) { + if (image_operands & uint32_t(spv::ImageOperandsMask::Offset)) { uint32_t offset_operand_index = operand_index + 1; - if (image_operands & SpvImageOperandsBiasMask) offset_operand_index++; - if (image_operands & SpvImageOperandsLodMask) offset_operand_index++; - if (image_operands & SpvImageOperandsGradMask) + if (image_operands & uint32_t(spv::ImageOperandsMask::Bias)) + offset_operand_index++; + if (image_operands & uint32_t(spv::ImageOperandsMask::Lod)) + offset_operand_index++; + if (image_operands & uint32_t(spv::ImageOperandsMask::Grad)) offset_operand_index += 2; - assert(((image_operands & SpvImageOperandsConstOffsetMask) == 0) && + assert(((image_operands & + uint32_t(spv::ImageOperandsMask::ConstOffset)) == 0) && "Offset and ConstOffset may not be used together"); if (offset_operand_index < inst->NumOperands()) { if (constants[offset_operand_index]) { - image_operands = image_operands | SpvImageOperandsConstOffsetMask; - image_operands = image_operands & ~SpvImageOperandsOffsetMask; + image_operands = + image_operands | uint32_t(spv::ImageOperandsMask::ConstOffset); + image_operands = + image_operands & ~uint32_t(spv::ImageOperandsMask::Offset); inst->SetInOperand(operand_index, {image_operands}); return true; } @@ -2866,108 +2904,119 @@ void FoldingRules::AddFoldingRules() { // Note that the order in which rules are added to the list matters. If a rule // applies to the instruction, the rest of the rules will not be attempted. // Take that into consideration. - rules_[SpvOpBitcast].push_back(BitCastScalarOrVector()); + rules_[spv::Op::OpBitcast].push_back(BitCastScalarOrVector()); - rules_[SpvOpCompositeConstruct].push_back(CompositeExtractFeedingConstruct); + rules_[spv::Op::OpCompositeConstruct].push_back( + CompositeExtractFeedingConstruct); - rules_[SpvOpCompositeExtract].push_back(InsertFeedingExtract()); - rules_[SpvOpCompositeExtract].push_back(CompositeConstructFeedingExtract); - rules_[SpvOpCompositeExtract].push_back(VectorShuffleFeedingExtract()); - rules_[SpvOpCompositeExtract].push_back(FMixFeedingExtract()); + rules_[spv::Op::OpCompositeExtract].push_back(InsertFeedingExtract()); + rules_[spv::Op::OpCompositeExtract].push_back( + CompositeConstructFeedingExtract); + rules_[spv::Op::OpCompositeExtract].push_back(VectorShuffleFeedingExtract()); + rules_[spv::Op::OpCompositeExtract].push_back(FMixFeedingExtract()); - rules_[SpvOpCompositeInsert].push_back(CompositeInsertToCompositeConstruct); + rules_[spv::Op::OpCompositeInsert].push_back( + CompositeInsertToCompositeConstruct); - rules_[SpvOpDot].push_back(DotProductDoingExtract()); + rules_[spv::Op::OpDot].push_back(DotProductDoingExtract()); - rules_[SpvOpEntryPoint].push_back(RemoveRedundantOperands()); + rules_[spv::Op::OpEntryPoint].push_back(RemoveRedundantOperands()); - rules_[SpvOpFAdd].push_back(RedundantFAdd()); - rules_[SpvOpFAdd].push_back(MergeAddNegateArithmetic()); - rules_[SpvOpFAdd].push_back(MergeAddAddArithmetic()); - rules_[SpvOpFAdd].push_back(MergeAddSubArithmetic()); - rules_[SpvOpFAdd].push_back(MergeGenericAddSubArithmetic()); - rules_[SpvOpFAdd].push_back(FactorAddMuls()); - rules_[SpvOpFAdd].push_back(MergeMulAddArithmetic); + rules_[spv::Op::OpFAdd].push_back(RedundantFAdd()); + rules_[spv::Op::OpFAdd].push_back(MergeAddNegateArithmetic()); + rules_[spv::Op::OpFAdd].push_back(MergeAddAddArithmetic()); + rules_[spv::Op::OpFAdd].push_back(MergeAddSubArithmetic()); + rules_[spv::Op::OpFAdd].push_back(MergeGenericAddSubArithmetic()); + rules_[spv::Op::OpFAdd].push_back(FactorAddMuls()); + rules_[spv::Op::OpFAdd].push_back(MergeMulAddArithmetic); - rules_[SpvOpFDiv].push_back(RedundantFDiv()); - rules_[SpvOpFDiv].push_back(ReciprocalFDiv()); - rules_[SpvOpFDiv].push_back(MergeDivDivArithmetic()); - rules_[SpvOpFDiv].push_back(MergeDivMulArithmetic()); - rules_[SpvOpFDiv].push_back(MergeDivNegateArithmetic()); + rules_[spv::Op::OpFDiv].push_back(RedundantFDiv()); + rules_[spv::Op::OpFDiv].push_back(ReciprocalFDiv()); + rules_[spv::Op::OpFDiv].push_back(MergeDivDivArithmetic()); + rules_[spv::Op::OpFDiv].push_back(MergeDivMulArithmetic()); + rules_[spv::Op::OpFDiv].push_back(MergeDivNegateArithmetic()); - rules_[SpvOpFMul].push_back(RedundantFMul()); - rules_[SpvOpFMul].push_back(MergeMulMulArithmetic()); - rules_[SpvOpFMul].push_back(MergeMulDivArithmetic()); - rules_[SpvOpFMul].push_back(MergeMulNegateArithmetic()); + rules_[spv::Op::OpFMul].push_back(RedundantFMul()); + rules_[spv::Op::OpFMul].push_back(MergeMulMulArithmetic()); + rules_[spv::Op::OpFMul].push_back(MergeMulDivArithmetic()); + rules_[spv::Op::OpFMul].push_back(MergeMulNegateArithmetic()); - rules_[SpvOpFNegate].push_back(MergeNegateArithmetic()); - rules_[SpvOpFNegate].push_back(MergeNegateAddSubArithmetic()); - rules_[SpvOpFNegate].push_back(MergeNegateMulDivArithmetic()); + rules_[spv::Op::OpFNegate].push_back(MergeNegateArithmetic()); + rules_[spv::Op::OpFNegate].push_back(MergeNegateAddSubArithmetic()); + rules_[spv::Op::OpFNegate].push_back(MergeNegateMulDivArithmetic()); - rules_[SpvOpFSub].push_back(RedundantFSub()); - rules_[SpvOpFSub].push_back(MergeSubNegateArithmetic()); - rules_[SpvOpFSub].push_back(MergeSubAddArithmetic()); - rules_[SpvOpFSub].push_back(MergeSubSubArithmetic()); - rules_[SpvOpFSub].push_back(MergeMulSubArithmetic); + rules_[spv::Op::OpFSub].push_back(RedundantFSub()); + rules_[spv::Op::OpFSub].push_back(MergeSubNegateArithmetic()); + rules_[spv::Op::OpFSub].push_back(MergeSubAddArithmetic()); + rules_[spv::Op::OpFSub].push_back(MergeSubSubArithmetic()); + rules_[spv::Op::OpFSub].push_back(MergeMulSubArithmetic); - rules_[SpvOpIAdd].push_back(RedundantIAdd()); - rules_[SpvOpIAdd].push_back(MergeAddNegateArithmetic()); - rules_[SpvOpIAdd].push_back(MergeAddAddArithmetic()); - rules_[SpvOpIAdd].push_back(MergeAddSubArithmetic()); - rules_[SpvOpIAdd].push_back(MergeGenericAddSubArithmetic()); - rules_[SpvOpIAdd].push_back(FactorAddMuls()); + rules_[spv::Op::OpIAdd].push_back(RedundantIAdd()); + rules_[spv::Op::OpIAdd].push_back(MergeAddNegateArithmetic()); + rules_[spv::Op::OpIAdd].push_back(MergeAddAddArithmetic()); + rules_[spv::Op::OpIAdd].push_back(MergeAddSubArithmetic()); + rules_[spv::Op::OpIAdd].push_back(MergeGenericAddSubArithmetic()); + rules_[spv::Op::OpIAdd].push_back(FactorAddMuls()); - rules_[SpvOpIMul].push_back(IntMultipleBy1()); - rules_[SpvOpIMul].push_back(MergeMulMulArithmetic()); - rules_[SpvOpIMul].push_back(MergeMulNegateArithmetic()); + rules_[spv::Op::OpIMul].push_back(IntMultipleBy1()); + rules_[spv::Op::OpIMul].push_back(MergeMulMulArithmetic()); + rules_[spv::Op::OpIMul].push_back(MergeMulNegateArithmetic()); - rules_[SpvOpISub].push_back(MergeSubNegateArithmetic()); - rules_[SpvOpISub].push_back(MergeSubAddArithmetic()); - rules_[SpvOpISub].push_back(MergeSubSubArithmetic()); + rules_[spv::Op::OpISub].push_back(MergeSubNegateArithmetic()); + rules_[spv::Op::OpISub].push_back(MergeSubAddArithmetic()); + rules_[spv::Op::OpISub].push_back(MergeSubSubArithmetic()); - rules_[SpvOpPhi].push_back(RedundantPhi()); + rules_[spv::Op::OpPhi].push_back(RedundantPhi()); - rules_[SpvOpSNegate].push_back(MergeNegateArithmetic()); - rules_[SpvOpSNegate].push_back(MergeNegateMulDivArithmetic()); - rules_[SpvOpSNegate].push_back(MergeNegateAddSubArithmetic()); + rules_[spv::Op::OpSNegate].push_back(MergeNegateArithmetic()); + rules_[spv::Op::OpSNegate].push_back(MergeNegateMulDivArithmetic()); + rules_[spv::Op::OpSNegate].push_back(MergeNegateAddSubArithmetic()); - rules_[SpvOpSelect].push_back(RedundantSelect()); + rules_[spv::Op::OpSelect].push_back(RedundantSelect()); - rules_[SpvOpStore].push_back(StoringUndef()); + rules_[spv::Op::OpStore].push_back(StoringUndef()); - rules_[SpvOpVectorShuffle].push_back(VectorShuffleFeedingShuffle()); + rules_[spv::Op::OpVectorShuffle].push_back(VectorShuffleFeedingShuffle()); - rules_[SpvOpImageSampleImplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleExplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleDrefImplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleDrefExplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleProjImplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleProjExplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleProjDrefImplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSampleProjDrefExplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageFetch].push_back(UpdateImageOperands()); - rules_[SpvOpImageGather].push_back(UpdateImageOperands()); - rules_[SpvOpImageDrefGather].push_back(UpdateImageOperands()); - rules_[SpvOpImageRead].push_back(UpdateImageOperands()); - rules_[SpvOpImageWrite].push_back(UpdateImageOperands()); - rules_[SpvOpImageSparseSampleImplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSparseSampleExplicitLod].push_back(UpdateImageOperands()); - rules_[SpvOpImageSparseSampleDrefImplicitLod].push_back( + rules_[spv::Op::OpImageSampleImplicitLod].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSampleExplicitLod].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSampleDrefImplicitLod].push_back( UpdateImageOperands()); - rules_[SpvOpImageSparseSampleDrefExplicitLod].push_back( + rules_[spv::Op::OpImageSampleDrefExplicitLod].push_back( UpdateImageOperands()); - rules_[SpvOpImageSparseSampleProjImplicitLod].push_back( + rules_[spv::Op::OpImageSampleProjImplicitLod].push_back( UpdateImageOperands()); - rules_[SpvOpImageSparseSampleProjExplicitLod].push_back( + rules_[spv::Op::OpImageSampleProjExplicitLod].push_back( UpdateImageOperands()); - rules_[SpvOpImageSparseSampleProjDrefImplicitLod].push_back( + rules_[spv::Op::OpImageSampleProjDrefImplicitLod].push_back( UpdateImageOperands()); - rules_[SpvOpImageSparseSampleProjDrefExplicitLod].push_back( + rules_[spv::Op::OpImageSampleProjDrefExplicitLod].push_back( UpdateImageOperands()); - rules_[SpvOpImageSparseFetch].push_back(UpdateImageOperands()); - rules_[SpvOpImageSparseGather].push_back(UpdateImageOperands()); - rules_[SpvOpImageSparseDrefGather].push_back(UpdateImageOperands()); - rules_[SpvOpImageSparseRead].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageFetch].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageDrefGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageRead].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageWrite].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleDrefImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleDrefExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjDrefImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjDrefExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseFetch].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseDrefGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseRead].push_back(UpdateImageOperands()); FeatureManager* feature_manager = context_->get_feature_mgr(); // Add rules for GLSLstd450 diff --git a/3rdparty/spirv-tools/source/opt/folding_rules.h b/3rdparty/spirv-tools/source/opt/folding_rules.h index f1a86395c..b51e0ce4a 100644 --- a/3rdparty/spirv-tools/source/opt/folding_rules.h +++ b/3rdparty/spirv-tools/source/opt/folding_rules.h @@ -64,7 +64,7 @@ class FoldingRules { virtual ~FoldingRules() = default; const FoldingRuleSet& GetRulesForInstruction(Instruction* inst) const { - if (inst->opcode() != SpvOpExtInst) { + if (inst->opcode() != spv::Op::OpExtInst) { auto it = rules_.find(inst->opcode()); if (it != rules_.end()) { return it->second; @@ -86,8 +86,14 @@ class FoldingRules { virtual void AddFoldingRules(); protected: + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + // The folding rules for core instructions. - std::unordered_map rules_; + std::unordered_map rules_; // The folding rules for extended instructions. struct Key { diff --git a/3rdparty/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp b/3rdparty/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp index 10e98fd8b..3f89e56c0 100644 --- a/3rdparty/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp @@ -23,21 +23,21 @@ Pass::Status FreezeSpecConstantValuePass::Process() { auto ctx = context(); ctx->module()->ForEachInst([&modified, ctx](Instruction* inst) { switch (inst->opcode()) { - case SpvOp::SpvOpSpecConstant: - inst->SetOpcode(SpvOp::SpvOpConstant); + case spv::Op::OpSpecConstant: + inst->SetOpcode(spv::Op::OpConstant); modified = true; break; - case SpvOp::SpvOpSpecConstantTrue: - inst->SetOpcode(SpvOp::SpvOpConstantTrue); + case spv::Op::OpSpecConstantTrue: + inst->SetOpcode(spv::Op::OpConstantTrue); modified = true; break; - case SpvOp::SpvOpSpecConstantFalse: - inst->SetOpcode(SpvOp::SpvOpConstantFalse); + case spv::Op::OpSpecConstantFalse: + inst->SetOpcode(spv::Op::OpConstantFalse); modified = true; break; - case SpvOp::SpvOpDecorate: - if (inst->GetSingleWordInOperand(1) == - SpvDecoration::SpvDecorationSpecId) { + case spv::Op::OpDecorate: + if (spv::Decoration(inst->GetSingleWordInOperand(1)) == + spv::Decoration::SpecId) { ctx->KillInst(inst); modified = true; } diff --git a/3rdparty/spirv-tools/source/opt/function.cpp b/3rdparty/spirv-tools/source/opt/function.cpp index bb51df3f9..6c7c949fd 100644 --- a/3rdparty/spirv-tools/source/opt/function.cpp +++ b/3rdparty/spirv-tools/source/opt/function.cpp @@ -264,7 +264,7 @@ std::string Function::PrettyPrint(uint32_t options) const { std::ostringstream str; ForEachInst([&str, options](const Instruction* inst) { str << inst->PrettyPrint(options); - if (inst->opcode() != SpvOpFunctionEnd) { + if (inst->opcode() != spv::Op::OpFunctionEnd) { str << std::endl; } }); diff --git a/3rdparty/spirv-tools/source/opt/function.h b/3rdparty/spirv-tools/source/opt/function.h index 146cbe340..8c0472cd2 100644 --- a/3rdparty/spirv-tools/source/opt/function.h +++ b/3rdparty/spirv-tools/source/opt/function.h @@ -253,7 +253,7 @@ inline void Function::RemoveEmptyBlocks() { auto first_empty = std::remove_if(std::begin(blocks_), std::end(blocks_), [](const std::unique_ptr& bb) -> bool { - return bb->GetLabelInst()->opcode() == SpvOpNop; + return bb->GetLabelInst()->opcode() == spv::Op::OpNop; }); blocks_.erase(first_empty, std::end(blocks_)); } diff --git a/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.cpp b/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.cpp index 4652d72d5..da2764fc8 100644 --- a/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.cpp @@ -158,7 +158,6 @@ #include "source/util/make_unique.h" #include "spirv-tools/libspirv.h" #include "spirv/unified1/GLSL.std.450.h" -#include "spirv/unified1/spirv.h" #include "type_manager.h" #include "types.h" @@ -194,14 +193,15 @@ spvtools::DiagnosticStream GraphicsRobustAccessPass::Fail() { spv_result_t GraphicsRobustAccessPass::IsCompatibleModule() { auto* feature_mgr = context()->get_feature_mgr(); - if (!feature_mgr->HasCapability(SpvCapabilityShader)) + if (!feature_mgr->HasCapability(spv::Capability::Shader)) return Fail() << "Can only process Shader modules"; - if (feature_mgr->HasCapability(SpvCapabilityVariablePointers)) + if (feature_mgr->HasCapability(spv::Capability::VariablePointers)) return Fail() << "Can't process modules with VariablePointers capability"; - if (feature_mgr->HasCapability(SpvCapabilityVariablePointersStorageBuffer)) + if (feature_mgr->HasCapability( + spv::Capability::VariablePointersStorageBuffer)) return Fail() << "Can't process modules with VariablePointersStorageBuffer " "capability"; - if (feature_mgr->HasCapability(SpvCapabilityRuntimeDescriptorArrayEXT)) { + if (feature_mgr->HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) { // These have a RuntimeArray outside of Block-decorated struct. There // is no way to compute the array length from within SPIR-V. return Fail() << "Can't process modules with RuntimeDescriptorArrayEXT " @@ -210,8 +210,9 @@ spv_result_t GraphicsRobustAccessPass::IsCompatibleModule() { { auto* inst = context()->module()->GetMemoryModel(); - const auto addressing_model = inst->GetSingleWordOperand(0); - if (addressing_model != SpvAddressingModelLogical) + const auto addressing_model = + spv::AddressingModel(inst->GetSingleWordOperand(0)); + if (addressing_model != spv::AddressingModel::Logical) return Fail() << "Addressing model must be Logical. Found " << inst->PrettyPrint(); } @@ -237,11 +238,11 @@ bool GraphicsRobustAccessPass::ProcessAFunction(opt::Function* function) { for (auto& block : *function) { for (auto& inst : block) { switch (inst.opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: access_chains.push_back(&inst); break; - case SpvOpImageTexelPointer: + case spv::Op::OpImageTexelPointer: image_texel_pointers.push_back(&inst); break; default: @@ -268,7 +269,7 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( auto* def_use_mgr = context()->get_def_use_mgr(); auto* type_mgr = context()->get_type_mgr(); const bool have_int64_cap = - context()->get_feature_mgr()->HasCapability(SpvCapabilityInt64); + context()->get_feature_mgr()->HasCapability(spv::Capability::Int64); // Replaces one of the OpAccessChain index operands with a new value. // Updates def-use analysis. @@ -451,7 +452,7 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( // It doesn't matter if 1 is signed or unsigned. auto* one = GetValueForType(1, wider_type); auto* count_minus_1 = InsertInst( - &inst, SpvOpISub, type_mgr->GetId(wider_type), TakeNextId(), + &inst, spv::Op::OpISub, type_mgr->GetId(wider_type), TakeNextId(), {{SPV_OPERAND_TYPE_ID, {count_inst->result_id()}}, {SPV_OPERAND_TYPE_ID, {one->result_id()}}}); auto* zero = GetValueForType(0, wider_type); @@ -486,15 +487,15 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( Instruction* index_inst = GetDef(index_id); switch (pointee_type->opcode()) { - case SpvOpTypeMatrix: // Use column count - case SpvOpTypeVector: // Use component count + case spv::Op::OpTypeMatrix: // Use column count + case spv::Op::OpTypeVector: // Use component count { const uint32_t count = pointee_type->GetSingleWordOperand(2); clamp_to_literal_count(idx, count); pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); } break; - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { // The array length can be a spec constant, so go through the general // case. Instruction* array_len = GetDef(pointee_type->GetSingleWordOperand(2)); @@ -502,11 +503,11 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); } break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { // SPIR-V requires the index to be an OpConstant. // We need to know the index literal value so we can compute the next // pointee type. - if (index_inst->opcode() != SpvOpConstant || + if (index_inst->opcode() != spv::Op::OpConstant || !constant_mgr->GetConstantFromInst(index_inst) ->type() ->AsInteger()) { @@ -537,7 +538,7 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( // No need to clamp this index. We just checked that it's valid. } break; - case SpvOpTypeRuntimeArray: { + case spv::Op::OpTypeRuntimeArray: { auto* array_len = MakeRuntimeArrayLengthInst(&inst, idx); if (!array_len) { // We've already signaled an error. return; @@ -571,7 +572,7 @@ uint32_t GraphicsRobustAccessPass::GetGlslInsts() { module_status_.glsl_insts_id = TakeNextId(); std::vector words = spvtools::utils::MakeVector(glsl); auto import_inst = MakeUnique( - context(), SpvOpExtInstImport, 0, module_status_.glsl_insts_id, + context(), spv::Op::OpExtInstImport, 0, module_status_.glsl_insts_id, std::initializer_list{ Operand{SPV_OPERAND_TYPE_LITERAL_STRING, std::move(words)}}); Instruction* inst = import_inst.get(); @@ -609,8 +610,8 @@ opt::Instruction* opt::GraphicsRobustAccessPass::WidenInteger( auto type_id = context()->get_type_mgr()->GetId(unsigned_type); auto conversion_id = TakeNextId(); auto* conversion = InsertInst( - before_inst, (sign_extend ? SpvOpSConvert : SpvOpUConvert), type_id, - conversion_id, {{SPV_OPERAND_TYPE_ID, {value->result_id()}}}); + before_inst, (sign_extend ? spv::Op::OpSConvert : spv::Op::OpUConvert), + type_id, conversion_id, {{SPV_OPERAND_TYPE_ID, {value->result_id()}}}); return conversion; } @@ -628,7 +629,7 @@ Instruction* GraphicsRobustAccessPass::MakeUMinInst( (void)xwidth; (void)ywidth; auto* smin_inst = InsertInst( - where, SpvOpExtInst, x->type_id(), smin_id, + where, spv::Op::OpExtInst, x->type_id(), smin_id, { {SPV_OPERAND_TYPE_ID, {glsl_insts_id}}, {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {GLSLstd450UMin}}, @@ -655,7 +656,7 @@ Instruction* GraphicsRobustAccessPass::MakeSClampInst( (void)minwidth; (void)maxwidth; auto* clamp_inst = InsertInst( - where, SpvOpExtInst, x->type_id(), clamp_id, + where, spv::Op::OpExtInst, x->type_id(), clamp_id, { {SPV_OPERAND_TYPE_ID, {glsl_insts_id}}, {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {GLSLstd450SClamp}}, @@ -689,13 +690,13 @@ Instruction* GraphicsRobustAccessPass::MakeRuntimeArrayLengthInst( Instruction* pointer_to_containing_struct = nullptr; while (steps_remaining > 0) { switch (current_access_chain->opcode()) { - case SpvOpCopyObject: + case spv::Op::OpCopyObject: // Whoops. Walk right through this one. current_access_chain = GetDef(current_access_chain->GetSingleWordInOperand(0)); break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: { const int first_index_operand = 3; // How many indices in this access chain contribute to getting us // to an element in the runtime array? @@ -793,7 +794,8 @@ Instruction* GraphicsRobustAccessPass::MakeRuntimeArrayLengthInst( analysis::Integer uint_type_for_query(32, false); auto* uint_type = type_mgr->GetRegisteredType(&uint_type_for_query); auto* array_len = InsertInst( - access_chain, SpvOpArrayLength, type_mgr->GetId(uint_type), array_len_id, + access_chain, spv::Op::OpArrayLength, type_mgr->GetId(uint_type), + array_len_id, {{SPV_OPERAND_TYPE_ID, {pointer_to_containing_struct->result_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index_of_runtime_array}}}); return array_len; @@ -839,11 +841,11 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( // Declare the ImageQuery capability if the module doesn't already have it. auto* feature_mgr = context()->get_feature_mgr(); - if (!feature_mgr->HasCapability(SpvCapabilityImageQuery)) { + if (!feature_mgr->HasCapability(spv::Capability::ImageQuery)) { auto cap = MakeUnique( - context(), SpvOpCapability, 0, 0, + context(), spv::Op::OpCapability, 0, 0, std::initializer_list{ - {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityImageQuery}}}); + {SPV_OPERAND_TYPE_CAPABILITY, {spv::Capability::ImageQuery}}}); def_use_mgr->AnalyzeInstDefUse(cap.get()); context()->AddCapability(std::move(cap)); feature_mgr->Analyze(context()->module()); @@ -890,21 +892,21 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( const int arrayness_bonus = arrayed ? 1 : 0; int num_coords = 0; switch (dim) { - case SpvDimBuffer: + case spv::Dim::Buffer: case SpvDim1D: num_coords = 1; break; - case SpvDimCube: + case spv::Dim::Cube: // For cube, we need bounds for x, y, but not face. - case SpvDimRect: + case spv::Dim::Rect: case SpvDim2D: num_coords = 2; break; case SpvDim3D: num_coords = 3; break; - case SpvDimSubpassData: - case SpvDimMax: + case spv::Dim::SubpassData: + case spv::Dim::Max: return Fail() << "Invalid image dimension for OpImageTexelPointer: " << int(dim); break; @@ -941,12 +943,12 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( const uint32_t image_id = TakeNextId(); auto* image = - InsertInst(image_texel_pointer, SpvOpLoad, image_type_id, image_id, + InsertInst(image_texel_pointer, spv::Op::OpLoad, image_type_id, image_id, {{SPV_OPERAND_TYPE_ID, {image_ptr->result_id()}}}); const uint32_t query_size_id = TakeNextId(); auto* query_size = - InsertInst(image_texel_pointer, SpvOpImageQuerySize, + InsertInst(image_texel_pointer, spv::Op::OpImageQuerySize, type_mgr->GetTypeInstruction(query_size_type), query_size_id, {{SPV_OPERAND_TYPE_ID, {image->result_id()}}}); @@ -962,7 +964,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( // in the face index ranging from 0 through 5. The inclusive upper bound // on the third coordinate therefore is multiplied by 6. auto* query_size_including_faces = query_size; - if (arrayed && (dim == SpvDimCube)) { + if (arrayed && (dim == spv::Dim::Cube)) { // Multiply the last coordinate by 6. auto* component_6 = constant_mgr->GetConstant(coord_component_type, {6}); const uint32_t component_6_id = @@ -974,7 +976,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( constant_mgr->GetDefiningInstruction(multiplicand); const auto query_size_including_faces_id = TakeNextId(); query_size_including_faces = InsertInst( - image_texel_pointer, SpvOpIMul, + image_texel_pointer, spv::Op::OpIMul, type_mgr->GetTypeInstruction(query_size_type), query_size_including_faces_id, {{SPV_OPERAND_TYPE_ID, {query_size_including_faces->result_id()}}, @@ -998,7 +1000,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( const uint32_t query_max_including_faces_id = TakeNextId(); auto* query_max_including_faces = InsertInst( - image_texel_pointer, SpvOpISub, + image_texel_pointer, spv::Op::OpISub, type_mgr->GetTypeInstruction(query_size_type), query_max_including_faces_id, {{SPV_OPERAND_TYPE_ID, {query_size_including_faces->result_id()}}, @@ -1016,12 +1018,12 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( // Get the sample count via OpImageQuerySamples const auto query_samples_id = TakeNextId(); auto* query_samples = InsertInst( - image_texel_pointer, SpvOpImageQuerySamples, + image_texel_pointer, spv::Op::OpImageQuerySamples, constant_mgr->GetDefiningInstruction(component_0)->type_id(), query_samples_id, {{SPV_OPERAND_TYPE_ID, {image->result_id()}}}); const auto max_samples_id = TakeNextId(); - auto* max_samples = InsertInst(image_texel_pointer, SpvOpImageQuerySamples, + auto* max_samples = InsertInst(image_texel_pointer, spv::Op::OpImageQuerySamples, query_samples->type_id(), max_samples_id, {{SPV_OPERAND_TYPE_ID, {query_samples_id}}, {SPV_OPERAND_TYPE_ID, {component_1_id}}}); @@ -1043,7 +1045,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( } opt::Instruction* GraphicsRobustAccessPass::InsertInst( - opt::Instruction* where_inst, SpvOp opcode, uint32_t type_id, + opt::Instruction* where_inst, spv::Op opcode, uint32_t type_id, uint32_t result_id, const Instruction::OperandList& operands) { module_status_.modified = true; auto* result = where_inst->InsertBefore( diff --git a/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.h b/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.h index 8f4c9dc7d..a7ffe115b 100644 --- a/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.h +++ b/3rdparty/spirv-tools/source/opt/graphics_robust_access_pass.h @@ -133,7 +133,7 @@ class GraphicsRobustAccessPass : public Pass { // Returns a new instruction inserted before |where_inst|, and created from // the remaining arguments. Registers the definitions and uses of the new // instruction and also records its block. - opt::Instruction* InsertInst(opt::Instruction* where_inst, SpvOp opcode, + opt::Instruction* InsertInst(opt::Instruction* where_inst, spv::Op opcode, uint32_t type_id, uint32_t result_id, const Instruction::OperandList& operands); diff --git a/3rdparty/spirv-tools/source/opt/if_conversion.cpp b/3rdparty/spirv-tools/source/opt/if_conversion.cpp index 1232796e5..5912cf12d 100644 --- a/3rdparty/spirv-tools/source/opt/if_conversion.cpp +++ b/3rdparty/spirv-tools/source/opt/if_conversion.cpp @@ -23,7 +23,7 @@ namespace spvtools { namespace opt { Pass::Status IfConversion::Process() { - if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { return Status::SuccessWithoutChange; } @@ -40,7 +40,7 @@ Pass::Status IfConversion::Process() { // Get an insertion point. auto iter = block.begin(); - while (iter != block.end() && iter->opcode() == SpvOpPhi) { + while (iter != block.end() && iter->opcode() == spv::Op::OpPhi) { ++iter; } @@ -171,23 +171,26 @@ bool IfConversion::CheckBlock(BasicBlock* block, DominatorAnalysis* dominators, *common = dominators->CommonDominator(inc0, inc1); if (!*common || cfg()->IsPseudoEntryBlock(*common)) return false; Instruction* branch = (*common)->terminator(); - if (branch->opcode() != SpvOpBranchConditional) return false; + if (branch->opcode() != spv::Op::OpBranchConditional) return false; auto merge = (*common)->GetMergeInst(); - if (!merge || merge->opcode() != SpvOpSelectionMerge) return false; - if (merge->GetSingleWordInOperand(1) == SpvSelectionControlDontFlattenMask) + if (!merge || merge->opcode() != spv::Op::OpSelectionMerge) return false; + if (spv::SelectionControlMask(merge->GetSingleWordInOperand(1)) == + spv::SelectionControlMask::DontFlatten) { return false; + } if ((*common)->MergeBlockIdIfAny() != block->id()) return false; return true; } bool IfConversion::CheckPhiUsers(Instruction* phi, BasicBlock* block) { - return get_def_use_mgr()->WhileEachUser(phi, [block, - this](Instruction* user) { - if (user->opcode() == SpvOpPhi && context()->get_instr_block(user) == block) - return false; - return true; - }); + return get_def_use_mgr()->WhileEachUser( + phi, [block, this](Instruction* user) { + if (user->opcode() == spv::Op::OpPhi && + context()->get_instr_block(user) == block) + return false; + return true; + }); } uint32_t IfConversion::SplatCondition(analysis::Vector* vec_data_ty, @@ -207,9 +210,9 @@ uint32_t IfConversion::SplatCondition(analysis::Vector* vec_data_ty, bool IfConversion::CheckType(uint32_t id) { Instruction* type = get_def_use_mgr()->GetDef(id); - SpvOp op = type->opcode(); - if (spvOpcodeIsScalarType(op) || op == SpvOpTypePointer || - op == SpvOpTypeVector) + spv::Op op = type->opcode(); + if (spvOpcodeIsScalarType(op) || op == spv::Op::OpTypePointer || + op == spv::Op::OpTypeVector) return true; return false; } @@ -255,7 +258,7 @@ void IfConversion::HoistInstruction(Instruction* inst, BasicBlock* target_block, }); Instruction* insertion_pos = target_block->terminator(); - if ((insertion_pos)->PreviousNode()->opcode() == SpvOpSelectionMerge) { + if ((insertion_pos)->PreviousNode()->opcode() == spv::Op::OpSelectionMerge) { insertion_pos = insertion_pos->PreviousNode(); } inst->RemoveFromList(); diff --git a/3rdparty/spirv-tools/source/opt/inline_opaque_pass.cpp b/3rdparty/spirv-tools/source/opt/inline_opaque_pass.cpp index fe9c67993..90a4c2247 100644 --- a/3rdparty/spirv-tools/source/opt/inline_opaque_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/inline_opaque_pass.cpp @@ -21,26 +21,24 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kTypePointerTypeIdInIdx = 1; - -} // anonymous namespace +constexpr uint32_t kTypePointerTypeIdInIdx = 1; +} // namespace bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) { const Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); switch (typeInst->opcode()) { - case SpvOpTypeSampler: - case SpvOpTypeImage: - case SpvOpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampledImage: return true; - case SpvOpTypePointer: + case spv::Op::OpTypePointer: return IsOpaqueType( typeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx)); default: break; } // TODO(greg-lunarg): Handle arrays containing opaque type - if (typeInst->opcode() != SpvOpTypeStruct) return false; + if (typeInst->opcode() != spv::Op::OpTypeStruct) return false; // Return true if any member is opaque return !typeInst->WhileEachInId([this](const uint32_t* tid) { if (IsOpaqueType(*tid)) return false; diff --git a/3rdparty/spirv-tools/source/opt/inline_pass.cpp b/3rdparty/spirv-tools/source/opt/inline_pass.cpp index e14516f75..3f160b24c 100644 --- a/3rdparty/spirv-tools/source/opt/inline_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/inline_pass.cpp @@ -23,24 +23,24 @@ #include "source/opt/reflect.h" #include "source/util/make_unique.h" -// Indices of operands in SPIR-V instructions - -static const int kSpvFunctionCallFunctionId = 2; -static const int kSpvFunctionCallArgumentId = 3; -static const int kSpvReturnValueId = 0; - namespace spvtools { namespace opt { +namespace { +// Indices of operands in SPIR-V instructions +constexpr int kSpvFunctionCallFunctionId = 2; +constexpr int kSpvFunctionCallArgumentId = 3; +constexpr int kSpvReturnValueId = 0; +} // namespace uint32_t InlinePass::AddPointerToType(uint32_t type_id, - SpvStorageClass storage_class) { + spv::StorageClass storage_class) { uint32_t resultId = context()->TakeNextId(); if (resultId == 0) { return resultId; } std::unique_ptr type_inst( - new Instruction(context(), SpvOpTypePointer, 0, resultId, + new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, {uint32_t(storage_class)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_id}}})); @@ -48,8 +48,8 @@ uint32_t InlinePass::AddPointerToType(uint32_t type_id, analysis::Type* pointeeTy; std::unique_ptr pointerTy; std::tie(pointeeTy, pointerTy) = - context()->get_type_mgr()->GetTypeAndPointerType(type_id, - SpvStorageClassFunction); + context()->get_type_mgr()->GetTypeAndPointerType( + type_id, spv::StorageClass::Function); context()->get_type_mgr()->RegisterType(resultId, *pointerTy); return resultId; } @@ -57,7 +57,7 @@ uint32_t InlinePass::AddPointerToType(uint32_t type_id, void InlinePass::AddBranch(uint32_t label_id, std::unique_ptr* block_ptr) { std::unique_ptr newBranch( - new Instruction(context(), SpvOpBranch, 0, 0, + new Instruction(context(), spv::Op::OpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); (*block_ptr)->AddInstruction(std::move(newBranch)); } @@ -66,7 +66,7 @@ void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id, uint32_t false_id, std::unique_ptr* block_ptr) { std::unique_ptr newBranch( - new Instruction(context(), SpvOpBranchConditional, 0, 0, + new Instruction(context(), spv::Op::OpBranchConditional, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); @@ -76,7 +76,7 @@ void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id, void InlinePass::AddLoopMerge(uint32_t merge_id, uint32_t continue_id, std::unique_ptr* block_ptr) { std::unique_ptr newLoopMerge(new Instruction( - context(), SpvOpLoopMerge, 0, 0, + context(), spv::Op::OpLoopMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LOOP_CONTROL, {0}}})); @@ -88,7 +88,7 @@ void InlinePass::AddStore(uint32_t ptr_id, uint32_t val_id, const Instruction* line_inst, const DebugScope& dbg_scope) { std::unique_ptr newStore( - new Instruction(context(), SpvOpStore, 0, 0, + new Instruction(context(), spv::Op::OpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}})); if (line_inst != nullptr) { @@ -103,7 +103,7 @@ void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id, const Instruction* line_inst, const DebugScope& dbg_scope) { std::unique_ptr newLoad( - new Instruction(context(), SpvOpLoad, type_id, resultId, + new Instruction(context(), spv::Op::OpLoad, type_id, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}})); if (line_inst != nullptr) { newLoad->AddDebugLine(line_inst); @@ -114,27 +114,27 @@ void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id, std::unique_ptr InlinePass::NewLabel(uint32_t label_id) { std::unique_ptr newLabel( - new Instruction(context(), SpvOpLabel, 0, label_id, {})); + new Instruction(context(), spv::Op::OpLabel, 0, label_id, {})); return newLabel; } uint32_t InlinePass::GetFalseId() { if (false_id_ != 0) return false_id_; - false_id_ = get_module()->GetGlobalValue(SpvOpConstantFalse); + false_id_ = get_module()->GetGlobalValue(spv::Op::OpConstantFalse); if (false_id_ != 0) return false_id_; - uint32_t boolId = get_module()->GetGlobalValue(SpvOpTypeBool); + uint32_t boolId = get_module()->GetGlobalValue(spv::Op::OpTypeBool); if (boolId == 0) { boolId = context()->TakeNextId(); if (boolId == 0) { return 0; } - get_module()->AddGlobalValue(SpvOpTypeBool, boolId, 0); + get_module()->AddGlobalValue(spv::Op::OpTypeBool, boolId, 0); } false_id_ = context()->TakeNextId(); if (false_id_ == 0) { return 0; } - get_module()->AddGlobalValue(SpvOpConstantFalse, false_id_, boolId); + get_module()->AddGlobalValue(spv::Op::OpConstantFalse, false_id_, boolId); return false_id_; } @@ -157,10 +157,10 @@ bool InlinePass::CloneAndMapLocals( analysis::DebugInlinedAtContext* inlined_at_ctx) { auto callee_block_itr = calleeFn->begin(); auto callee_var_itr = callee_block_itr->begin(); - while (callee_var_itr->opcode() == SpvOp::SpvOpVariable || + while (callee_var_itr->opcode() == spv::Op::OpVariable || callee_var_itr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { - if (callee_var_itr->opcode() != SpvOp::SpvOpVariable) { + if (callee_var_itr->opcode() != spv::Op::OpVariable) { ++callee_var_itr; continue; } @@ -191,10 +191,11 @@ uint32_t InlinePass::CreateReturnVar( "Cannot create a return variable of type void."); // Find or create ptr to callee return type. uint32_t returnVarTypeId = - type_mgr->FindPointerToType(calleeTypeId, SpvStorageClassFunction); + type_mgr->FindPointerToType(calleeTypeId, spv::StorageClass::Function); if (returnVarTypeId == 0) { - returnVarTypeId = AddPointerToType(calleeTypeId, SpvStorageClassFunction); + returnVarTypeId = + AddPointerToType(calleeTypeId, spv::StorageClass::Function); if (returnVarTypeId == 0) { return 0; } @@ -206,17 +207,18 @@ uint32_t InlinePass::CreateReturnVar( return 0; } - std::unique_ptr var_inst( - new Instruction(context(), SpvOpVariable, returnVarTypeId, returnVarId, - {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, - {SpvStorageClassFunction}}})); + std::unique_ptr var_inst(new Instruction( + context(), spv::Op::OpVariable, returnVarTypeId, returnVarId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, + {(uint32_t)spv::StorageClass::Function}}})); new_vars->push_back(std::move(var_inst)); get_decoration_mgr()->CloneDecorations(calleeFn->result_id(), returnVarId); return returnVarId; } bool InlinePass::IsSameBlockOp(const Instruction* inst) const { - return inst->opcode() == SpvOpSampledImage || inst->opcode() == SpvOpImage; + return inst->opcode() == spv::Op::OpSampledImage || + inst->opcode() == spv::Op::OpImage; } bool InlinePass::CloneSameBlockOps( @@ -299,9 +301,9 @@ InstructionList::iterator InlinePass::AddStoresForVariableInitializers( std::unique_ptr* new_blk_ptr, UptrVectorIterator callee_first_block_itr) { auto callee_itr = callee_first_block_itr->begin(); - while (callee_itr->opcode() == SpvOp::SpvOpVariable || + while (callee_itr->opcode() == spv::Op::OpVariable || callee_itr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { - if (callee_itr->opcode() == SpvOp::SpvOpVariable && + if (callee_itr->opcode() == spv::Op::OpVariable && callee_itr->NumInOperands() == 2) { assert(callee2caller.count(callee_itr->result_id()) && "Expected the variable to have already been mapped."); @@ -330,7 +332,8 @@ bool InlinePass::InlineSingleInstruction( BasicBlock* new_blk_ptr, const Instruction* inst, uint32_t dbg_inlined_at) { // If we have return, it must be at the end of the callee. We will handle // it at the end. - if (inst->opcode() == SpvOpReturnValue || inst->opcode() == SpvOpReturn) + if (inst->opcode() == spv::Op::OpReturnValue || + inst->opcode() == spv::Op::OpReturn) return true; // Copy callee instruction and remap all input Ids. @@ -366,7 +369,7 @@ std::unique_ptr InlinePass::InlineReturn( analysis::DebugInlinedAtContext* inlined_at_ctx, Function* calleeFn, const Instruction* inst, uint32_t returnVarId) { // Store return value to return variable. - if (inst->opcode() == SpvOpReturnValue) { + if (inst->opcode() == spv::Op::OpReturnValue) { assert(returnVarId != 0); uint32_t valId = inst->GetInOperand(kSpvReturnValueId).words[0]; const auto mapItr = callee2caller.find(valId); @@ -388,7 +391,8 @@ std::unique_ptr InlinePass::InlineReturn( } if (returnLabelId == 0) return new_blk_ptr; - if (inst->opcode() == SpvOpReturn || inst->opcode() == SpvOpReturnValue) + if (inst->opcode() == spv::Op::OpReturn || + inst->opcode() == spv::Op::OpReturnValue) AddBranch(returnLabelId, &new_blk_ptr); new_blocks->push_back(std::move(new_blk_ptr)); return MakeUnique(NewLabel(returnLabelId)); @@ -499,7 +503,7 @@ void InlinePass::MoveLoopMergeInstToFirstBlock( // Insert a modified copy of the loop merge into the first block. auto loop_merge_itr = last->tail(); --loop_merge_itr; - assert(loop_merge_itr->opcode() == SpvOpLoopMerge); + assert(loop_merge_itr->opcode() == spv::Op::OpLoopMerge); std::unique_ptr cp_inst(loop_merge_itr->Clone(context())); first->tail().InsertBefore(std::move(cp_inst)); @@ -696,7 +700,7 @@ bool InlinePass::GenInlineCode( } bool InlinePass::IsInlinableFunctionCall(const Instruction* inst) { - if (inst->opcode() != SpvOp::SpvOpFunctionCall) return false; + if (inst->opcode() != spv::Op::OpFunctionCall) return false; const uint32_t calleeFnId = inst->GetSingleWordOperand(kSpvFunctionCallFunctionId); const auto ci = inlinable_.find(calleeFnId); @@ -738,7 +742,7 @@ void InlinePass::UpdateSucceedingPhis( bool InlinePass::HasNoReturnInLoop(Function* func) { // If control not structured, do not do loop/return analysis // TODO: Analyze returns in non-structured control flow - if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) return false; const auto structured_analysis = context()->GetStructuredCFGAnalysis(); // Search for returns in structured construct. @@ -776,7 +780,7 @@ bool InlinePass::IsInlinableFunction(Function* func) { if (func->cbegin() == func->cend()) return false; // Do not inline functions with DontInline flag. - if (func->control_mask() & SpvFunctionControlDontInlineMask) { + if (func->control_mask() & uint32_t(spv::FunctionControlMask::DontInline)) { return false; } @@ -811,7 +815,7 @@ bool InlinePass::IsInlinableFunction(Function* func) { bool InlinePass::ContainsAbortOtherThanUnreachable(Function* func) const { return !func->WhileEachInst([](Instruction* inst) { - return inst->opcode() == SpvOpUnreachable || + return inst->opcode() == spv::Op::OpUnreachable || !spvOpcodeIsAbort(inst->opcode()); }); } diff --git a/3rdparty/spirv-tools/source/opt/inline_pass.h b/3rdparty/spirv-tools/source/opt/inline_pass.h index d29c1e074..1c9d60e32 100644 --- a/3rdparty/spirv-tools/source/opt/inline_pass.h +++ b/3rdparty/spirv-tools/source/opt/inline_pass.h @@ -44,7 +44,7 @@ class InlinePass : public Pass { // Add pointer to type to module and return resultId. Returns 0 if the type // could not be created. - uint32_t AddPointerToType(uint32_t type_id, SpvStorageClass storage_class); + uint32_t AddPointerToType(uint32_t type_id, spv::StorageClass storage_class); // Add unconditional branch to labelId to end of block block_ptr. void AddBranch(uint32_t labelId, std::unique_ptr* block_ptr); diff --git a/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp b/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp index c2c5d6cb4..ca36dd606 100644 --- a/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp @@ -16,31 +16,29 @@ #include "inst_bindless_check_pass.h" -namespace { - -// Input Operand Indices -static const int kSpvImageSampleImageIdInIdx = 0; -static const int kSpvSampledImageImageIdInIdx = 0; -static const int kSpvSampledImageSamplerIdInIdx = 1; -static const int kSpvImageSampledImageIdInIdx = 0; -static const int kSpvCopyObjectOperandIdInIdx = 0; -static const int kSpvLoadPtrIdInIdx = 0; -static const int kSpvAccessChainBaseIdInIdx = 0; -static const int kSpvAccessChainIndex0IdInIdx = 1; -static const int kSpvTypeArrayTypeIdInIdx = 0; -static const int kSpvTypeArrayLengthIdInIdx = 1; -static const int kSpvConstantValueInIdx = 0; -static const int kSpvVariableStorageClassInIdx = 0; -static const int kSpvTypePtrTypeIdInIdx = 1; -static const int kSpvTypeImageDim = 1; -static const int kSpvTypeImageDepth = 2; -static const int kSpvTypeImageArrayed = 3; -static const int kSpvTypeImageMS = 4; -static const int kSpvTypeImageSampled = 5; -} // anonymous namespace - namespace spvtools { namespace opt { +namespace { +// Input Operand Indices +constexpr int kSpvImageSampleImageIdInIdx = 0; +constexpr int kSpvSampledImageImageIdInIdx = 0; +constexpr int kSpvSampledImageSamplerIdInIdx = 1; +constexpr int kSpvImageSampledImageIdInIdx = 0; +constexpr int kSpvCopyObjectOperandIdInIdx = 0; +constexpr int kSpvLoadPtrIdInIdx = 0; +constexpr int kSpvAccessChainBaseIdInIdx = 0; +constexpr int kSpvAccessChainIndex0IdInIdx = 1; +constexpr int kSpvTypeArrayTypeIdInIdx = 0; +constexpr int kSpvTypeArrayLengthIdInIdx = 1; +constexpr int kSpvConstantValueInIdx = 0; +constexpr int kSpvVariableStorageClassInIdx = 0; +constexpr int kSpvTypePtrTypeIdInIdx = 1; +constexpr int kSpvTypeImageDim = 1; +constexpr int kSpvTypeImageDepth = 2; +constexpr int kSpvTypeImageArrayed = 3; +constexpr int kSpvTypeImageMS = 4; +constexpr int kSpvTypeImageSampled = 5; +} // namespace uint32_t InstBindlessCheckPass::GenDebugReadLength( uint32_t var_id, InstructionBuilder* builder) { @@ -79,25 +77,25 @@ uint32_t InstBindlessCheckPass::CloneOriginalImage( uint32_t old_image_id, InstructionBuilder* builder) { Instruction* new_image_inst; Instruction* old_image_inst = get_def_use_mgr()->GetDef(old_image_id); - if (old_image_inst->opcode() == SpvOpLoad) { + if (old_image_inst->opcode() == spv::Op::OpLoad) { new_image_inst = builder->AddLoad( old_image_inst->type_id(), old_image_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx)); - } else if (old_image_inst->opcode() == SpvOp::SpvOpSampledImage) { + } else if (old_image_inst->opcode() == spv::Op::OpSampledImage) { uint32_t clone_id = CloneOriginalImage( old_image_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx), builder); new_image_inst = builder->AddBinaryOp( - old_image_inst->type_id(), SpvOpSampledImage, clone_id, + old_image_inst->type_id(), spv::Op::OpSampledImage, clone_id, old_image_inst->GetSingleWordInOperand(kSpvSampledImageSamplerIdInIdx)); - } else if (old_image_inst->opcode() == SpvOp::SpvOpImage) { + } else if (old_image_inst->opcode() == spv::Op::OpImage) { uint32_t clone_id = CloneOriginalImage( old_image_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx), builder); - new_image_inst = - builder->AddUnaryOp(old_image_inst->type_id(), SpvOpImage, clone_id); + new_image_inst = builder->AddUnaryOp(old_image_inst->type_id(), + spv::Op::OpImage, clone_id); } else { - assert(old_image_inst->opcode() == SpvOp::SpvOpCopyObject && + assert(old_image_inst->opcode() == spv::Op::OpCopyObject && "expecting OpCopyObject"); uint32_t clone_id = CloneOriginalImage( old_image_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx), @@ -143,38 +141,38 @@ uint32_t InstBindlessCheckPass::CloneOriginalReference( uint32_t InstBindlessCheckPass::GetImageId(Instruction* inst) { switch (inst->opcode()) { - case SpvOp::SpvOpImageSampleImplicitLod: - case SpvOp::SpvOpImageSampleExplicitLod: - case SpvOp::SpvOpImageSampleDrefImplicitLod: - case SpvOp::SpvOpImageSampleDrefExplicitLod: - case SpvOp::SpvOpImageSampleProjImplicitLod: - case SpvOp::SpvOpImageSampleProjExplicitLod: - case SpvOp::SpvOpImageSampleProjDrefImplicitLod: - case SpvOp::SpvOpImageSampleProjDrefExplicitLod: - case SpvOp::SpvOpImageGather: - case SpvOp::SpvOpImageDrefGather: - case SpvOp::SpvOpImageQueryLod: - case SpvOp::SpvOpImageSparseSampleImplicitLod: - case SpvOp::SpvOpImageSparseSampleExplicitLod: - case SpvOp::SpvOpImageSparseSampleDrefImplicitLod: - case SpvOp::SpvOpImageSparseSampleDrefExplicitLod: - case SpvOp::SpvOpImageSparseSampleProjImplicitLod: - case SpvOp::SpvOpImageSparseSampleProjExplicitLod: - case SpvOp::SpvOpImageSparseSampleProjDrefImplicitLod: - case SpvOp::SpvOpImageSparseSampleProjDrefExplicitLod: - case SpvOp::SpvOpImageSparseGather: - case SpvOp::SpvOpImageSparseDrefGather: - case SpvOp::SpvOpImageFetch: - case SpvOp::SpvOpImageRead: - case SpvOp::SpvOpImageQueryFormat: - case SpvOp::SpvOpImageQueryOrder: - case SpvOp::SpvOpImageQuerySizeLod: - case SpvOp::SpvOpImageQuerySize: - case SpvOp::SpvOpImageQueryLevels: - case SpvOp::SpvOpImageQuerySamples: - case SpvOp::SpvOpImageSparseFetch: - case SpvOp::SpvOpImageSparseRead: - case SpvOp::SpvOpImageWrite: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageQueryLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageFetch: + case spv::Op::OpImageRead: + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: + case spv::Op::OpImageQuerySizeLod: + case spv::Op::OpImageQuerySize: + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseRead: + case spv::Op::OpImageWrite: return inst->GetSingleWordInOperand(kSpvImageSampleImageIdInIdx); default: break; @@ -190,56 +188,58 @@ Instruction* InstBindlessCheckPass::GetPointeeTypeInst(Instruction* ptr_inst) { bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, RefAnalysis* ref) { ref->ref_inst = ref_inst; - if (ref_inst->opcode() == SpvOpLoad || ref_inst->opcode() == SpvOpStore) { + if (ref_inst->opcode() == spv::Op::OpLoad || + ref_inst->opcode() == spv::Op::OpStore) { ref->desc_load_id = 0; ref->ptr_id = ref_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx); Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id); - if (ptr_inst->opcode() != SpvOp::SpvOpAccessChain) return false; + if (ptr_inst->opcode() != spv::Op::OpAccessChain) return false; ref->var_id = ptr_inst->GetSingleWordInOperand(kSpvAccessChainBaseIdInIdx); Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); - if (var_inst->opcode() != SpvOp::SpvOpVariable) return false; - uint32_t storage_class = - var_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx); + if (var_inst->opcode() != spv::Op::OpVariable) return false; + spv::StorageClass storage_class = spv::StorageClass( + var_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx)); switch (storage_class) { - case SpvStorageClassUniform: - case SpvStorageClassStorageBuffer: + case spv::StorageClass::Uniform: + case spv::StorageClass::StorageBuffer: break; default: return false; break; } // Check for deprecated storage block form - if (storage_class == SpvStorageClassUniform) { + if (storage_class == spv::StorageClass::Uniform) { uint32_t var_ty_id = var_inst->type_id(); Instruction* var_ty_inst = get_def_use_mgr()->GetDef(var_ty_id); uint32_t ptr_ty_id = var_ty_inst->GetSingleWordInOperand(kSpvTypePtrTypeIdInIdx); Instruction* ptr_ty_inst = get_def_use_mgr()->GetDef(ptr_ty_id); - SpvOp ptr_ty_op = ptr_ty_inst->opcode(); + spv::Op ptr_ty_op = ptr_ty_inst->opcode(); uint32_t block_ty_id = - (ptr_ty_op == SpvOpTypeArray || ptr_ty_op == SpvOpTypeRuntimeArray) + (ptr_ty_op == spv::Op::OpTypeArray || + ptr_ty_op == spv::Op::OpTypeRuntimeArray) ? ptr_ty_inst->GetSingleWordInOperand(kSpvTypeArrayTypeIdInIdx) : ptr_ty_id; assert(get_def_use_mgr()->GetDef(block_ty_id)->opcode() == - SpvOpTypeStruct && + spv::Op::OpTypeStruct && "unexpected block type"); bool block_found = get_decoration_mgr()->FindDecoration( - block_ty_id, SpvDecorationBlock, + block_ty_id, uint32_t(spv::Decoration::Block), [](const Instruction&) { return true; }); if (!block_found) { // If block decoration not found, verify deprecated form of SSBO bool buffer_block_found = get_decoration_mgr()->FindDecoration( - block_ty_id, SpvDecorationBufferBlock, + block_ty_id, uint32_t(spv::Decoration::BufferBlock), [](const Instruction&) { return true; }); USE_ASSERT(buffer_block_found && "block decoration not found"); - storage_class = SpvStorageClassStorageBuffer; + storage_class = spv::StorageClass::StorageBuffer; } } - ref->strg_class = storage_class; + ref->strg_class = uint32_t(storage_class); Instruction* desc_type_inst = GetPointeeTypeInst(var_inst); switch (desc_type_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: // A load through a descriptor array will have at least 3 operands. We // do not want to instrument loads of descriptors here which are part of // an image-based reference. @@ -261,29 +261,29 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, Instruction* desc_load_inst; for (;;) { desc_load_inst = get_def_use_mgr()->GetDef(desc_load_id); - if (desc_load_inst->opcode() == SpvOp::SpvOpSampledImage) + if (desc_load_inst->opcode() == spv::Op::OpSampledImage) desc_load_id = desc_load_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx); - else if (desc_load_inst->opcode() == SpvOp::SpvOpImage) + else if (desc_load_inst->opcode() == spv::Op::OpImage) desc_load_id = desc_load_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx); - else if (desc_load_inst->opcode() == SpvOp::SpvOpCopyObject) + else if (desc_load_inst->opcode() == spv::Op::OpCopyObject) desc_load_id = desc_load_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx); else break; } - if (desc_load_inst->opcode() != SpvOp::SpvOpLoad) { + if (desc_load_inst->opcode() != spv::Op::OpLoad) { // TODO(greg-lunarg): Handle additional possibilities? return false; } ref->desc_load_id = desc_load_id; ref->ptr_id = desc_load_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx); Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id); - if (ptr_inst->opcode() == SpvOp::SpvOpVariable) { + if (ptr_inst->opcode() == spv::Op::OpVariable) { ref->desc_idx_id = 0; ref->var_id = ref->ptr_id; - } else if (ptr_inst->opcode() == SpvOp::SpvOpAccessChain) { + } else if (ptr_inst->opcode() == spv::Op::OpAccessChain) { if (ptr_inst->NumInOperands() != 2) { assert(false && "unexpected bindless index number"); return false; @@ -292,7 +292,7 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, ptr_inst->GetSingleWordInOperand(kSpvAccessChainIndex0IdInIdx); ref->var_id = ptr_inst->GetSingleWordInOperand(kSpvAccessChainBaseIdInIdx); Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); - if (var_inst->opcode() != SpvOpVariable) { + if (var_inst->opcode() != spv::Op::OpVariable) { assert(false && "unexpected bindless base"); return false; } @@ -369,13 +369,13 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, uint32_t buff_ty_id; uint32_t ac_in_idx = 1; switch (desc_ty_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: buff_ty_id = desc_ty_inst->GetSingleWordInOperand(0); ++ac_in_idx; break; default: - assert(desc_ty_inst->opcode() == SpvOpTypeStruct && + assert(desc_ty_inst->opcode() == spv::Op::OpTypeStruct && "unexpected descriptor type"); buff_ty_id = desc_ty_inst->result_id(); break; @@ -393,19 +393,20 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, Instruction* curr_ty_inst = get_def_use_mgr()->GetDef(curr_ty_id); uint32_t curr_offset_id = 0; switch (curr_ty_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: { // Get array stride and multiply by current index - uint32_t arr_stride = FindStride(curr_ty_id, SpvDecorationArrayStride); + uint32_t arr_stride = + FindStride(curr_ty_id, uint32_t(spv::Decoration::ArrayStride)); uint32_t arr_stride_id = builder->GetUintConstantId(arr_stride); uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), SpvOpIMul, arr_stride_id, curr_idx_32b_id); + GetUintId(), spv::Op::OpIMul, arr_stride_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); // Get element type for next step curr_ty_id = curr_ty_inst->GetSingleWordInOperand(0); } break; - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { assert(matrix_stride != 0 && "missing matrix stride"); matrix_stride_id = builder->GetUintConstantId(matrix_stride); uint32_t vec_ty_id = curr_ty_inst->GetSingleWordInOperand(0); @@ -423,40 +424,40 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, } uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), SpvOpIMul, col_stride_id, curr_idx_32b_id); + GetUintId(), spv::Op::OpIMul, col_stride_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); // Get element type for next step curr_ty_id = vec_ty_id; in_matrix = true; } break; - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { // If inside a row major matrix type, multiply index by matrix stride, // else multiply by component size uint32_t comp_ty_id = curr_ty_inst->GetSingleWordInOperand(0u); uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); if (in_matrix && !col_major) { Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), SpvOpIMul, matrix_stride_id, curr_idx_32b_id); + GetUintId(), spv::Op::OpIMul, matrix_stride_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); } else { uint32_t comp_ty_sz = ByteSize(comp_ty_id, 0u, false, false); uint32_t comp_ty_sz_id = builder->GetUintConstantId(comp_ty_sz); Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), SpvOpIMul, comp_ty_sz_id, curr_idx_32b_id); + GetUintId(), spv::Op::OpIMul, comp_ty_sz_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); } // Get element type for next step curr_ty_id = comp_ty_id; } break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { // Get buffer byte offset for the referenced member Instruction* curr_idx_inst = get_def_use_mgr()->GetDef(curr_idx_id); - assert(curr_idx_inst->opcode() == SpvOpConstant && + assert(curr_idx_inst->opcode() == spv::Op::OpConstant && "unexpected struct index"); uint32_t member_idx = curr_idx_inst->GetSingleWordInOperand(0); uint32_t member_offset = 0xdeadbeef; bool found = get_decoration_mgr()->FindDecoration( - curr_ty_id, SpvDecorationOffset, + curr_ty_id, uint32_t(spv::Decoration::Offset), [&member_idx, &member_offset](const Instruction& deco_inst) { if (deco_inst.GetSingleWordInOperand(1u) != member_idx) return false; @@ -470,7 +471,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, // enclosing struct type at the member index. If none found, reset // stride to 0. found = get_decoration_mgr()->FindDecoration( - curr_ty_id, SpvDecorationMatrixStride, + curr_ty_id, uint32_t(spv::Decoration::MatrixStride), [&member_idx, &matrix_stride](const Instruction& deco_inst) { if (deco_inst.GetSingleWordInOperand(1u) != member_idx) return false; @@ -480,7 +481,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, if (!found) matrix_stride = 0; // Look for column major decoration found = get_decoration_mgr()->FindDecoration( - curr_ty_id, SpvDecorationColMajor, + curr_ty_id, uint32_t(spv::Decoration::ColMajor), [&member_idx, &col_major](const Instruction& deco_inst) { if (deco_inst.GetSingleWordInOperand(1u) != member_idx) return false; @@ -496,8 +497,8 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, if (sum_id == 0) sum_id = curr_offset_id; else { - Instruction* sum_inst = - builder->AddBinaryOp(GetUintId(), SpvOpIAdd, sum_id, curr_offset_id); + Instruction* sum_inst = builder->AddBinaryOp(GetUintId(), spv::Op::OpIAdd, + sum_id, curr_offset_id); sum_id = sum_inst->result_id(); } ++ac_in_idx; @@ -507,7 +508,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, uint32_t last = bsize - 1; uint32_t last_id = builder->GetUintConstantId(last); Instruction* sum_inst = - builder->AddBinaryOp(GetUintId(), SpvOpIAdd, sum_id, last_id); + builder->AddBinaryOp(GetUintId(), spv::Op::OpIAdd, sum_id, last_id); return sum_inst->result_id(); } @@ -527,8 +528,9 @@ void InstBindlessCheckPass::GenCheckCode( std::unique_ptr merge_label(NewLabel(merge_blk_id)); std::unique_ptr valid_label(NewLabel(valid_blk_id)); std::unique_ptr invalid_label(NewLabel(invalid_blk_id)); - (void)builder.AddConditionalBranch(check_id, valid_blk_id, invalid_blk_id, - merge_blk_id, SpvSelectionControlMaskNone); + (void)builder.AddConditionalBranch( + check_id, valid_blk_id, invalid_blk_id, merge_blk_id, + uint32_t(spv::SelectionControlMask::MaskNone)); // Gen valid bounds branch std::unique_ptr new_blk_ptr( new BasicBlock(std::move(valid_label))); @@ -593,24 +595,24 @@ void InstBindlessCheckPass::GenDescIdxCheckCode( RefAnalysis ref; if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return; Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id); - if (ptr_inst->opcode() != SpvOp::SpvOpAccessChain) return; + if (ptr_inst->opcode() != spv::Op::OpAccessChain) return; // If index and bound both compile-time constants and index < bound, // return without changing Instruction* var_inst = get_def_use_mgr()->GetDef(ref.var_id); Instruction* desc_type_inst = GetPointeeTypeInst(var_inst); uint32_t length_id = 0; - if (desc_type_inst->opcode() == SpvOpTypeArray) { + if (desc_type_inst->opcode() == spv::Op::OpTypeArray) { length_id = desc_type_inst->GetSingleWordInOperand(kSpvTypeArrayLengthIdInIdx); Instruction* index_inst = get_def_use_mgr()->GetDef(ref.desc_idx_id); Instruction* length_inst = get_def_use_mgr()->GetDef(length_id); - if (index_inst->opcode() == SpvOpConstant && - length_inst->opcode() == SpvOpConstant && + if (index_inst->opcode() == spv::Op::OpConstant && + length_inst->opcode() == spv::Op::OpConstant && index_inst->GetSingleWordInOperand(kSpvConstantValueInIdx) < length_inst->GetSingleWordInOperand(kSpvConstantValueInIdx)) return; } else if (!desc_idx_enabled_ || - desc_type_inst->opcode() != SpvOpTypeRuntimeArray) { + desc_type_inst->opcode() != spv::Op::OpTypeRuntimeArray) { return; } // Move original block's preceding instructions into first new block @@ -624,7 +626,7 @@ void InstBindlessCheckPass::GenDescIdxCheckCode( // If length id not yet set, descriptor array is runtime size so // generate load of length from stage's debug input buffer. if (length_id == 0) { - assert(desc_type_inst->opcode() == SpvOpTypeRuntimeArray && + assert(desc_type_inst->opcode() == spv::Op::OpTypeRuntimeArray && "unexpected bindless type"); length_id = GenDebugReadLength(ref.var_id, &builder); } @@ -633,7 +635,7 @@ void InstBindlessCheckPass::GenDescIdxCheckCode( // for the referenced value. uint32_t desc_idx_32b_id = Gen32BitCvtCode(ref.desc_idx_id, &builder); uint32_t length_32b_id = Gen32BitCvtCode(length_id, &builder); - Instruction* ult_inst = builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, + Instruction* ult_inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpULessThan, desc_idx_32b_id, length_32b_id); ref.desc_idx_id = desc_idx_32b_id; GenCheckCode(ult_inst->result_id(), error_id, 0u, length_id, stage_idx, &ref, @@ -661,9 +663,10 @@ void InstBindlessCheckPass::GenDescInitCheckCode( // TODO(greg-lunarg): Do bounds check for aggregate loads and stores Instruction* ref_ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id); Instruction* pte_type_inst = GetPointeeTypeInst(ref_ptr_inst); - uint32_t pte_type_op = pte_type_inst->opcode(); - if (pte_type_op == SpvOpTypeArray || pte_type_op == SpvOpTypeRuntimeArray || - pte_type_op == SpvOpTypeStruct) + spv::Op pte_type_op = pte_type_inst->opcode(); + if (pte_type_op == spv::Op::OpTypeArray || + pte_type_op == spv::Op::OpTypeRuntimeArray || + pte_type_op == spv::Op::OpTypeStruct) init_check = true; } // If initialization check and not enabled, return @@ -687,11 +690,13 @@ void InstBindlessCheckPass::GenDescInitCheckCode( // being full reference and false branch being debug output and zero // for the referenced value. Instruction* ult_inst = - builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, ref_id, init_id); - uint32_t error = init_check ? kInstErrorBindlessUninit - : (ref.strg_class == SpvStorageClassUniform - ? kInstErrorBuffOOBUniform - : kInstErrorBuffOOBStorage); + builder.AddBinaryOp(GetBoolId(), spv::Op::OpULessThan, ref_id, init_id); + uint32_t error = + init_check + ? kInstErrorBindlessUninit + : (spv::StorageClass(ref.strg_class) == spv::StorageClass::Uniform + ? kInstErrorBuffOOBUniform + : kInstErrorBuffOOBStorage); uint32_t error_id = builder.GetUintConstantId(error); GenCheckCode(ult_inst->result_id(), error_id, init_check ? 0 : ref_id, init_check ? builder.GetUintConstantId(0u) : init_id, stage_idx, @@ -708,11 +713,11 @@ void InstBindlessCheckPass::GenTexBuffCheckCode( std::vector>* new_blocks) { // Only process OpImageRead and OpImageWrite with no optional operands Instruction* ref_inst = &*ref_inst_itr; - SpvOp op = ref_inst->opcode(); + spv::Op op = ref_inst->opcode(); uint32_t num_in_oprnds = ref_inst->NumInOperands(); - if (!((op == SpvOpImageRead && num_in_oprnds == 2) || - (op == SpvOpImageFetch && num_in_oprnds == 2) || - (op == SpvOpImageWrite && num_in_oprnds == 3))) + if (!((op == spv::Op::OpImageRead && num_in_oprnds == 2) || + (op == spv::Op::OpImageFetch && num_in_oprnds == 2) || + (op == spv::Op::OpImageWrite && num_in_oprnds == 3))) return; // Pull components from descriptor reference RefAnalysis ref; @@ -721,17 +726,20 @@ void InstBindlessCheckPass::GenTexBuffCheckCode( Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id); uint32_t image_ty_id = image_inst->type_id(); Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id); - if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim) != SpvDimBuffer) + if (spv::Dim(image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim)) != + spv::Dim::Buffer) { return; + } if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) != 0) return; if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) != 0) return; if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) != 0) return; // Enable ImageQuery Capability if not yet enabled - if (!get_feature_mgr()->HasCapability(SpvCapabilityImageQuery)) { - std::unique_ptr cap_image_query_inst(new Instruction( - context(), SpvOpCapability, 0, 0, - std::initializer_list{ - {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityImageQuery}}})); + if (!get_feature_mgr()->HasCapability(spv::Capability::ImageQuery)) { + std::unique_ptr cap_image_query_inst( + new Instruction(context(), spv::Op::OpCapability, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_CAPABILITY, + {uint32_t(spv::Capability::ImageQuery)}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*cap_image_query_inst); context()->AddCapability(std::move(cap_image_query_inst)); } @@ -750,13 +758,13 @@ void InstBindlessCheckPass::GenTexBuffCheckCode( if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u); // Get texel buffer size. Instruction* size_inst = - builder.AddUnaryOp(GetUintId(), SpvOpImageQuerySize, ref.image_id); + builder.AddUnaryOp(GetUintId(), spv::Op::OpImageQuerySize, ref.image_id); uint32_t size_id = size_inst->result_id(); // Generate runtime initialization/bounds test code with true branch // being full reference and false branch being debug output and zero // for the referenced value. Instruction* ult_inst = - builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, coord_id, size_id); + builder.AddBinaryOp(GetBoolId(), spv::Op::OpULessThan, coord_id, size_id); uint32_t error = (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageSampled) == 2) ? kInstErrorBuffOOBStorageTexel @@ -778,13 +786,16 @@ void InstBindlessCheckPass::InitializeInstBindlessCheck() { // init check is enabled. if (desc_idx_enabled_ || buffer_bounds_enabled_ || texel_buffer_enabled_) for (auto& anno : get_module()->annotations()) - if (anno.opcode() == SpvOpDecorate) { - if (anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet) + if (anno.opcode() == spv::Op::OpDecorate) { + if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::DescriptorSet) { var2desc_set_[anno.GetSingleWordInOperand(0u)] = anno.GetSingleWordInOperand(2u); - else if (anno.GetSingleWordInOperand(1u) == SpvDecorationBinding) + } else if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::Binding) { var2binding_[anno.GetSingleWordInOperand(0u)] = anno.GetSingleWordInOperand(2u); + } } } diff --git a/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp b/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp index 3318f88f2..be361e69b 100644 --- a/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp @@ -22,9 +22,9 @@ namespace opt { uint32_t InstBuffAddrCheckPass::CloneOriginalReference( Instruction* ref_inst, InstructionBuilder* builder) { // Clone original ref with new result id (if load) - assert( - (ref_inst->opcode() == SpvOpLoad || ref_inst->opcode() == SpvOpStore) && - "unexpected ref"); + assert((ref_inst->opcode() == spv::Op::OpLoad || + ref_inst->opcode() == spv::Op::OpStore) && + "unexpected ref"); std::unique_ptr new_ref_inst(ref_inst->Clone(context())); uint32_t ref_result_id = ref_inst->result_id(); uint32_t new_ref_id = 0; @@ -41,16 +41,17 @@ uint32_t InstBuffAddrCheckPass::CloneOriginalReference( } bool InstBuffAddrCheckPass::IsPhysicalBuffAddrReference(Instruction* ref_inst) { - if (ref_inst->opcode() != SpvOpLoad && ref_inst->opcode() != SpvOpStore) + if (ref_inst->opcode() != spv::Op::OpLoad && + ref_inst->opcode() != spv::Op::OpStore) return false; uint32_t ptr_id = ref_inst->GetSingleWordInOperand(0); analysis::DefUseManager* du_mgr = get_def_use_mgr(); Instruction* ptr_inst = du_mgr->GetDef(ptr_id); - if (ptr_inst->opcode() != SpvOpAccessChain) return false; + if (ptr_inst->opcode() != spv::Op::OpAccessChain) return false; uint32_t ptr_ty_id = ptr_inst->type_id(); Instruction* ptr_ty_inst = du_mgr->GetDef(ptr_ty_id); - if (ptr_ty_inst->GetSingleWordInOperand(0) != - SpvStorageClassPhysicalStorageBufferEXT) + if (spv::StorageClass(ptr_ty_inst->GetSingleWordInOperand(0)) != + spv::StorageClass::PhysicalStorageBufferEXT) return false; return true; } @@ -72,8 +73,9 @@ void InstBuffAddrCheckPass::GenCheckCode( std::unique_ptr merge_label(NewLabel(merge_blk_id)); std::unique_ptr valid_label(NewLabel(valid_blk_id)); std::unique_ptr invalid_label(NewLabel(invalid_blk_id)); - (void)builder.AddConditionalBranch(check_id, valid_blk_id, invalid_blk_id, - merge_blk_id, SpvSelectionControlMaskNone); + (void)builder.AddConditionalBranch( + check_id, valid_blk_id, invalid_blk_id, merge_blk_id, + uint32_t(spv::SelectionControlMask::MaskNone)); // Gen valid branch std::unique_ptr new_blk_ptr( new BasicBlock(std::move(valid_label))); @@ -86,12 +88,12 @@ void InstBuffAddrCheckPass::GenCheckCode( builder.SetInsertPoint(&*new_blk_ptr); // Convert uptr from uint64 to 2 uint32 Instruction* lo_uptr_inst = - builder.AddUnaryOp(GetUintId(), SpvOpUConvert, ref_uptr_id); + builder.AddUnaryOp(GetUintId(), spv::Op::OpUConvert, ref_uptr_id); Instruction* rshift_uptr_inst = - builder.AddBinaryOp(GetUint64Id(), SpvOpShiftRightLogical, ref_uptr_id, - builder.GetUintConstantId(32)); - Instruction* hi_uptr_inst = builder.AddUnaryOp(GetUintId(), SpvOpUConvert, - rshift_uptr_inst->result_id()); + builder.AddBinaryOp(GetUint64Id(), spv::Op::OpShiftRightLogical, + ref_uptr_id, builder.GetUintConstantId(32)); + Instruction* hi_uptr_inst = builder.AddUnaryOp( + GetUintId(), spv::Op::OpUConvert, rshift_uptr_inst->result_id()); GenDebugStreamWrite( uid2offset_[ref_inst->unique_id()], stage_idx, {error_id, lo_uptr_inst->result_id(), hi_uptr_inst->result_id()}, @@ -105,8 +107,8 @@ void InstBuffAddrCheckPass::GenCheckCode( analysis::Type* ref_type = type_mgr->GetType(ref_type_id); if (ref_type->AsPointer() != nullptr) { uint32_t null_u64_id = GetNullId(GetUint64Id()); - Instruction* null_ptr_inst = - builder.AddUnaryOp(ref_type_id, SpvOpConvertUToPtr, null_u64_id); + Instruction* null_ptr_inst = builder.AddUnaryOp( + ref_type_id, spv::Op::OpConvertUToPtr, null_u64_id); null_id = null_ptr_inst->result_id(); } else { null_id = GetNullId(ref_type_id); @@ -133,16 +135,16 @@ void InstBuffAddrCheckPass::GenCheckCode( uint32_t InstBuffAddrCheckPass::GetTypeAlignment(uint32_t type_id) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case SpvOpTypeFloat: - case SpvOpTypeInt: - case SpvOpTypeVector: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeVector: return GetTypeLength(type_id); - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: return GetTypeAlignment(type_inst->GetSingleWordInOperand(0)); - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: return GetTypeAlignment(type_inst->GetSingleWordInOperand(0)); - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { uint32_t max = 0; type_inst->ForEachInId([&max, this](const uint32_t* iid) { uint32_t alignment = GetTypeAlignment(*iid); @@ -150,9 +152,9 @@ uint32_t InstBuffAddrCheckPass::GetTypeAlignment(uint32_t type_id) { }); return max; } - case SpvOpTypePointer: - assert(type_inst->GetSingleWordInOperand(0) == - SpvStorageClassPhysicalStorageBufferEXT && + case spv::Op::OpTypePointer: + assert(spv::StorageClass(type_inst->GetSingleWordInOperand(0)) == + spv::StorageClass::PhysicalStorageBufferEXT && "unexpected pointer type"); return 8u; default: @@ -164,29 +166,29 @@ uint32_t InstBuffAddrCheckPass::GetTypeAlignment(uint32_t type_id) { uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case SpvOpTypeFloat: - case SpvOpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: return type_inst->GetSingleWordInOperand(0) / 8u; - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { uint32_t raw_cnt = type_inst->GetSingleWordInOperand(1); uint32_t adj_cnt = (raw_cnt == 3u) ? 4u : raw_cnt; return adj_cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0)); } - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: return type_inst->GetSingleWordInOperand(1) * GetTypeLength(type_inst->GetSingleWordInOperand(0)); - case SpvOpTypePointer: - assert(type_inst->GetSingleWordInOperand(0) == - SpvStorageClassPhysicalStorageBufferEXT && + case spv::Op::OpTypePointer: + assert(spv::StorageClass(type_inst->GetSingleWordInOperand(0)) == + spv::StorageClass::PhysicalStorageBufferEXT && "unexpected pointer type"); return 8u; - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { uint32_t const_id = type_inst->GetSingleWordInOperand(1); Instruction* const_inst = get_def_use_mgr()->GetDef(const_id); uint32_t cnt = const_inst->GetSingleWordInOperand(0); return cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0)); } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { uint32_t len = 0; type_inst->ForEachInId([&len, this](const uint32_t* iid) { // Align struct length @@ -200,7 +202,7 @@ uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) { }); return len; } - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeRuntimeArray: default: assert(false && "unexpected type"); return 0; @@ -213,7 +215,7 @@ void InstBuffAddrCheckPass::AddParam(uint32_t type_id, uint32_t pid = TakeNextId(); param_vec->push_back(pid); std::unique_ptr param_inst(new Instruction( - get_module()->context(), SpvOpFunctionParameter, type_id, pid, {})); + get_module()->context(), spv::Op::OpFunctionParameter, type_id, pid, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); (*input_func)->AddParameter(std::move(param_inst)); } @@ -231,10 +233,10 @@ uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { analysis::Function func_ty(type_mgr->GetType(GetBoolId()), param_types); analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty); std::unique_ptr func_inst( - new Instruction(get_module()->context(), SpvOpFunction, GetBoolId(), - search_test_func_id_, + new Instruction(get_module()->context(), spv::Op::OpFunction, + GetBoolId(), search_test_func_id_, {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvFunctionControlMaskNone}}, + {uint32_t(spv::FunctionControlMask::MaskNone)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_mgr->GetTypeInstruction(reg_func_ty)}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); @@ -256,7 +258,7 @@ uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { // Branch to search loop header std::unique_ptr hdr_blk_label(NewLabel(hdr_blk_id)); (void)builder.AddInstruction(MakeUnique( - context(), SpvOpBranch, 0, 0, + context(), spv::Op::OpBranch, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {hdr_blk_id}}})); input_func->AddBasicBlock(std::move(first_blk_ptr)); // Linear search loop header block @@ -273,12 +275,12 @@ uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { uint32_t idx_phi_id = TakeNextId(); uint32_t idx_inc_id = TakeNextId(); std::unique_ptr idx_inc_inst(new Instruction( - context(), SpvOpIAdd, GetUintId(), idx_inc_id, + context(), spv::Op::OpIAdd, GetUintId(), idx_inc_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {idx_phi_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {builder.GetUintConstantId(1u)}}})); std::unique_ptr idx_phi_inst(new Instruction( - context(), SpvOpPhi, GetUintId(), idx_phi_id, + context(), spv::Op::OpPhi, GetUintId(), idx_phi_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {builder.GetUintConstantId(1u)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {first_blk_id}}, @@ -292,14 +294,15 @@ uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { std::unique_ptr bound_test_blk_label( NewLabel(bound_test_blk_id)); (void)builder.AddInstruction(MakeUnique( - context(), SpvOpLoopMerge, 0, 0, + context(), spv::Op::OpLoopMerge, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {bound_test_blk_id}}, {SPV_OPERAND_TYPE_ID, {cont_blk_id}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {SpvLoopControlMaskNone}}})); + {SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::LoopControlMask::MaskNone)}}})); // Branch to continue/work block (void)builder.AddInstruction(MakeUnique( - context(), SpvOpBranch, 0, 0, + context(), spv::Op::OpBranch, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {cont_blk_id}}})); input_func->AddBasicBlock(std::move(hdr_blk_ptr)); // Continue/Work Block. Read next buffer pointer and break if greater @@ -313,19 +316,19 @@ uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { uint32_t ibuf_id = GetInputBufferId(); uint32_t ibuf_ptr_id = GetInputBufferPtrId(); Instruction* uptr_ac_inst = builder.AddTernaryOp( - ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id, builder.GetUintConstantId(kDebugInputDataOffset), idx_inc_id); uint32_t ibuf_type_id = GetInputBufferTypeId(); - Instruction* uptr_load_inst = - builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, uptr_ac_inst->result_id()); + Instruction* uptr_load_inst = builder.AddUnaryOp( + ibuf_type_id, spv::Op::OpLoad, uptr_ac_inst->result_id()); // If loaded address greater than ref_ptr arg, break, else branch back to // loop header Instruction* uptr_test_inst = - builder.AddBinaryOp(GetBoolId(), SpvOpUGreaterThan, + builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThan, uptr_load_inst->result_id(), param_vec[0]); - (void)builder.AddConditionalBranch(uptr_test_inst->result_id(), - bound_test_blk_id, hdr_blk_id, - kInvalidId, SpvSelectionControlMaskNone); + (void)builder.AddConditionalBranch( + uptr_test_inst->result_id(), bound_test_blk_id, hdr_blk_id, kInvalidId, + uint32_t(spv::SelectionControlMask::MaskNone)); input_func->AddBasicBlock(std::move(cont_blk_ptr)); // Bounds test block. Read length of selected buffer and test that // all len arg bytes are in buffer. @@ -333,63 +336,65 @@ uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { MakeUnique(std::move(bound_test_blk_label)); builder.SetInsertPoint(&*bound_test_blk_ptr); // Decrement index to point to previous/candidate buffer address - Instruction* cand_idx_inst = builder.AddBinaryOp( - GetUintId(), SpvOpISub, idx_inc_id, builder.GetUintConstantId(1u)); + Instruction* cand_idx_inst = + builder.AddBinaryOp(GetUintId(), spv::Op::OpISub, idx_inc_id, + builder.GetUintConstantId(1u)); // Load candidate buffer address Instruction* cand_ac_inst = - builder.AddTernaryOp(ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.AddTernaryOp(ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id, builder.GetUintConstantId(kDebugInputDataOffset), cand_idx_inst->result_id()); - Instruction* cand_load_inst = - builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, cand_ac_inst->result_id()); + Instruction* cand_load_inst = builder.AddUnaryOp( + ibuf_type_id, spv::Op::OpLoad, cand_ac_inst->result_id()); // Compute offset of ref_ptr from candidate buffer address - Instruction* offset_inst = builder.AddBinaryOp( - ibuf_type_id, SpvOpISub, param_vec[0], cand_load_inst->result_id()); + Instruction* offset_inst = + builder.AddBinaryOp(ibuf_type_id, spv::Op::OpISub, param_vec[0], + cand_load_inst->result_id()); // Convert ref length to uint64 Instruction* ref_len_64_inst = - builder.AddUnaryOp(ibuf_type_id, SpvOpUConvert, param_vec[1]); + builder.AddUnaryOp(ibuf_type_id, spv::Op::OpUConvert, param_vec[1]); // Add ref length to ref offset to compute end of reference - Instruction* ref_end_inst = - builder.AddBinaryOp(ibuf_type_id, SpvOpIAdd, offset_inst->result_id(), - ref_len_64_inst->result_id()); + Instruction* ref_end_inst = builder.AddBinaryOp( + ibuf_type_id, spv::Op::OpIAdd, offset_inst->result_id(), + ref_len_64_inst->result_id()); // Load starting index of lengths in input buffer and convert to uint32 Instruction* len_start_ac_inst = - builder.AddTernaryOp(ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.AddTernaryOp(ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id, builder.GetUintConstantId(kDebugInputDataOffset), builder.GetUintConstantId(0u)); Instruction* len_start_load_inst = builder.AddUnaryOp( - ibuf_type_id, SpvOpLoad, len_start_ac_inst->result_id()); + ibuf_type_id, spv::Op::OpLoad, len_start_ac_inst->result_id()); Instruction* len_start_32_inst = builder.AddUnaryOp( - GetUintId(), SpvOpUConvert, len_start_load_inst->result_id()); + GetUintId(), spv::Op::OpUConvert, len_start_load_inst->result_id()); // Decrement search index to get candidate buffer length index - Instruction* cand_len_idx_inst = - builder.AddBinaryOp(GetUintId(), SpvOpISub, cand_idx_inst->result_id(), - builder.GetUintConstantId(1u)); + Instruction* cand_len_idx_inst = builder.AddBinaryOp( + GetUintId(), spv::Op::OpISub, cand_idx_inst->result_id(), + builder.GetUintConstantId(1u)); // Add candidate length index to start index Instruction* len_idx_inst = builder.AddBinaryOp( - GetUintId(), SpvOpIAdd, cand_len_idx_inst->result_id(), + GetUintId(), spv::Op::OpIAdd, cand_len_idx_inst->result_id(), len_start_32_inst->result_id()); // Load candidate buffer length Instruction* len_ac_inst = - builder.AddTernaryOp(ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.AddTernaryOp(ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id, builder.GetUintConstantId(kDebugInputDataOffset), len_idx_inst->result_id()); - Instruction* len_load_inst = - builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, len_ac_inst->result_id()); + Instruction* len_load_inst = builder.AddUnaryOp( + ibuf_type_id, spv::Op::OpLoad, len_ac_inst->result_id()); // Test if reference end within candidate buffer length Instruction* len_test_inst = builder.AddBinaryOp( - GetBoolId(), SpvOpULessThanEqual, ref_end_inst->result_id(), + GetBoolId(), spv::Op::OpULessThanEqual, ref_end_inst->result_id(), len_load_inst->result_id()); // Return test result (void)builder.AddInstruction(MakeUnique( - context(), SpvOpReturnValue, 0, 0, + context(), spv::Op::OpReturnValue, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {len_test_inst->result_id()}}})); // Close block input_func->AddBasicBlock(std::move(bound_test_blk_ptr)); // Close function and add function to module - std::unique_ptr func_end_inst( - new Instruction(get_module()->context(), SpvOpFunctionEnd, 0, 0, {})); + std::unique_ptr func_end_inst(new Instruction( + get_module()->context(), spv::Op::OpFunctionEnd, 0, 0, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst); input_func->SetFunctionEnd(std::move(func_end_inst)); context()->AddFunction(std::move(input_func)); @@ -403,18 +408,18 @@ uint32_t InstBuffAddrCheckPass::GenSearchAndTest(Instruction* ref_inst, InstructionBuilder* builder, uint32_t* ref_uptr_id) { // Enable Int64 if necessary - if (!get_feature_mgr()->HasCapability(SpvCapabilityInt64)) { + if (!get_feature_mgr()->HasCapability(spv::Capability::Int64)) { std::unique_ptr cap_int64_inst(new Instruction( - context(), SpvOpCapability, 0, 0, - std::initializer_list{ - {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityInt64}}})); + context(), spv::Op::OpCapability, 0, 0, + std::initializer_list{{SPV_OPERAND_TYPE_CAPABILITY, + {uint32_t(spv::Capability::Int64)}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*cap_int64_inst); context()->AddCapability(std::move(cap_int64_inst)); } // Convert reference pointer to uint64 uint32_t ref_ptr_id = ref_inst->GetSingleWordInOperand(0); Instruction* ref_uptr_inst = - builder->AddUnaryOp(GetUint64Id(), SpvOpConvertPtrToU, ref_ptr_id); + builder->AddUnaryOp(GetUint64Id(), spv::Op::OpConvertPtrToU, ref_ptr_id); *ref_uptr_id = ref_uptr_inst->result_id(); // Compute reference length in bytes analysis::DefUseManager* du_mgr = get_def_use_mgr(); @@ -427,7 +432,7 @@ uint32_t InstBuffAddrCheckPass::GenSearchAndTest(Instruction* ref_inst, const std::vector args = {GetSearchAndTestFuncId(), *ref_uptr_id, ref_len_id}; Instruction* call_inst = - builder->AddNaryOp(GetBoolId(), SpvOpFunctionCall, args); + builder->AddNaryOp(GetBoolId(), spv::Op::OpFunctionCall, args); uint32_t retval = call_inst->result_id(); return retval; } @@ -485,7 +490,7 @@ Pass::Status InstBuffAddrCheckPass::ProcessImpl() { Pass::Status InstBuffAddrCheckPass::Process() { if (!get_feature_mgr()->HasCapability( - SpvCapabilityPhysicalStorageBufferAddressesEXT)) + spv::Capability::PhysicalStorageBufferAddressesEXT)) return Status::SuccessWithoutChange; InitInstBuffAddrCheck(); return ProcessImpl(); diff --git a/3rdparty/spirv-tools/source/opt/inst_debug_printf_pass.cpp b/3rdparty/spirv-tools/source/opt/inst_debug_printf_pass.cpp index 4218138f9..151b94c73 100644 --- a/3rdparty/spirv-tools/source/opt/inst_debug_printf_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/inst_debug_printf_pass.cpp @@ -35,7 +35,7 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, uint32_t c_ty_id = type_mgr->GetId(c_ty); for (uint32_t c = 0; c < v_ty->element_count(); ++c) { Instruction* c_inst = builder->AddIdLiteralOp( - c_ty_id, SpvOpCompositeExtract, val_inst->result_id(), c); + c_ty_id, spv::Op::OpCompositeExtract, val_inst->result_id(), c); GenOutputValues(c_inst, val_ids, builder); } return; @@ -44,8 +44,9 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, // Select between uint32 zero or one uint32_t zero_id = builder->GetUintConstantId(0); uint32_t one_id = builder->GetUintConstantId(1); - Instruction* sel_inst = builder->AddTernaryOp( - GetUintId(), SpvOpSelect, val_inst->result_id(), one_id, zero_id); + Instruction* sel_inst = + builder->AddTernaryOp(GetUintId(), spv::Op::OpSelect, + val_inst->result_id(), one_id, zero_id); val_ids->push_back(sel_inst->result_id()); return; } @@ -55,21 +56,21 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, case 16: { // Convert float16 to float32 and recurse Instruction* f32_inst = builder->AddUnaryOp( - GetFloatId(), SpvOpFConvert, val_inst->result_id()); + GetFloatId(), spv::Op::OpFConvert, val_inst->result_id()); GenOutputValues(f32_inst, val_ids, builder); return; } case 64: { // Bitcast float64 to uint64 and recurse Instruction* ui64_inst = builder->AddUnaryOp( - GetUint64Id(), SpvOpBitcast, val_inst->result_id()); + GetUint64Id(), spv::Op::OpBitcast, val_inst->result_id()); GenOutputValues(ui64_inst, val_ids, builder); return; } case 32: { // Bitcase float32 to uint32 - Instruction* bc_inst = builder->AddUnaryOp(GetUintId(), SpvOpBitcast, - val_inst->result_id()); + Instruction* bc_inst = builder->AddUnaryOp( + GetUintId(), spv::Op::OpBitcast, val_inst->result_id()); val_ids->push_back(bc_inst->result_id()); return; } @@ -85,17 +86,17 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, Instruction* ui64_inst = val_inst; if (i_ty->IsSigned()) { // Bitcast sint64 to uint64 - ui64_inst = builder->AddUnaryOp(GetUint64Id(), SpvOpBitcast, + ui64_inst = builder->AddUnaryOp(GetUint64Id(), spv::Op::OpBitcast, val_inst->result_id()); } // Break uint64 into 2x uint32 Instruction* lo_ui64_inst = builder->AddUnaryOp( - GetUintId(), SpvOpUConvert, ui64_inst->result_id()); + GetUintId(), spv::Op::OpUConvert, ui64_inst->result_id()); Instruction* rshift_ui64_inst = builder->AddBinaryOp( - GetUint64Id(), SpvOpShiftRightLogical, ui64_inst->result_id(), - builder->GetUintConstantId(32)); + GetUint64Id(), spv::Op::OpShiftRightLogical, + ui64_inst->result_id(), builder->GetUintConstantId(32)); Instruction* hi_ui64_inst = builder->AddUnaryOp( - GetUintId(), SpvOpUConvert, rshift_ui64_inst->result_id()); + GetUintId(), spv::Op::OpUConvert, rshift_ui64_inst->result_id()); val_ids->push_back(lo_ui64_inst->result_id()); val_ids->push_back(hi_ui64_inst->result_id()); return; @@ -104,12 +105,12 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, Instruction* ui8_inst = val_inst; if (i_ty->IsSigned()) { // Bitcast sint8 to uint8 - ui8_inst = builder->AddUnaryOp(GetUint8Id(), SpvOpBitcast, + ui8_inst = builder->AddUnaryOp(GetUint8Id(), spv::Op::OpBitcast, val_inst->result_id()); } // Convert uint8 to uint32 Instruction* ui32_inst = builder->AddUnaryOp( - GetUintId(), SpvOpUConvert, ui8_inst->result_id()); + GetUintId(), spv::Op::OpUConvert, ui8_inst->result_id()); val_ids->push_back(ui32_inst->result_id()); return; } @@ -117,7 +118,7 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, Instruction* ui32_inst = val_inst; if (i_ty->IsSigned()) { // Bitcast sint32 to uint32 - ui32_inst = builder->AddUnaryOp(GetUintId(), SpvOpBitcast, + ui32_inst = builder->AddUnaryOp(GetUintId(), spv::Op::OpBitcast, val_inst->result_id()); } // uint32 needs no further processing @@ -158,7 +159,7 @@ void InstDebugPrintfPass::GenOutputCode( return; } Instruction* opnd_inst = get_def_use_mgr()->GetDef(*iid); - if (opnd_inst->opcode() == SpvOpString) { + if (opnd_inst->opcode() == spv::Op::OpString) { uint32_t string_id_id = builder.GetUintConstantId(*iid); val_ids.push_back(string_id_id); } else { @@ -176,7 +177,7 @@ void InstDebugPrintfPass::GenDebugPrintfCode( std::vector>* new_blocks) { // If not DebugPrintf OpExtInst, return. Instruction* printf_inst = &*ref_inst_itr; - if (printf_inst->opcode() != SpvOpExtInst) return; + if (printf_inst->opcode() != spv::Op::OpExtInst) return; if (printf_inst->GetSingleWordInOperand(0) != ext_inst_printf_id_) return; if (printf_inst->GetSingleWordInOperand(1) != NonSemanticDebugPrintfDebugPrintf) diff --git a/3rdparty/spirv-tools/source/opt/instruction.cpp b/3rdparty/spirv-tools/source/opt/instruction.cpp index e775a9926..ece6baf92 100644 --- a/3rdparty/spirv-tools/source/opt/instruction.cpp +++ b/3rdparty/spirv-tools/source/opt/instruction.cpp @@ -24,38 +24,37 @@ namespace spvtools { namespace opt { - namespace { // Indices used to get particular operands out of instructions using InOperand. -const uint32_t kTypeImageDimIndex = 1; -const uint32_t kLoadBaseIndex = 0; -const uint32_t kPointerTypeStorageClassIndex = 0; -const uint32_t kVariableStorageClassIndex = 0; -const uint32_t kTypeImageSampledIndex = 5; +constexpr uint32_t kTypeImageDimIndex = 1; +constexpr uint32_t kLoadBaseIndex = 0; +constexpr uint32_t kPointerTypeStorageClassIndex = 0; +constexpr uint32_t kVariableStorageClassIndex = 0; +constexpr uint32_t kTypeImageSampledIndex = 5; // Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100 // extension instructions. -const uint32_t kExtInstSetIdInIdx = 0; -const uint32_t kExtInstInstructionInIdx = 1; -const uint32_t kDebugScopeNumWords = 7; -const uint32_t kDebugScopeNumWordsWithoutInlinedAt = 6; -const uint32_t kDebugNoScopeNumWords = 5; +constexpr uint32_t kExtInstSetIdInIdx = 0; +constexpr uint32_t kExtInstInstructionInIdx = 1; +constexpr uint32_t kDebugScopeNumWords = 7; +constexpr uint32_t kDebugScopeNumWordsWithoutInlinedAt = 6; +constexpr uint32_t kDebugNoScopeNumWords = 5; // Number of operands of an OpBranchConditional instruction // with weights. -const uint32_t kOpBranchConditionalWithWeightsNumOperands = 5; +constexpr uint32_t kOpBranchConditionalWithWeightsNumOperands = 5; } // namespace Instruction::Instruction(IRContext* c) : utils::IntrusiveNodeBase(), context_(c), - opcode_(SpvOpNop), + opcode_(spv::Op::OpNop), has_type_id_(false), has_result_id_(false), unique_id_(c->TakeNextUniqueId()), dbg_scope_(kNoDebugScope, kNoInlinedAt) {} -Instruction::Instruction(IRContext* c, SpvOp op) +Instruction::Instruction(IRContext* c, spv::Op op) : utils::IntrusiveNodeBase(), context_(c), opcode_(op), @@ -68,12 +67,13 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, std::vector&& dbg_line) : utils::IntrusiveNodeBase(), context_(c), - opcode_(static_cast(inst.opcode)), + opcode_(static_cast(inst.opcode)), has_type_id_(inst.type_id != 0), has_result_id_(inst.result_id != 0), unique_id_(c->TakeNextUniqueId()), dbg_line_insts_(std::move(dbg_line)), dbg_scope_(kNoDebugScope, kNoInlinedAt) { + operands_.reserve(inst.num_operands); for (uint32_t i = 0; i < inst.num_operands; ++i) { const auto& current_payload = inst.operands[i]; operands_.emplace_back( @@ -88,11 +88,12 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, const DebugScope& dbg_scope) : utils::IntrusiveNodeBase(), context_(c), - opcode_(static_cast(inst.opcode)), + opcode_(static_cast(inst.opcode)), has_type_id_(inst.type_id != 0), has_result_id_(inst.result_id != 0), unique_id_(c->TakeNextUniqueId()), dbg_scope_(dbg_scope) { + operands_.reserve(inst.num_operands); for (uint32_t i = 0; i < inst.num_operands; ++i) { const auto& current_payload = inst.operands[i]; operands_.emplace_back( @@ -101,7 +102,7 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, } } -Instruction::Instruction(IRContext* c, SpvOp op, uint32_t ty_id, +Instruction::Instruction(IRContext* c, spv::Op op, uint32_t ty_id, uint32_t res_id, const OperandList& in_operands) : utils::IntrusiveNodeBase(), context_(c), @@ -111,6 +112,14 @@ Instruction::Instruction(IRContext* c, SpvOp op, uint32_t ty_id, unique_id_(c->TakeNextUniqueId()), operands_(), dbg_scope_(kNoDebugScope, kNoInlinedAt) { + size_t operands_size = in_operands.size(); + if (has_type_id_) { + operands_size++; + } + if (has_result_id_) { + operands_size++; + } + operands_.reserve(operands_size); if (has_type_id_) { operands_.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_TYPE_ID, std::initializer_list{ty_id}); @@ -179,7 +188,7 @@ uint32_t Instruction::NumInOperandWords() const { } bool Instruction::HasBranchWeights() const { - if (opcode_ == SpvOpBranchConditional && + if (opcode_ == spv::Op::OpBranchConditional && NumOperands() == kOpBranchConditionalWithWeightsNumOperands) { return true; } @@ -208,13 +217,13 @@ bool Instruction::IsReadOnlyLoad() const { return false; } - if (address_def->opcode() == SpvOpVariable) { + if (address_def->opcode() == spv::Op::OpVariable) { if (address_def->IsReadOnlyPointer()) { return true; } } - if (address_def->opcode() == SpvOpLoad) { + if (address_def->opcode() == spv::Op::OpLoad) { const analysis::Type* address_type = context()->get_type_mgr()->GetType(address_def->type_id()); if (address_type->AsSampledImage() != nullptr) { @@ -235,12 +244,12 @@ Instruction* Instruction::GetBaseAddress() const { bool done = false; while (!done) { switch (base_inst->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: - case SpvOpImageTexelPointer: - case SpvOpCopyObject: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpCopyObject: // All of these instructions have the base pointer use a base pointer // in in-operand 0. base = base_inst->GetSingleWordInOperand(0); @@ -255,20 +264,20 @@ Instruction* Instruction::GetBaseAddress() const { } bool Instruction::IsReadOnlyPointer() const { - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) return IsReadOnlyPointerShaders(); else return IsReadOnlyPointerKernel(); } bool Instruction::IsVulkanStorageImage() const { - if (opcode() != SpvOpTypePointer) { + if (opcode() != spv::Op::OpTypePointer) { return false; } - uint32_t storage_class = - GetSingleWordInOperand(kPointerTypeStorageClassIndex); - if (storage_class != SpvStorageClassUniformConstant) { + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::UniformConstant) { return false; } @@ -276,17 +285,18 @@ bool Instruction::IsVulkanStorageImage() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == SpvOpTypeArray || - base_type->opcode() == SpvOpTypeRuntimeArray) { + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != SpvOpTypeImage) { + if (base_type->opcode() != spv::Op::OpTypeImage) { return false; } - if (base_type->GetSingleWordInOperand(kTypeImageDimIndex) == SpvDimBuffer) { + if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) == + spv::Dim::Buffer) { return false; } @@ -296,13 +306,13 @@ bool Instruction::IsVulkanStorageImage() const { } bool Instruction::IsVulkanSampledImage() const { - if (opcode() != SpvOpTypePointer) { + if (opcode() != spv::Op::OpTypePointer) { return false; } - uint32_t storage_class = - GetSingleWordInOperand(kPointerTypeStorageClassIndex); - if (storage_class != SpvStorageClassUniformConstant) { + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::UniformConstant) { return false; } @@ -310,17 +320,18 @@ bool Instruction::IsVulkanSampledImage() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == SpvOpTypeArray || - base_type->opcode() == SpvOpTypeRuntimeArray) { + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != SpvOpTypeImage) { + if (base_type->opcode() != spv::Op::OpTypeImage) { return false; } - if (base_type->GetSingleWordInOperand(kTypeImageDimIndex) == SpvDimBuffer) { + if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) == + spv::Dim::Buffer) { return false; } @@ -330,13 +341,13 @@ bool Instruction::IsVulkanSampledImage() const { } bool Instruction::IsVulkanStorageTexelBuffer() const { - if (opcode() != SpvOpTypePointer) { + if (opcode() != spv::Op::OpTypePointer) { return false; } - uint32_t storage_class = - GetSingleWordInOperand(kPointerTypeStorageClassIndex); - if (storage_class != SpvStorageClassUniformConstant) { + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::UniformConstant) { return false; } @@ -344,17 +355,18 @@ bool Instruction::IsVulkanStorageTexelBuffer() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == SpvOpTypeArray || - base_type->opcode() == SpvOpTypeRuntimeArray) { + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != SpvOpTypeImage) { + if (base_type->opcode() != spv::Op::OpTypeImage) { return false; } - if (base_type->GetSingleWordInOperand(kTypeImageDimIndex) != SpvDimBuffer) { + if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) != + spv::Dim::Buffer) { return false; } @@ -366,7 +378,7 @@ bool Instruction::IsVulkanStorageTexelBuffer() const { bool Instruction::IsVulkanStorageBuffer() const { // Is there a difference between a "Storage buffer" and a "dynamic storage // buffer" in SPIR-V and do we care about the difference? - if (opcode() != SpvOpTypePointer) { + if (opcode() != spv::Op::OpTypePointer) { return false; } @@ -374,28 +386,28 @@ bool Instruction::IsVulkanStorageBuffer() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == SpvOpTypeArray || - base_type->opcode() == SpvOpTypeRuntimeArray) { + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != SpvOpTypeStruct) { + if (base_type->opcode() != spv::Op::OpTypeStruct) { return false; } - uint32_t storage_class = - GetSingleWordInOperand(kPointerTypeStorageClassIndex); - if (storage_class == SpvStorageClassUniform) { + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class == spv::StorageClass::Uniform) { bool is_buffer_block = false; context()->get_decoration_mgr()->ForEachDecoration( - base_type->result_id(), SpvDecorationBufferBlock, + base_type->result_id(), uint32_t(spv::Decoration::BufferBlock), [&is_buffer_block](const Instruction&) { is_buffer_block = true; }); return is_buffer_block; - } else if (storage_class == SpvStorageClassStorageBuffer) { + } else if (storage_class == spv::StorageClass::StorageBuffer) { bool is_block = false; context()->get_decoration_mgr()->ForEachDecoration( - base_type->result_id(), SpvDecorationBlock, + base_type->result_id(), uint32_t(spv::Decoration::Block), [&is_block](const Instruction&) { is_block = true; }); return is_block; } @@ -403,13 +415,14 @@ bool Instruction::IsVulkanStorageBuffer() const { } bool Instruction::IsVulkanStorageBufferVariable() const { - if (opcode() != SpvOpVariable) { + if (opcode() != spv::Op::OpVariable) { return false; } - uint32_t storage_class = GetSingleWordInOperand(kVariableStorageClassIndex); - if (storage_class == SpvStorageClassStorageBuffer || - storage_class == SpvStorageClassUniform) { + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kVariableStorageClassIndex)); + if (storage_class == spv::StorageClass::StorageBuffer || + storage_class == spv::StorageClass::Uniform) { Instruction* var_type = context()->get_def_use_mgr()->GetDef(type_id()); return var_type != nullptr && var_type->IsVulkanStorageBuffer(); } @@ -418,13 +431,13 @@ bool Instruction::IsVulkanStorageBufferVariable() const { } bool Instruction::IsVulkanUniformBuffer() const { - if (opcode() != SpvOpTypePointer) { + if (opcode() != spv::Op::OpTypePointer) { return false; } - uint32_t storage_class = - GetSingleWordInOperand(kPointerTypeStorageClassIndex); - if (storage_class != SpvStorageClassUniform) { + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::Uniform) { return false; } @@ -432,19 +445,19 @@ bool Instruction::IsVulkanUniformBuffer() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == SpvOpTypeArray || - base_type->opcode() == SpvOpTypeRuntimeArray) { + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != SpvOpTypeStruct) { + if (base_type->opcode() != spv::Op::OpTypeStruct) { return false; } bool is_block = false; context()->get_decoration_mgr()->ForEachDecoration( - base_type->result_id(), SpvDecorationBlock, + base_type->result_id(), uint32_t(spv::Decoration::Block), [&is_block](const Instruction&) { is_block = true; }); return is_block; } @@ -455,27 +468,27 @@ bool Instruction::IsReadOnlyPointerShaders() const { } Instruction* type_def = context()->get_def_use_mgr()->GetDef(type_id()); - if (type_def->opcode() != SpvOpTypePointer) { + if (type_def->opcode() != spv::Op::OpTypePointer) { return false; } - uint32_t storage_class = - type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex); + spv::StorageClass storage_class = spv::StorageClass( + type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex)); switch (storage_class) { - case SpvStorageClassUniformConstant: + case spv::StorageClass::UniformConstant: if (!type_def->IsVulkanStorageImage() && !type_def->IsVulkanStorageTexelBuffer()) { return true; } break; - case SpvStorageClassUniform: + case spv::StorageClass::Uniform: if (!type_def->IsVulkanStorageBuffer()) { return true; } break; - case SpvStorageClassPushConstant: - case SpvStorageClassInput: + case spv::StorageClass::PushConstant: + case spv::StorageClass::Input: return true; default: break; @@ -483,7 +496,7 @@ bool Instruction::IsReadOnlyPointerShaders() const { bool is_nonwritable = false; context()->get_decoration_mgr()->ForEachDecoration( - result_id(), SpvDecorationNonWritable, + result_id(), uint32_t(spv::Decoration::NonWritable), [&is_nonwritable](const Instruction&) { is_nonwritable = true; }); return is_nonwritable; } @@ -494,14 +507,14 @@ bool Instruction::IsReadOnlyPointerKernel() const { } Instruction* type_def = context()->get_def_use_mgr()->GetDef(type_id()); - if (type_def->opcode() != SpvOpTypePointer) { + if (type_def->opcode() != spv::Op::OpTypePointer) { return false; } - uint32_t storage_class = - type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex); + spv::StorageClass storage_class = spv::StorageClass( + type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex)); - return storage_class == SpvStorageClassUniformConstant; + return storage_class == spv::StorageClass::UniformConstant; } void Instruction::UpdateLexicalScope(uint32_t scope) { @@ -564,13 +577,13 @@ bool Instruction::IsDebugLineInst() const { bool Instruction::IsLineInst() const { return IsLine() || IsNoLine(); } bool Instruction::IsLine() const { - if (opcode() == SpvOpLine) return true; + if (opcode() == spv::Op::OpLine) return true; NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); return ext_opt == NonSemanticShaderDebugInfo100DebugLine; } bool Instruction::IsNoLine() const { - if (opcode() == SpvOpNoLine) return true; + if (opcode() == spv::Op::OpNoLine) return true; NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); return ext_opt == NonSemanticShaderDebugInfo100DebugNoLine; } @@ -597,33 +610,35 @@ bool Instruction::IsValidBasePointer() const { } Instruction* type = context()->get_def_use_mgr()->GetDef(tid); - if (type->opcode() != SpvOpTypePointer) { + if (type->opcode() != spv::Op::OpTypePointer) { return false; } auto feature_mgr = context()->get_feature_mgr(); - if (feature_mgr->HasCapability(SpvCapabilityAddresses)) { + if (feature_mgr->HasCapability(spv::Capability::Addresses)) { // TODO: The rules here could be more restrictive. return true; } - if (opcode() == SpvOpVariable || opcode() == SpvOpFunctionParameter) { + if (opcode() == spv::Op::OpVariable || + opcode() == spv::Op::OpFunctionParameter) { return true; } // With variable pointers, there are more valid base pointer objects. // Variable pointers implicitly declares Variable pointers storage buffer. - SpvStorageClass storage_class = - static_cast(type->GetSingleWordInOperand(0)); - if ((feature_mgr->HasCapability(SpvCapabilityVariablePointersStorageBuffer) && - storage_class == SpvStorageClassStorageBuffer) || - (feature_mgr->HasCapability(SpvCapabilityVariablePointers) && - storage_class == SpvStorageClassWorkgroup)) { + spv::StorageClass storage_class = + static_cast(type->GetSingleWordInOperand(0)); + if ((feature_mgr->HasCapability( + spv::Capability::VariablePointersStorageBuffer) && + storage_class == spv::StorageClass::StorageBuffer) || + (feature_mgr->HasCapability(spv::Capability::VariablePointers) && + storage_class == spv::StorageClass::Workgroup)) { switch (opcode()) { - case SpvOpPhi: - case SpvOpSelect: - case SpvOpFunctionCall: - case SpvOpConstantNull: + case spv::Op::OpPhi: + case spv::Op::OpSelect: + case spv::Op::OpFunctionCall: + case spv::Op::OpConstantNull: return true; default: break; @@ -641,7 +656,7 @@ bool Instruction::IsValidBasePointer() const { } OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const { - if (opcode() != SpvOpExtInst) { + if (opcode() != spv::Op::OpExtInst) { return OpenCLDebugInfo100InstructionsMax; } @@ -660,7 +675,7 @@ OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const { NonSemanticShaderDebugInfo100Instructions Instruction::GetShader100DebugOpcode() const { - if (opcode() != SpvOpExtInst) { + if (opcode() != spv::Op::OpExtInst) { return NonSemanticShaderDebugInfo100InstructionsMax; } @@ -682,7 +697,7 @@ NonSemanticShaderDebugInfo100Instructions Instruction::GetShader100DebugOpcode() } CommonDebugInfoInstructions Instruction::GetCommonDebugOpcode() const { - if (opcode() != SpvOpExtInst) { + if (opcode() != spv::Op::OpExtInst) { return CommonDebugInfoInstructionsMax; } @@ -712,25 +727,25 @@ bool Instruction::IsValidBaseImage() const { } Instruction* type = context()->get_def_use_mgr()->GetDef(tid); - return (type->opcode() == SpvOpTypeImage || - type->opcode() == SpvOpTypeSampledImage); + return (type->opcode() == spv::Op::OpTypeImage || + type->opcode() == spv::Op::OpTypeSampledImage); } bool Instruction::IsOpaqueType() const { - if (opcode() == SpvOpTypeStruct) { + if (opcode() == spv::Op::OpTypeStruct) { bool is_opaque = false; ForEachInOperand([&is_opaque, this](const uint32_t* op_id) { Instruction* type_inst = context()->get_def_use_mgr()->GetDef(*op_id); is_opaque |= type_inst->IsOpaqueType(); }); return is_opaque; - } else if (opcode() == SpvOpTypeArray) { + } else if (opcode() == spv::Op::OpTypeArray) { uint32_t sub_type_id = GetSingleWordInOperand(0); Instruction* sub_type_inst = context()->get_def_use_mgr()->GetDef(sub_type_id); return sub_type_inst->IsOpaqueType(); } else { - return opcode() == SpvOpTypeRuntimeArray || + return opcode() == spv::Op::OpTypeRuntimeArray || spvOpcodeIsBaseOpaqueType(opcode()); } } @@ -765,22 +780,23 @@ bool Instruction::IsFoldableByFoldScalar() const { bool Instruction::IsFloatingPointFoldingAllowed() const { // TODO: Add the rules for kernels. For now it will be pessimistic. // For now, do not support capabilities introduced by SPV_KHR_float_controls. - if (!context_->get_feature_mgr()->HasCapability(SpvCapabilityShader) || - context_->get_feature_mgr()->HasCapability(SpvCapabilityDenormPreserve) || + if (!context_->get_feature_mgr()->HasCapability(spv::Capability::Shader) || context_->get_feature_mgr()->HasCapability( - SpvCapabilityDenormFlushToZero) || + spv::Capability::DenormPreserve) || context_->get_feature_mgr()->HasCapability( - SpvCapabilitySignedZeroInfNanPreserve) || + spv::Capability::DenormFlushToZero) || context_->get_feature_mgr()->HasCapability( - SpvCapabilityRoundingModeRTZ) || + spv::Capability::SignedZeroInfNanPreserve) || context_->get_feature_mgr()->HasCapability( - SpvCapabilityRoundingModeRTE)) { + spv::Capability::RoundingModeRTZ) || + context_->get_feature_mgr()->HasCapability( + spv::Capability::RoundingModeRTE)) { return false; } bool is_nocontract = false; context_->get_decoration_mgr()->WhileEachDecoration( - result_id(), SpvDecorationNoContraction, + result_id(), uint32_t(spv::Decoration::NoContraction), [&is_nocontract](const Instruction&) { is_nocontract = true; return false; @@ -816,101 +832,101 @@ void Instruction::Dump() const { bool Instruction::IsOpcodeCodeMotionSafe() const { switch (opcode_) { - case SpvOpNop: - case SpvOpUndef: - case SpvOpLoad: - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpArrayLength: - case SpvOpVectorExtractDynamic: - case SpvOpVectorInsertDynamic: - case SpvOpVectorShuffle: - case SpvOpCompositeConstruct: - case SpvOpCompositeExtract: - case SpvOpCompositeInsert: - case SpvOpCopyObject: - case SpvOpTranspose: - case SpvOpConvertFToU: - case SpvOpConvertFToS: - case SpvOpConvertSToF: - case SpvOpConvertUToF: - case SpvOpUConvert: - case SpvOpSConvert: - case SpvOpFConvert: - case SpvOpQuantizeToF16: - case SpvOpBitcast: - case SpvOpSNegate: - case SpvOpFNegate: - case SpvOpIAdd: - case SpvOpFAdd: - case SpvOpISub: - case SpvOpFSub: - case SpvOpIMul: - case SpvOpFMul: - case SpvOpUDiv: - case SpvOpSDiv: - case SpvOpFDiv: - case SpvOpUMod: - case SpvOpSRem: - case SpvOpSMod: - case SpvOpFRem: - case SpvOpFMod: - case SpvOpVectorTimesScalar: - case SpvOpMatrixTimesScalar: - case SpvOpVectorTimesMatrix: - case SpvOpMatrixTimesVector: - case SpvOpMatrixTimesMatrix: - case SpvOpOuterProduct: - case SpvOpDot: - case SpvOpIAddCarry: - case SpvOpISubBorrow: - case SpvOpUMulExtended: - case SpvOpSMulExtended: - case SpvOpAny: - case SpvOpAll: - case SpvOpIsNan: - case SpvOpIsInf: - case SpvOpLogicalEqual: - case SpvOpLogicalNotEqual: - case SpvOpLogicalOr: - case SpvOpLogicalAnd: - case SpvOpLogicalNot: - case SpvOpSelect: - case SpvOpIEqual: - case SpvOpINotEqual: - case SpvOpUGreaterThan: - case SpvOpSGreaterThan: - case SpvOpUGreaterThanEqual: - case SpvOpSGreaterThanEqual: - case SpvOpULessThan: - case SpvOpSLessThan: - case SpvOpULessThanEqual: - case SpvOpSLessThanEqual: - case SpvOpFOrdEqual: - case SpvOpFUnordEqual: - case SpvOpFOrdNotEqual: - case SpvOpFUnordNotEqual: - case SpvOpFOrdLessThan: - case SpvOpFUnordLessThan: - case SpvOpFOrdGreaterThan: - case SpvOpFUnordGreaterThan: - case SpvOpFOrdLessThanEqual: - case SpvOpFUnordLessThanEqual: - case SpvOpFOrdGreaterThanEqual: - case SpvOpFUnordGreaterThanEqual: - case SpvOpShiftRightLogical: - case SpvOpShiftRightArithmetic: - case SpvOpShiftLeftLogical: - case SpvOpBitwiseOr: - case SpvOpBitwiseXor: - case SpvOpBitwiseAnd: - case SpvOpNot: - case SpvOpBitFieldInsert: - case SpvOpBitFieldSExtract: - case SpvOpBitFieldUExtract: - case SpvOpBitReverse: - case SpvOpBitCount: - case SpvOpSizeOf: + case spv::Op::OpNop: + case spv::Op::OpUndef: + case spv::Op::OpLoad: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpArrayLength: + case spv::Op::OpVectorExtractDynamic: + case spv::Op::OpVectorInsertDynamic: + case spv::Op::OpVectorShuffle: + case spv::Op::OpCompositeConstruct: + case spv::Op::OpCompositeExtract: + case spv::Op::OpCompositeInsert: + case spv::Op::OpCopyObject: + case spv::Op::OpTranspose: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: + case spv::Op::OpUConvert: + case spv::Op::OpSConvert: + case spv::Op::OpFConvert: + case spv::Op::OpQuantizeToF16: + case spv::Op::OpBitcast: + case spv::Op::OpSNegate: + case spv::Op::OpFNegate: + case spv::Op::OpIAdd: + case spv::Op::OpFAdd: + case spv::Op::OpISub: + case spv::Op::OpFSub: + case spv::Op::OpIMul: + case spv::Op::OpFMul: + case spv::Op::OpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpFDiv: + case spv::Op::OpUMod: + case spv::Op::OpSRem: + case spv::Op::OpSMod: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpMatrixTimesScalar: + case spv::Op::OpVectorTimesMatrix: + case spv::Op::OpMatrixTimesVector: + case spv::Op::OpMatrixTimesMatrix: + case spv::Op::OpOuterProduct: + case spv::Op::OpDot: + case spv::Op::OpIAddCarry: + case spv::Op::OpISubBorrow: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: + case spv::Op::OpAny: + case spv::Op::OpAll: + case spv::Op::OpIsNan: + case spv::Op::OpIsInf: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: + case spv::Op::OpLogicalNot: + case spv::Op::OpSelect: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: + case spv::Op::OpBitFieldInsert: + case spv::Op::OpBitFieldSExtract: + case spv::Op::OpBitFieldUExtract: + case spv::Op::OpBitReverse: + case spv::Op::OpBitCount: + case spv::Op::OpSizeOf: return true; default: return false; @@ -922,7 +938,7 @@ bool Instruction::IsScalarizable() const { return true; } - if (opcode() == SpvOpExtInst) { + if (opcode() == spv::Op::OpExtInst) { uint32_t instSetId = context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); @@ -997,16 +1013,16 @@ bool Instruction::IsOpcodeSafeToDelete() const { } switch (opcode()) { - case SpvOpDPdx: - case SpvOpDPdy: - case SpvOpFwidth: - case SpvOpDPdxFine: - case SpvOpDPdyFine: - case SpvOpFwidthFine: - case SpvOpDPdxCoarse: - case SpvOpDPdyCoarse: - case SpvOpFwidthCoarse: - case SpvOpImageQueryLod: + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpFwidth: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpFwidthFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidthCoarse: + case spv::Op::OpImageQueryLod: return true; default: return false; @@ -1015,7 +1031,7 @@ bool Instruction::IsOpcodeSafeToDelete() const { bool Instruction::IsNonSemanticInstruction() const { if (!HasResultId()) return false; - if (opcode() != SpvOpExtInst) return false; + if (opcode() != spv::Op::OpExtInst) return false; auto import_inst = context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(0)); @@ -1035,7 +1051,7 @@ void DebugScope::ToBinary(uint32_t type_id, uint32_t result_id, num_words = kDebugScopeNumWordsWithoutInlinedAt; } std::vector operands = { - (num_words << 16) | static_cast(SpvOpExtInst), + (num_words << 16) | static_cast(spv::Op::OpExtInst), type_id, result_id, ext_set, diff --git a/3rdparty/spirv-tools/source/opt/instruction.h b/3rdparty/spirv-tools/source/opt/instruction.h index e79c6289b..22736bff8 100644 --- a/3rdparty/spirv-tools/source/opt/instruction.h +++ b/3rdparty/spirv-tools/source/opt/instruction.h @@ -36,8 +36,8 @@ #include "source/util/string_utils.h" #include "spirv-tools/libspirv.h" -const uint32_t kNoDebugScope = 0; -const uint32_t kNoInlinedAt = 0; +constexpr uint32_t kNoDebugScope = 0; +constexpr uint32_t kNoInlinedAt = 0; namespace spvtools { namespace opt { @@ -190,7 +190,7 @@ class Instruction : public utils::IntrusiveNodeBase { Instruction() : utils::IntrusiveNodeBase(), context_(nullptr), - opcode_(SpvOpNop), + opcode_(spv::Op::OpNop), has_type_id_(false), has_result_id_(false), unique_id_(0), @@ -200,7 +200,7 @@ class Instruction : public utils::IntrusiveNodeBase { Instruction(IRContext*); // Creates an instruction with the given opcode |op| and no additional logical // operands. - Instruction(IRContext*, SpvOp); + Instruction(IRContext*, spv::Op); // Creates an instruction using the given spv_parsed_instruction_t |inst|. All // the data inside |inst| will be copied and owned in this instance. And keep // record of line-related debug instructions |dbg_line| ahead of this @@ -213,7 +213,7 @@ class Instruction : public utils::IntrusiveNodeBase { // Creates an instruction with the given opcode |op|, type id: |ty_id|, // result id: |res_id| and input operands: |in_operands|. - Instruction(IRContext* c, SpvOp op, uint32_t ty_id, uint32_t res_id, + Instruction(IRContext* c, spv::Op op, uint32_t ty_id, uint32_t res_id, const OperandList& in_operands); // TODO: I will want to remove these, but will first have to remove the use of @@ -235,12 +235,12 @@ class Instruction : public utils::IntrusiveNodeBase { IRContext* context() const { return context_; } - SpvOp opcode() const { return opcode_; } + spv::Op opcode() const { return opcode_; } // Sets the opcode of this instruction to a specific opcode. Note this may // invalidate the instruction. // TODO(qining): Remove this function when instruction building and insertion // is well implemented. - void SetOpcode(SpvOp op) { opcode_ = op; } + void SetOpcode(spv::Op op) { opcode_ = op; } uint32_t type_id() const { return has_type_id_ ? GetSingleWordOperand(0) : 0; } @@ -625,7 +625,7 @@ class Instruction : public utils::IntrusiveNodeBase { bool IsValidBaseImage() const; IRContext* context_; // IR Context - SpvOp opcode_; // Opcode + spv::Op opcode_; // Opcode bool has_type_id_; // True if the instruction has a type id bool has_result_id_; // True if the instruction has a result id uint32_t unique_id_; // Unique instruction id @@ -732,12 +732,12 @@ inline void Instruction::SetResultType(uint32_t ty_id) { } inline bool Instruction::IsNop() const { - return opcode_ == SpvOpNop && !has_type_id_ && !has_result_id_ && + return opcode_ == spv::Op::OpNop && !has_type_id_ && !has_result_id_ && operands_.empty(); } inline void Instruction::ToNop() { - opcode_ = SpvOpNop; + opcode_ = spv::Op::OpNop; has_type_id_ = false; has_result_id_ = false; operands_.clear(); @@ -879,12 +879,12 @@ inline void Instruction::ForEachInOperand( inline bool Instruction::HasLabels() const { switch (opcode_) { - case SpvOpSelectionMerge: - case SpvOpBranch: - case SpvOpLoopMerge: - case SpvOpBranchConditional: - case SpvOpSwitch: - case SpvOpPhi: + case spv::Op::OpSelectionMerge: + case spv::Op::OpBranch: + case spv::Op::OpLoopMerge: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: + case spv::Op::OpPhi: return true; break; default: diff --git a/3rdparty/spirv-tools/source/opt/instrument_pass.cpp b/3rdparty/spirv-tools/source/opt/instrument_pass.cpp index d143d5959..441d943f7 100644 --- a/3rdparty/spirv-tools/source/opt/instrument_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/instrument_pass.cpp @@ -19,20 +19,15 @@ #include "source/cfa.h" #include "source/spirv_constant.h" -namespace { - -// Common Parameter Positions -static const int kInstCommonParamInstIdx = 0; -static const int kInstCommonParamCnt = 1; - -// Indices of operands in SPIR-V instructions -static const int kEntryPointExecutionModelInIdx = 0; -static const int kEntryPointFunctionIdInIdx = 1; - -} // anonymous namespace - namespace spvtools { namespace opt { +namespace { +// Common Parameter Positions +constexpr int kInstCommonParamInstIdx = 0; +constexpr int kInstCommonParamCnt = 1; +// Indices of operands in SPIR-V instructions +constexpr int kEntryPointFunctionIdInIdx = 1; +} // namespace void InstrumentPass::MovePreludeCode( BasicBlock::iterator ref_inst_itr, @@ -83,7 +78,7 @@ void InstrumentPass::MovePostludeCode( std::unique_ptr InstrumentPass::NewLabel(uint32_t label_id) { std::unique_ptr newLabel( - new Instruction(context(), SpvOpLabel, 0, label_id, {})); + new Instruction(context(), spv::Op::OpLabel, 0, label_id, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*newLabel); return newLabel; } @@ -91,7 +86,7 @@ std::unique_ptr InstrumentPass::NewLabel(uint32_t label_id) { std::unique_ptr InstrumentPass::NewName( uint32_t id, const std::string& name_str) { std::unique_ptr new_name(new Instruction( - context(), SpvOpName, 0, 0, + context(), spv::Op::OpName, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {id}}, {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}})); @@ -124,7 +119,7 @@ std::unique_ptr InstrumentPass::NewGlobalName( std::unique_ptr InstrumentPass::NewMemberName( uint32_t id, uint32_t member_index, const std::string& name_str) { std::unique_ptr new_name(new Instruction( - context(), SpvOpMemberName, 0, 0, + context(), spv::Op::OpMemberName, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {id}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}}, @@ -145,10 +140,10 @@ uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id, analysis::Type* val_32b_reg_ty = type_mgr->GetRegisteredType(&val_32b_ty); uint32_t val_32b_reg_ty_id = type_mgr->GetId(val_32b_reg_ty); if (is_signed) - return builder->AddUnaryOp(val_32b_reg_ty_id, SpvOpSConvert, val_id) + return builder->AddUnaryOp(val_32b_reg_ty_id, spv::Op::OpSConvert, val_id) ->result_id(); else - return builder->AddUnaryOp(val_32b_reg_ty_id, SpvOpUConvert, val_id) + return builder->AddUnaryOp(val_32b_reg_ty_id, spv::Op::OpUConvert, val_id) ->result_id(); } @@ -161,7 +156,7 @@ uint32_t InstrumentPass::GenUintCastCode(uint32_t val_id, uint32_t val_ty_id = get_def_use_mgr()->GetDef(val_32b_id)->type_id(); analysis::Integer* val_ty = type_mgr->GetType(val_ty_id)->AsInteger(); if (!val_ty->IsSigned()) return val_32b_id; - return builder->AddUnaryOp(GetUintId(), SpvOpBitcast, val_32b_id) + return builder->AddUnaryOp(GetUintId(), spv::Op::OpBitcast, val_32b_id) ->result_id(); } @@ -173,15 +168,16 @@ void InstrumentPass::GenDebugOutputFieldCode(uint32_t base_offset_id, uint32_t val_id = GenUintCastCode(field_value_id, builder); // Store value Instruction* data_idx_inst = - builder->AddBinaryOp(GetUintId(), SpvOpIAdd, base_offset_id, + builder->AddBinaryOp(GetUintId(), spv::Op::OpIAdd, base_offset_id, builder->GetUintConstantId(field_offset)); uint32_t buf_id = GetOutputBufferId(); uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); Instruction* achain_inst = - builder->AddTernaryOp(buf_uint_ptr_id, SpvOpAccessChain, buf_id, + builder->AddTernaryOp(buf_uint_ptr_id, spv::Op::OpAccessChain, buf_id, builder->GetUintConstantId(kDebugOutputDataOffset), data_idx_inst->result_id()); - (void)builder->AddBinaryOp(0, SpvOpStore, achain_inst->result_id(), val_id); + (void)builder->AddBinaryOp(0, spv::Op::OpStore, achain_inst->result_id(), + val_id); } void InstrumentPass::GenCommonStreamWriteCode(uint32_t record_sz, @@ -207,7 +203,7 @@ void InstrumentPass::GenFragCoordEltDebugOutputCode( uint32_t base_offset_id, uint32_t uint_frag_coord_id, uint32_t element, InstructionBuilder* builder) { Instruction* element_val_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, uint_frag_coord_id, element); + GetUintId(), spv::Op::OpCompositeExtract, uint_frag_coord_id, element); GenDebugOutputFieldCode(base_offset_id, kInstFragOutFragCoordX + element, element_val_inst->result_id(), builder); } @@ -216,7 +212,8 @@ uint32_t InstrumentPass::GenVarLoad(uint32_t var_id, InstructionBuilder* builder) { Instruction* var_inst = get_def_use_mgr()->GetDef(var_id); uint32_t type_id = GetPointeeTypeId(var_inst); - Instruction* load_inst = builder->AddUnaryOp(type_id, SpvOpLoad, var_id); + Instruction* load_inst = + builder->AddUnaryOp(type_id, spv::Op::OpLoad, var_id); return load_inst->result_id(); } @@ -233,31 +230,31 @@ void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx, uint32_t base_offset_id, InstructionBuilder* builder) { // TODO(greg-lunarg): Add support for all stages - switch (stage_idx) { - case SpvExecutionModelVertex: { + switch (spv::ExecutionModel(stage_idx)) { + case spv::ExecutionModel::Vertex: { // Load and store VertexId and InstanceId GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInVertexIndex), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::VertexIndex)), kInstVertOutVertexIndex, base_offset_id, builder); - GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInInstanceIndex), - kInstVertOutInstanceIndex, base_offset_id, builder); + GenBuiltinOutputCode(context()->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::InstanceIndex)), + kInstVertOutInstanceIndex, base_offset_id, builder); } break; - case SpvExecutionModelGLCompute: - case SpvExecutionModelTaskNV: - case SpvExecutionModelMeshNV: - case SpvExecutionModelTaskEXT: - case SpvExecutionModelMeshEXT: { + case spv::ExecutionModel::GLCompute: + case spv::ExecutionModel::TaskNV: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::TaskEXT: + case spv::ExecutionModel::MeshEXT: { // Load and store GlobalInvocationId. - uint32_t load_id = GenVarLoad( - context()->GetBuiltinInputVarId(SpvBuiltInGlobalInvocationId), - builder); + uint32_t load_id = GenVarLoad(context()->GetBuiltinInputVarId(uint32_t( + spv::BuiltIn::GlobalInvocationId)), + builder); Instruction* x_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, load_id, 0); + GetUintId(), spv::Op::OpCompositeExtract, load_id, 0); Instruction* y_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, load_id, 1); + GetUintId(), spv::Op::OpCompositeExtract, load_id, 1); Instruction* z_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, load_id, 2); + GetUintId(), spv::Op::OpCompositeExtract, load_id, 2); GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdX, x_inst->result_id(), builder); GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdY, @@ -265,69 +262,71 @@ void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx, GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdZ, z_inst->result_id(), builder); } break; - case SpvExecutionModelGeometry: { + case spv::ExecutionModel::Geometry: { // Load and store PrimitiveId and InvocationId. GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInPrimitiveId), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), kInstGeomOutPrimitiveId, base_offset_id, builder); GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInInvocationId), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)), kInstGeomOutInvocationId, base_offset_id, builder); } break; - case SpvExecutionModelTessellationControl: { + case spv::ExecutionModel::TessellationControl: { // Load and store InvocationId and PrimitiveId GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInInvocationId), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)), kInstTessCtlOutInvocationId, base_offset_id, builder); GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInPrimitiveId), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), kInstTessCtlOutPrimitiveId, base_offset_id, builder); } break; - case SpvExecutionModelTessellationEvaluation: { + case spv::ExecutionModel::TessellationEvaluation: { // Load and store PrimitiveId and TessCoord.uv GenBuiltinOutputCode( - context()->GetBuiltinInputVarId(SpvBuiltInPrimitiveId), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), kInstTessEvalOutPrimitiveId, base_offset_id, builder); uint32_t load_id = GenVarLoad( - context()->GetBuiltinInputVarId(SpvBuiltInTessCoord), builder); + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::TessCoord)), + builder); Instruction* uvec3_cast_inst = - builder->AddUnaryOp(GetVec3UintId(), SpvOpBitcast, load_id); + builder->AddUnaryOp(GetVec3UintId(), spv::Op::OpBitcast, load_id); uint32_t uvec3_cast_id = uvec3_cast_inst->result_id(); Instruction* u_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, uvec3_cast_id, 0); + GetUintId(), spv::Op::OpCompositeExtract, uvec3_cast_id, 0); Instruction* v_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, uvec3_cast_id, 1); + GetUintId(), spv::Op::OpCompositeExtract, uvec3_cast_id, 1); GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordU, u_inst->result_id(), builder); GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordV, v_inst->result_id(), builder); } break; - case SpvExecutionModelFragment: { + case spv::ExecutionModel::Fragment: { // Load FragCoord and convert to Uint Instruction* frag_coord_inst = builder->AddUnaryOp( - GetVec4FloatId(), SpvOpLoad, - context()->GetBuiltinInputVarId(SpvBuiltInFragCoord)); + GetVec4FloatId(), spv::Op::OpLoad, + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::FragCoord))); Instruction* uint_frag_coord_inst = builder->AddUnaryOp( - GetVec4UintId(), SpvOpBitcast, frag_coord_inst->result_id()); + GetVec4UintId(), spv::Op::OpBitcast, frag_coord_inst->result_id()); for (uint32_t u = 0; u < 2u; ++u) GenFragCoordEltDebugOutputCode( base_offset_id, uint_frag_coord_inst->result_id(), u, builder); } break; - case SpvExecutionModelRayGenerationNV: - case SpvExecutionModelIntersectionNV: - case SpvExecutionModelAnyHitNV: - case SpvExecutionModelClosestHitNV: - case SpvExecutionModelMissNV: - case SpvExecutionModelCallableNV: { + case spv::ExecutionModel::RayGenerationNV: + case spv::ExecutionModel::IntersectionNV: + case spv::ExecutionModel::AnyHitNV: + case spv::ExecutionModel::ClosestHitNV: + case spv::ExecutionModel::MissNV: + case spv::ExecutionModel::CallableNV: { // Load and store LaunchIdNV. uint32_t launch_id = GenVarLoad( - context()->GetBuiltinInputVarId(SpvBuiltInLaunchIdNV), builder); + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::LaunchIdNV)), + builder); Instruction* x_launch_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, launch_id, 0); + GetUintId(), spv::Op::OpCompositeExtract, launch_id, 0); Instruction* y_launch_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, launch_id, 1); + GetUintId(), spv::Op::OpCompositeExtract, launch_id, 1); Instruction* z_launch_inst = builder->AddIdLiteralOp( - GetUintId(), SpvOpCompositeExtract, launch_id, 2); + GetUintId(), spv::Op::OpCompositeExtract, launch_id, 2); GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdX, x_launch_inst->result_id(), builder); GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdY, @@ -349,7 +348,7 @@ void InstrumentPass::GenDebugStreamWrite( std::vector args = {output_func_id, builder->GetUintConstantId(instruction_idx)}; (void)args.insert(args.end(), validation_ids.begin(), validation_ids.end()); - (void)builder->AddNaryOp(GetVoidId(), SpvOpFunctionCall, args); + (void)builder->AddNaryOp(GetVoidId(), spv::Op::OpFunctionCall, args); } bool InstrumentPass::AllConstant(const std::vector& ids) { @@ -385,13 +384,15 @@ uint32_t InstrumentPass::GenDebugDirectRead( builder.SetInsertPoint(insert_before); } uint32_t res_id = - builder.AddNaryOp(GetUintId(), SpvOpFunctionCall, args)->result_id(); + builder.AddNaryOp(GetUintId(), spv::Op::OpFunctionCall, args) + ->result_id(); if (insert_in_first_block) call2id_[args] = res_id; return res_id; } bool InstrumentPass::IsSameBlockOp(const Instruction* inst) const { - return inst->opcode() == SpvOpSampledImage || inst->opcode() == SpvOpImage; + return inst->opcode() == spv::Op::OpSampledImage || + inst->opcode() == spv::Op::OpImage; } void InstrumentPass::CloneSameBlockOps( @@ -457,7 +458,7 @@ void InstrumentPass::UpdateSucceedingPhis( uint32_t InstrumentPass::GetOutputBufferPtrId() { if (output_buffer_ptr_id_ == 0) { output_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType( - GetUintId(), SpvStorageClassStorageBuffer); + GetUintId(), spv::StorageClass::StorageBuffer); } return output_buffer_ptr_id_; } @@ -470,7 +471,7 @@ uint32_t InstrumentPass::GetInputBufferTypeId() { uint32_t InstrumentPass::GetInputBufferPtrId() { if (input_buffer_ptr_id_ == 0) { input_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType( - GetInputBufferTypeId(), SpvStorageClassStorageBuffer); + GetInputBufferTypeId(), spv::StorageClass::StorageBuffer); } return input_buffer_ptr_id_; } @@ -519,8 +520,8 @@ analysis::Type* InstrumentPass::GetUintXRuntimeArrayType( // invalidated after this pass. assert(context()->get_def_use_mgr()->NumUses(uint_arr_ty_id) == 0 && "used RuntimeArray type returned"); - deco_mgr->AddDecorationVal(uint_arr_ty_id, SpvDecorationArrayStride, - width / 8u); + deco_mgr->AddDecorationVal( + uint_arr_ty_id, uint32_t(spv::Decoration::ArrayStride), width / 8u); } return *rarr_ty; } @@ -548,7 +549,7 @@ uint32_t InstrumentPass::GetOutputBufferId() { analysis::Type* reg_uint_rarr_ty = GetUintRuntimeArrayType(32); analysis::Integer uint_ty(32, false); analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); - analysis::Struct buf_ty({reg_uint_ty, reg_uint_rarr_ty}); + analysis::Struct buf_ty({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty}); analysis::Type* reg_buf_ty = type_mgr->GetRegisteredType(&buf_ty); uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty); // By the Vulkan spec, a pre-existing struct containing a RuntimeArray @@ -559,26 +560,30 @@ uint32_t InstrumentPass::GetOutputBufferId() { // invalidated after this pass. assert(context()->get_def_use_mgr()->NumUses(obufTyId) == 0 && "used struct type returned"); - deco_mgr->AddDecoration(obufTyId, SpvDecorationBlock); + deco_mgr->AddDecoration(obufTyId, uint32_t(spv::Decoration::Block)); + deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputFlagsOffset, + uint32_t(spv::Decoration::Offset), 0); deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputSizeOffset, - SpvDecorationOffset, 0); + uint32_t(spv::Decoration::Offset), 4); deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputDataOffset, - SpvDecorationOffset, 4); + uint32_t(spv::Decoration::Offset), 8); uint32_t obufTyPtrId_ = - type_mgr->FindPointerToType(obufTyId, SpvStorageClassStorageBuffer); + type_mgr->FindPointerToType(obufTyId, spv::StorageClass::StorageBuffer); output_buffer_id_ = TakeNextId(); std::unique_ptr newVarOp(new Instruction( - context(), SpvOpVariable, obufTyPtrId_, output_buffer_id_, + context(), spv::Op::OpVariable, obufTyPtrId_, output_buffer_id_, {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvStorageClassStorageBuffer}}})); + {uint32_t(spv::StorageClass::StorageBuffer)}}})); context()->AddGlobalValue(std::move(newVarOp)); context()->AddDebug2Inst(NewGlobalName(obufTyId, "OutputBuffer")); - context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "written_count")); - context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "data")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "flags")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "written_count")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 2, "data")); context()->AddDebug2Inst(NewGlobalName(output_buffer_id_, "output_buffer")); - deco_mgr->AddDecorationVal(output_buffer_id_, SpvDecorationDescriptorSet, - desc_set_); - deco_mgr->AddDecorationVal(output_buffer_id_, SpvDecorationBinding, + deco_mgr->AddDecorationVal( + output_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_); + deco_mgr->AddDecorationVal(output_buffer_id_, + uint32_t(spv::Decoration::Binding), GetOutputBufferBinding()); AddStorageBufferExt(); if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { @@ -610,22 +615,24 @@ uint32_t InstrumentPass::GetInputBufferId() { // invalidated after this pass. assert(context()->get_def_use_mgr()->NumUses(ibufTyId) == 0 && "used struct type returned"); - deco_mgr->AddDecoration(ibufTyId, SpvDecorationBlock); - deco_mgr->AddMemberDecoration(ibufTyId, 0, SpvDecorationOffset, 0); + deco_mgr->AddDecoration(ibufTyId, uint32_t(spv::Decoration::Block)); + deco_mgr->AddMemberDecoration(ibufTyId, 0, + uint32_t(spv::Decoration::Offset), 0); uint32_t ibufTyPtrId_ = - type_mgr->FindPointerToType(ibufTyId, SpvStorageClassStorageBuffer); + type_mgr->FindPointerToType(ibufTyId, spv::StorageClass::StorageBuffer); input_buffer_id_ = TakeNextId(); std::unique_ptr newVarOp(new Instruction( - context(), SpvOpVariable, ibufTyPtrId_, input_buffer_id_, + context(), spv::Op::OpVariable, ibufTyPtrId_, input_buffer_id_, {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvStorageClassStorageBuffer}}})); + {uint32_t(spv::StorageClass::StorageBuffer)}}})); context()->AddGlobalValue(std::move(newVarOp)); context()->AddDebug2Inst(NewGlobalName(ibufTyId, "InputBuffer")); context()->AddDebug2Inst(NewMemberName(ibufTyId, 0, "data")); context()->AddDebug2Inst(NewGlobalName(input_buffer_id_, "input_buffer")); - deco_mgr->AddDecorationVal(input_buffer_id_, SpvDecorationDescriptorSet, - desc_set_); - deco_mgr->AddDecorationVal(input_buffer_id_, SpvDecorationBinding, + deco_mgr->AddDecorationVal( + input_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_); + deco_mgr->AddDecorationVal(input_buffer_id_, + uint32_t(spv::Decoration::Binding), GetInputBufferBinding()); AddStorageBufferExt(); if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { @@ -746,10 +753,10 @@ uint32_t InstrumentPass::GetStreamWriteFunctionId(uint32_t stage_idx, analysis::Function func_ty(type_mgr->GetType(GetVoidId()), param_types); analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty); std::unique_ptr func_inst( - new Instruction(get_module()->context(), SpvOpFunction, GetVoidId(), - param2output_func_id_[param_cnt], + new Instruction(get_module()->context(), spv::Op::OpFunction, + GetVoidId(), param2output_func_id_[param_cnt], {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvFunctionControlMaskNone}}, + {uint32_t(spv::FunctionControlMask::MaskNone)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_mgr->GetTypeInstruction(reg_func_ty)}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); @@ -761,7 +768,7 @@ uint32_t InstrumentPass::GetStreamWriteFunctionId(uint32_t stage_idx, uint32_t pid = TakeNextId(); param_vec.push_back(pid); std::unique_ptr param_inst( - new Instruction(get_module()->context(), SpvOpFunctionParameter, + new Instruction(get_module()->context(), spv::Op::OpFunctionParameter, GetUintId(), pid, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); output_func->AddParameter(std::move(param_inst)); @@ -780,37 +787,39 @@ uint32_t InstrumentPass::GetStreamWriteFunctionId(uint32_t stage_idx, uint32_t buf_id = GetOutputBufferId(); uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); Instruction* obuf_curr_sz_ac_inst = - builder.AddBinaryOp(buf_uint_ptr_id, SpvOpAccessChain, buf_id, + builder.AddBinaryOp(buf_uint_ptr_id, spv::Op::OpAccessChain, buf_id, builder.GetUintConstantId(kDebugOutputSizeOffset)); // Fetch the current debug buffer written size atomically, adding the // size of the record to be written. uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz); - uint32_t mask_none_id = builder.GetUintConstantId(SpvMemoryAccessMaskNone); - uint32_t scope_invok_id = builder.GetUintConstantId(SpvScopeInvocation); + uint32_t mask_none_id = + builder.GetUintConstantId(uint32_t(spv::MemoryAccessMask::MaskNone)); + uint32_t scope_invok_id = + builder.GetUintConstantId(uint32_t(spv::Scope::Invocation)); Instruction* obuf_curr_sz_inst = builder.AddQuadOp( - GetUintId(), SpvOpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(), + GetUintId(), spv::Op::OpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(), scope_invok_id, mask_none_id, obuf_record_sz_id); uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id(); // Compute new written size Instruction* obuf_new_sz_inst = - builder.AddBinaryOp(GetUintId(), SpvOpIAdd, obuf_curr_sz_id, + builder.AddBinaryOp(GetUintId(), spv::Op::OpIAdd, obuf_curr_sz_id, builder.GetUintConstantId(obuf_record_sz)); // Fetch the data bound Instruction* obuf_bnd_inst = - builder.AddIdLiteralOp(GetUintId(), SpvOpArrayLength, + builder.AddIdLiteralOp(GetUintId(), spv::Op::OpArrayLength, GetOutputBufferId(), kDebugOutputDataOffset); // Test that new written size is less than or equal to debug output // data bound Instruction* obuf_safe_inst = builder.AddBinaryOp( - GetBoolId(), SpvOpULessThanEqual, obuf_new_sz_inst->result_id(), + GetBoolId(), spv::Op::OpULessThanEqual, obuf_new_sz_inst->result_id(), obuf_bnd_inst->result_id()); uint32_t merge_blk_id = TakeNextId(); uint32_t write_blk_id = TakeNextId(); std::unique_ptr merge_label(NewLabel(merge_blk_id)); std::unique_ptr write_label(NewLabel(write_blk_id)); - (void)builder.AddConditionalBranch(obuf_safe_inst->result_id(), - write_blk_id, merge_blk_id, merge_blk_id, - SpvSelectionControlMaskNone); + (void)builder.AddConditionalBranch( + obuf_safe_inst->result_id(), write_blk_id, merge_blk_id, merge_blk_id, + uint32_t(spv::SelectionControlMask::MaskNone)); // Close safety test block and gen write block output_func->AddBasicBlock(std::move(new_blk_ptr)); new_blk_ptr = MakeUnique(std::move(write_label)); @@ -830,10 +839,10 @@ uint32_t InstrumentPass::GetStreamWriteFunctionId(uint32_t stage_idx, new_blk_ptr = MakeUnique(std::move(merge_label)); builder.SetInsertPoint(&*new_blk_ptr); // Close merge block and function and add function to module - (void)builder.AddNullaryOp(0, SpvOpReturn); + (void)builder.AddNullaryOp(0, spv::Op::OpReturn); output_func->AddBasicBlock(std::move(new_blk_ptr)); - std::unique_ptr func_end_inst( - new Instruction(get_module()->context(), SpvOpFunctionEnd, 0, 0, {})); + std::unique_ptr func_end_inst(new Instruction( + get_module()->context(), spv::Op::OpFunctionEnd, 0, 0, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst); output_func->SetFunctionEnd(std::move(func_end_inst)); context()->AddFunction(std::move(output_func)); @@ -860,9 +869,9 @@ uint32_t InstrumentPass::GetDirectReadFunctionId(uint32_t param_cnt) { analysis::Function func_ty(type_mgr->GetType(ibuf_type_id), param_types); analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty); std::unique_ptr func_inst(new Instruction( - get_module()->context(), SpvOpFunction, ibuf_type_id, func_id, + get_module()->context(), spv::Op::OpFunction, ibuf_type_id, func_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvFunctionControlMaskNone}}, + {uint32_t(spv::FunctionControlMask::MaskNone)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_mgr->GetTypeInstruction(reg_func_ty)}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); @@ -873,8 +882,9 @@ uint32_t InstrumentPass::GetDirectReadFunctionId(uint32_t param_cnt) { for (uint32_t c = 0; c < param_cnt; ++c) { uint32_t pid = TakeNextId(); param_vec.push_back(pid); - std::unique_ptr param_inst(new Instruction( - get_module()->context(), SpvOpFunctionParameter, GetUintId(), pid, {})); + std::unique_ptr param_inst( + new Instruction(get_module()->context(), spv::Op::OpFunctionParameter, + GetUintId(), pid, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); input_func->AddParameter(std::move(param_inst)); } @@ -899,27 +909,27 @@ uint32_t InstrumentPass::GetDirectReadFunctionId(uint32_t param_cnt) { } else { if (ibuf_type_id != GetUintId()) { Instruction* ucvt_inst = - builder.AddUnaryOp(GetUintId(), SpvOpUConvert, last_value_id); + builder.AddUnaryOp(GetUintId(), spv::Op::OpUConvert, last_value_id); last_value_id = ucvt_inst->result_id(); } Instruction* offset_inst = builder.AddBinaryOp( - GetUintId(), SpvOpIAdd, last_value_id, param_vec[p]); + GetUintId(), spv::Op::OpIAdd, last_value_id, param_vec[p]); offset_id = offset_inst->result_id(); } Instruction* ac_inst = builder.AddTernaryOp( - buf_ptr_id, SpvOpAccessChain, buf_id, + buf_ptr_id, spv::Op::OpAccessChain, buf_id, builder.GetUintConstantId(kDebugInputDataOffset), offset_id); Instruction* load_inst = - builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, ac_inst->result_id()); + builder.AddUnaryOp(ibuf_type_id, spv::Op::OpLoad, ac_inst->result_id()); last_value_id = load_inst->result_id(); } (void)builder.AddInstruction(MakeUnique( - context(), SpvOpReturnValue, 0, 0, + context(), spv::Op::OpReturnValue, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {last_value_id}}})); // Close block and function and add function to module input_func->AddBasicBlock(std::move(new_blk_ptr)); - std::unique_ptr func_end_inst( - new Instruction(get_module()->context(), SpvOpFunctionEnd, 0, 0, {})); + std::unique_ptr func_end_inst(new Instruction( + get_module()->context(), spv::Op::OpFunctionEnd, 0, 0, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst); input_func->SetFunctionEnd(std::move(func_end_inst)); context()->AddFunction(std::move(input_func)); @@ -970,7 +980,7 @@ bool InstrumentPass::InstrumentFunction(Function* func, uint32_t stage_idx, // block. This will allow function calls to be inserted into the first // block without interfering with the instrumentation algorithm. if (opt_direct_reads_ && !first_block_split) { - if (ii->opcode() != SpvOpVariable) { + if (ii->opcode() != spv::Op::OpVariable) { SplitBlock(ii, bi, &new_blks); first_block_split = true; } @@ -1001,7 +1011,9 @@ bool InstrumentPass::InstrumentFunction(Function* func, uint32_t stage_idx, // Restart instrumenting at beginning of last new block, // but skip over any new phi or copy instruction. ii = bi->begin(); - if (ii->opcode() == SpvOpPhi || ii->opcode() == SpvOpCopyObject) ++ii; + if (ii->opcode() == spv::Op::OpPhi || + ii->opcode() == spv::Op::OpCopyObject) + ++ii; new_blks.clear(); } } @@ -1039,35 +1051,24 @@ bool InstrumentPass::InstProcessEntryPointCallTree(InstProcessFunction& pfn) { // one model per module. In such cases we will need // to clone any functions which are in the call trees of entrypoints // with differing execution models. - uint32_t ecnt = 0; - uint32_t stage = SpvExecutionModelMax; - for (auto& e : get_module()->entry_points()) { - if (ecnt == 0) - stage = e.GetSingleWordInOperand(kEntryPointExecutionModelInIdx); - else if (e.GetSingleWordInOperand(kEntryPointExecutionModelInIdx) != - stage) { - if (consumer()) { - std::string message = "Mixed stage shader module not supported"; - consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); - } - return false; - } - ++ecnt; - } + spv::ExecutionModel stage = context()->GetStage(); // Check for supported stages - if (stage != SpvExecutionModelVertex && stage != SpvExecutionModelFragment && - stage != SpvExecutionModelGeometry && - stage != SpvExecutionModelGLCompute && - stage != SpvExecutionModelTessellationControl && - stage != SpvExecutionModelTessellationEvaluation && - stage != SpvExecutionModelTaskNV && stage != SpvExecutionModelMeshNV && - stage != SpvExecutionModelRayGenerationNV && - stage != SpvExecutionModelIntersectionNV && - stage != SpvExecutionModelAnyHitNV && - stage != SpvExecutionModelClosestHitNV && - stage != SpvExecutionModelMissNV && - stage != SpvExecutionModelCallableNV && - stage != SpvExecutionModelTaskEXT && stage != SpvExecutionModelMeshEXT) { + if (stage != spv::ExecutionModel::Vertex && + stage != spv::ExecutionModel::Fragment && + stage != spv::ExecutionModel::Geometry && + stage != spv::ExecutionModel::GLCompute && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::TaskNV && + stage != spv::ExecutionModel::MeshNV && + stage != spv::ExecutionModel::RayGenerationNV && + stage != spv::ExecutionModel::IntersectionNV && + stage != spv::ExecutionModel::AnyHitNV && + stage != spv::ExecutionModel::ClosestHitNV && + stage != spv::ExecutionModel::MissNV && + stage != spv::ExecutionModel::CallableNV && + stage != spv::ExecutionModel::TaskEXT && + stage != spv::ExecutionModel::MeshEXT) { if (consumer()) { std::string message = "Stage not supported by instrumentation"; consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); @@ -1079,7 +1080,7 @@ bool InstrumentPass::InstProcessEntryPointCallTree(InstProcessFunction& pfn) { for (auto& e : get_module()->entry_points()) { roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx)); } - bool modified = InstProcessCallTreeFromRoots(pfn, &roots, stage); + bool modified = InstProcessCallTreeFromRoots(pfn, &roots, uint32_t(stage)); return modified; } diff --git a/3rdparty/spirv-tools/source/opt/instrument_pass.h b/3rdparty/spirv-tools/source/opt/instrument_pass.h index 215b02635..e98ba88e4 100644 --- a/3rdparty/spirv-tools/source/opt/instrument_pass.h +++ b/3rdparty/spirv-tools/source/opt/instrument_pass.h @@ -55,13 +55,14 @@ namespace spvtools { namespace opt { - +namespace { // Validation Ids // These are used to identify the general validation being done and map to // its output buffers. -static const uint32_t kInstValidationIdBindless = 0; -static const uint32_t kInstValidationIdBuffAddr = 1; -static const uint32_t kInstValidationIdDebugPrintf = 2; +constexpr uint32_t kInstValidationIdBindless = 0; +constexpr uint32_t kInstValidationIdBuffAddr = 1; +constexpr uint32_t kInstValidationIdDebugPrintf = 2; +} // namespace class InstrumentPass : public Pass { using cbb_ptr = const BasicBlock*; diff --git a/3rdparty/spirv-tools/source/opt/interface_var_sroa.cpp b/3rdparty/spirv-tools/source/opt/interface_var_sroa.cpp index 1b2cb3636..08477cbdd 100644 --- a/3rdparty/spirv-tools/source/opt/interface_var_sroa.cpp +++ b/3rdparty/spirv-tools/source/opt/interface_var_sroa.cpp @@ -23,29 +23,28 @@ #include "source/opt/type_manager.h" #include "source/util/make_unique.h" -const static uint32_t kOpDecorateDecorationInOperandIndex = 1; -const static uint32_t kOpDecorateLiteralInOperandIndex = 2; -const static uint32_t kOpEntryPointInOperandInterface = 3; -const static uint32_t kOpVariableStorageClassInOperandIndex = 0; -const static uint32_t kOpTypeArrayElemTypeInOperandIndex = 0; -const static uint32_t kOpTypeArrayLengthInOperandIndex = 1; -const static uint32_t kOpTypeMatrixColCountInOperandIndex = 1; -const static uint32_t kOpTypeMatrixColTypeInOperandIndex = 0; -const static uint32_t kOpTypePtrTypeInOperandIndex = 1; -const static uint32_t kOpConstantValueInOperandIndex = 0; - namespace spvtools { namespace opt { namespace { +constexpr uint32_t kOpDecorateDecorationInOperandIndex = 1; +constexpr uint32_t kOpDecorateLiteralInOperandIndex = 2; +constexpr uint32_t kOpEntryPointInOperandInterface = 3; +constexpr uint32_t kOpVariableStorageClassInOperandIndex = 0; +constexpr uint32_t kOpTypeArrayElemTypeInOperandIndex = 0; +constexpr uint32_t kOpTypeArrayLengthInOperandIndex = 1; +constexpr uint32_t kOpTypeMatrixColCountInOperandIndex = 1; +constexpr uint32_t kOpTypeMatrixColTypeInOperandIndex = 0; +constexpr uint32_t kOpTypePtrTypeInOperandIndex = 1; +constexpr uint32_t kOpConstantValueInOperandIndex = 0; // Get the length of the OpTypeArray |array_type|. uint32_t GetArrayLength(analysis::DefUseManager* def_use_mgr, Instruction* array_type) { - assert(array_type->opcode() == SpvOpTypeArray); + assert(array_type->opcode() == spv::Op::OpTypeArray); uint32_t const_int_id = array_type->GetSingleWordInOperand(kOpTypeArrayLengthInOperandIndex); Instruction* array_length_inst = def_use_mgr->GetDef(const_int_id); - assert(array_length_inst->opcode() == SpvOpConstant); + assert(array_length_inst->opcode() == spv::Op::OpConstant); return array_length_inst->GetSingleWordInOperand( kOpConstantValueInOperandIndex); } @@ -53,7 +52,7 @@ uint32_t GetArrayLength(analysis::DefUseManager* def_use_mgr, // Get the element type instruction of the OpTypeArray |array_type|. Instruction* GetArrayElementType(analysis::DefUseManager* def_use_mgr, Instruction* array_type) { - assert(array_type->opcode() == SpvOpTypeArray); + assert(array_type->opcode() == spv::Op::OpTypeArray); uint32_t elem_type_id = array_type->GetSingleWordInOperand(kOpTypeArrayElemTypeInOperandIndex); return def_use_mgr->GetDef(elem_type_id); @@ -62,7 +61,7 @@ Instruction* GetArrayElementType(analysis::DefUseManager* def_use_mgr, // Get the column type instruction of the OpTypeMatrix |matrix_type|. Instruction* GetMatrixColumnType(analysis::DefUseManager* def_use_mgr, Instruction* matrix_type) { - assert(matrix_type->opcode() == SpvOpTypeMatrix); + assert(matrix_type->opcode() == spv::Op::OpTypeMatrix); uint32_t column_type_id = matrix_type->GetSingleWordInOperand(kOpTypeMatrixColTypeInOperandIndex); return def_use_mgr->GetDef(column_type_id); @@ -77,14 +76,14 @@ uint32_t GetComponentTypeOfArrayMatrix(analysis::DefUseManager* def_use_mgr, if (depth_to_component == 0) return type_id; Instruction* type_inst = def_use_mgr->GetDef(type_id); - if (type_inst->opcode() == SpvOpTypeArray) { + if (type_inst->opcode() == spv::Op::OpTypeArray) { uint32_t elem_type_id = type_inst->GetSingleWordInOperand(kOpTypeArrayElemTypeInOperandIndex); return GetComponentTypeOfArrayMatrix(def_use_mgr, elem_type_id, depth_to_component - 1); } - assert(type_inst->opcode() == SpvOpTypeMatrix); + assert(type_inst->opcode() == spv::Op::OpTypeMatrix); uint32_t column_type_id = type_inst->GetSingleWordInOperand(kOpTypeMatrixColTypeInOperandIndex); return GetComponentTypeOfArrayMatrix(def_use_mgr, column_type_id, @@ -94,7 +93,7 @@ uint32_t GetComponentTypeOfArrayMatrix(analysis::DefUseManager* def_use_mgr, // Creates an OpDecorate instruction whose Target is |var_id| and Decoration is // |decoration|. Adds |literal| as an extra operand of the instruction. void CreateDecoration(analysis::DecorationManager* decoration_mgr, - uint32_t var_id, SpvDecoration decoration, + uint32_t var_id, spv::Decoration decoration, uint32_t literal) { std::vector operands({ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, @@ -102,7 +101,7 @@ void CreateDecoration(analysis::DecorationManager* decoration_mgr, {static_cast(decoration)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {literal}}, }); - decoration_mgr->AddDecoration(SpvOpDecorate, std::move(operands)); + decoration_mgr->AddDecoration(spv::Op::OpDecorate, std::move(operands)); } // Replaces load instructions with composite construct instructions in all the @@ -128,8 +127,8 @@ void ReplaceLoadWithCompositeConstruct( } // Returns the storage class of the instruction |var|. -SpvStorageClass GetStorageClass(Instruction* var) { - return static_cast( +spv::StorageClass GetStorageClass(Instruction* var) { + return static_cast( var->GetSingleWordInOperand(kOpVariableStorageClassInOperandIndex)); } @@ -137,16 +136,17 @@ SpvStorageClass GetStorageClass(Instruction* var) { bool InterfaceVariableScalarReplacement::HasExtraArrayness( Instruction& entry_point, Instruction* var) { - SpvExecutionModel execution_model = - static_cast(entry_point.GetSingleWordInOperand(0)); - if (execution_model != SpvExecutionModelTessellationEvaluation && - execution_model != SpvExecutionModelTessellationControl) { + spv::ExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); + if (execution_model != spv::ExecutionModel::TessellationEvaluation && + execution_model != spv::ExecutionModel::TessellationControl) { return false; } - if (!context()->get_decoration_mgr()->HasDecoration(var->result_id(), - SpvDecorationPatch)) { - if (execution_model == SpvExecutionModelTessellationControl) return true; - return GetStorageClass(var) != SpvStorageClassOutput; + if (!context()->get_decoration_mgr()->HasDecoration( + var->result_id(), uint32_t(spv::Decoration::Patch))) { + if (execution_model == spv::ExecutionModel::TessellationControl) + return true; + return GetStorageClass(var) != spv::StorageClass::Output; } return false; } @@ -163,7 +163,7 @@ bool InterfaceVariableScalarReplacement:: bool InterfaceVariableScalarReplacement::GetVariableLocation( Instruction* var, uint32_t* location) { return !context()->get_decoration_mgr()->WhileEachDecoration( - var->result_id(), SpvDecorationLocation, + var->result_id(), uint32_t(spv::Decoration::Location), [location](const Instruction& inst) { *location = inst.GetSingleWordInOperand(kOpDecorateLiteralInOperandIndex); @@ -174,7 +174,7 @@ bool InterfaceVariableScalarReplacement::GetVariableLocation( bool InterfaceVariableScalarReplacement::GetVariableComponent( Instruction* var, uint32_t* component) { return !context()->get_decoration_mgr()->WhileEachDecoration( - var->result_id(), SpvDecorationComponent, + var->result_id(), uint32_t(spv::Decoration::Component), [component](const Instruction& inst) { *component = inst.GetSingleWordInOperand(kOpDecorateLiteralInOperandIndex); @@ -190,11 +190,11 @@ InterfaceVariableScalarReplacement::CollectInterfaceVariables( i < entry_point.NumInOperands(); ++i) { Instruction* interface_var = context()->get_def_use_mgr()->GetDef( entry_point.GetSingleWordInOperand(i)); - assert(interface_var->opcode() == SpvOpVariable); + assert(interface_var->opcode() == spv::Op::OpVariable); - SpvStorageClass storage_class = GetStorageClass(interface_var); - if (storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + spv::StorageClass storage_class = GetStorageClass(interface_var); + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { continue; } @@ -205,10 +205,10 @@ InterfaceVariableScalarReplacement::CollectInterfaceVariables( void InterfaceVariableScalarReplacement::KillInstructionAndUsers( Instruction* inst) { - if (inst->opcode() == SpvOpEntryPoint) { + if (inst->opcode() == spv::Op::OpEntryPoint) { return; } - if (inst->opcode() != SpvOpAccessChain) { + if (inst->opcode() != spv::Op::OpAccessChain) { context()->KillInst(inst); return; } @@ -232,10 +232,10 @@ void InterfaceVariableScalarReplacement::KillLocationAndComponentDecorations( uint32_t var_id) { context()->get_decoration_mgr()->RemoveDecorationsFrom( var_id, [](const Instruction& inst) { - uint32_t decoration = - inst.GetSingleWordInOperand(kOpDecorateDecorationInOperandIndex); - return decoration == SpvDecorationLocation || - decoration == SpvDecorationComponent; + spv::Decoration decoration = spv::Decoration( + inst.GetSingleWordInOperand(kOpDecorateDecorationInOperandIndex)); + return decoration == spv::Decoration::Location || + decoration == spv::Decoration::Component; }); } @@ -307,9 +307,9 @@ void InterfaceVariableScalarReplacement::AddLocationAndComponentDecorations( if (!vars.HasMultipleComponents()) { uint32_t var_id = vars.GetComponentVariable()->result_id(); CreateDecoration(context()->get_decoration_mgr(), var_id, - SpvDecorationLocation, *location); + spv::Decoration::Location, *location); CreateDecoration(context()->get_decoration_mgr(), var_id, - SpvDecorationComponent, component); + spv::Decoration::Component, component); ++(*location); return; } @@ -389,15 +389,15 @@ bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( std::unordered_map* loads_to_component_values, std::unordered_map* loads_for_access_chain_to_component_values) { - SpvOp opcode = interface_var_user->opcode(); - if (opcode == SpvOpStore) { + spv::Op opcode = interface_var_user->opcode(); + if (opcode == spv::Op::OpStore) { uint32_t value_id = interface_var_user->GetSingleWordInOperand(1); StoreComponentOfValueToScalarVar(value_id, interface_var_component_indices, scalar_var, extra_array_index, interface_var_user); return true; } - if (opcode == SpvOpLoad) { + if (opcode == spv::Op::OpLoad) { Instruction* scalar_load = LoadScalarVar(scalar_var, extra_array_index, interface_var_user); loads_to_component_values->insert({interface_var_user, scalar_load}); @@ -408,25 +408,25 @@ bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( // them only for the first element of the extra array. if (extra_array_index && *extra_array_index != 0) return true; - if (opcode == SpvOpDecorateId || opcode == SpvOpDecorateString || - opcode == SpvOpDecorate) { + if (opcode == spv::Op::OpDecorateId || opcode == spv::Op::OpDecorateString || + opcode == spv::Op::OpDecorate) { CloneAnnotationForVariable(interface_var_user, scalar_var->result_id()); return true; } - if (opcode == SpvOpName) { + if (opcode == spv::Op::OpName) { std::unique_ptr new_inst(interface_var_user->Clone(context())); new_inst->SetInOperand(0, {scalar_var->result_id()}); context()->AddDebug2Inst(std::move(new_inst)); return true; } - if (opcode == SpvOpEntryPoint) { + if (opcode == spv::Op::OpEntryPoint) { return ReplaceInterfaceVarInEntryPoint(interface_var, interface_var_user, scalar_var->result_id()); } - if (opcode == SpvOpAccessChain) { + if (opcode == spv::Op::OpAccessChain) { ReplaceAccessChainWith(interface_var_user, interface_var_component_indices, scalar_var, loads_for_access_chain_to_component_values); @@ -445,8 +445,8 @@ bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( void InterfaceVariableScalarReplacement::UseBaseAccessChainForAccessChain( Instruction* access_chain, Instruction* base_access_chain) { - assert(base_access_chain->opcode() == SpvOpAccessChain && - access_chain->opcode() == SpvOpAccessChain && + assert(base_access_chain->opcode() == spv::Op::OpAccessChain && + access_chain->opcode() == spv::Op::OpAccessChain && access_chain->GetSingleWordInOperand(0) == base_access_chain->result_id()); Instruction::OperandList new_operands; @@ -470,10 +470,10 @@ Instruction* InterfaceVariableScalarReplacement::CreateAccessChainToVar( uint32_t ptr_type_id = GetPointerType(*component_type_id, GetStorageClass(var)); - std::unique_ptr new_access_chain( - new Instruction(context(), SpvOpAccessChain, ptr_type_id, TakeNextId(), - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); + std::unique_ptr new_access_chain(new Instruction( + context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); for (uint32_t index_id : index_ids) { new_access_chain->AddOperand({SPV_OPERAND_TYPE_ID, {index_id}}); } @@ -489,13 +489,13 @@ Instruction* InterfaceVariableScalarReplacement::CreateAccessChainWithIndex( Instruction* insert_before) { uint32_t ptr_type_id = GetPointerType(component_type_id, GetStorageClass(var)); - uint32_t index_id = context()->get_constant_mgr()->GetUIntConst(index); - std::unique_ptr new_access_chain( - new Instruction(context(), SpvOpAccessChain, ptr_type_id, TakeNextId(), - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {var->result_id()}}, - {SPV_OPERAND_TYPE_ID, {index_id}}, - })); + uint32_t index_id = context()->get_constant_mgr()->GetUIntConstId(index); + std::unique_ptr new_access_chain(new Instruction( + context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_ID, {index_id}}, + })); Instruction* inst = new_access_chain.get(); context()->get_def_use_mgr()->AnalyzeInstDefUse(inst); insert_before->InsertBefore(std::move(new_access_chain)); @@ -519,20 +519,20 @@ void InterfaceVariableScalarReplacement::ReplaceAccessChainWith( [this, access_chain, &indexes, &interface_var_component_indices, scalar_var, loads_to_component_values](Instruction* user) { switch (user->opcode()) { - case SpvOpAccessChain: { + case spv::Op::OpAccessChain: { UseBaseAccessChainForAccessChain(user, access_chain); ReplaceAccessChainWith(user, interface_var_component_indices, scalar_var, loads_to_component_values); return; } - case SpvOpStore: { + case spv::Op::OpStore: { uint32_t value_id = user->GetSingleWordInOperand(1); StoreComponentOfValueToAccessChainToScalarVar( value_id, interface_var_component_indices, scalar_var, indexes, user); return; } - case SpvOpLoad: { + case spv::Op::OpLoad: { Instruction* value = LoadAccessChainToVar(scalar_var, indexes, user); loads_to_component_values->insert({user, value}); @@ -546,9 +546,9 @@ void InterfaceVariableScalarReplacement::ReplaceAccessChainWith( void InterfaceVariableScalarReplacement::CloneAnnotationForVariable( Instruction* annotation_inst, uint32_t var_id) { - assert(annotation_inst->opcode() == SpvOpDecorate || - annotation_inst->opcode() == SpvOpDecorateId || - annotation_inst->opcode() == SpvOpDecorateString); + assert(annotation_inst->opcode() == spv::Op::OpDecorate || + annotation_inst->opcode() == spv::Op::OpDecorateId || + annotation_inst->opcode() == spv::Op::OpDecorateString); std::unique_ptr new_inst(annotation_inst->Clone(context())); new_inst->SetInOperand(0, {var_id}); context()->AddAnnotationInst(std::move(new_inst)); @@ -593,13 +593,13 @@ bool InterfaceVariableScalarReplacement::ReplaceInterfaceVarInEntryPoint( uint32_t InterfaceVariableScalarReplacement::GetPointeeTypeIdOfVar( Instruction* var) { - assert(var->opcode() == SpvOpVariable); + assert(var->opcode() == spv::Op::OpVariable); uint32_t ptr_type_id = var->type_id(); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); Instruction* ptr_type_inst = def_use_mgr->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == SpvOpTypePointer && + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && "Variable must have a pointer type."); return ptr_type_inst->GetSingleWordInOperand(kOpTypePtrTypeInOperandIndex); } @@ -643,7 +643,7 @@ Instruction* InterfaceVariableScalarReplacement::LoadScalarVar( Instruction* InterfaceVariableScalarReplacement::CreateLoad( uint32_t type_id, Instruction* ptr, Instruction* insert_before) { std::unique_ptr load( - new Instruction(context(), SpvOpLoad, type_id, TakeNextId(), + new Instruction(context(), spv::Op::OpLoad, type_id, TakeNextId(), std::initializer_list{ {SPV_OPERAND_TYPE_ID, {ptr->result_id()}}})); Instruction* load_inst = load.get(); @@ -660,7 +660,7 @@ void InterfaceVariableScalarReplacement::StoreComponentOfValueTo( component_type_id, value_id, component_indices, extra_array_index)); std::unique_ptr new_store( - new Instruction(context(), SpvOpStore)); + new Instruction(context(), spv::Op::OpStore)); new_store->AddOperand({SPV_OPERAND_TYPE_ID, {ptr->result_id()}}); new_store->AddOperand( {SPV_OPERAND_TYPE_ID, {composite_extract->result_id()}}); @@ -678,7 +678,7 @@ Instruction* InterfaceVariableScalarReplacement::CreateCompositeExtract( const std::vector& indexes, const uint32_t* extra_first_index) { uint32_t component_id = TakeNextId(); Instruction* composite_extract = new Instruction( - context(), SpvOpCompositeExtract, type_id, component_id, + context(), spv::Op::OpCompositeExtract, type_id, component_id, std::initializer_list{{SPV_OPERAND_TYPE_ID, {composite_id}}}); if (extra_first_index) { composite_extract->AddOperand( @@ -731,8 +731,8 @@ InterfaceVariableScalarReplacement::CreateCompositeConstructForComponentOfLoad( depth_to_component); } uint32_t new_id = context()->TakeNextId(); - std::unique_ptr new_composite_construct( - new Instruction(context(), SpvOpCompositeConstruct, type_id, new_id, {})); + std::unique_ptr new_composite_construct(new Instruction( + context(), spv::Op::OpCompositeConstruct, type_id, new_id, {})); Instruction* composite_construct = new_composite_construct.get(); def_use_mgr->AnalyzeInstDefUse(composite_construct); @@ -781,7 +781,7 @@ uint32_t InterfaceVariableScalarReplacement::GetArrayType( uint32_t elem_type_id, uint32_t array_length) { analysis::Type* elem_type = context()->get_type_mgr()->GetType(elem_type_id); uint32_t array_length_id = - context()->get_constant_mgr()->GetUIntConst(array_length); + context()->get_constant_mgr()->GetUIntConstId(array_length); analysis::Array array_type( elem_type, analysis::Array::LengthInfo{array_length_id, {0, array_length}}); @@ -789,7 +789,7 @@ uint32_t InterfaceVariableScalarReplacement::GetArrayType( } uint32_t InterfaceVariableScalarReplacement::GetPointerType( - uint32_t type_id, SpvStorageClass storage_class) { + uint32_t type_id, spv::StorageClass storage_class) { analysis::Type* type = context()->get_type_mgr()->GetType(type_id); analysis::Pointer ptr_type(type, storage_class); return context()->get_type_mgr()->GetTypeInstruction(&ptr_type); @@ -797,9 +797,9 @@ uint32_t InterfaceVariableScalarReplacement::GetPointerType( InterfaceVariableScalarReplacement::NestedCompositeComponents InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForArray( - Instruction* interface_var_type, SpvStorageClass storage_class, + Instruction* interface_var_type, spv::StorageClass storage_class, uint32_t extra_array_length) { - assert(interface_var_type->opcode() == SpvOpTypeArray); + assert(interface_var_type->opcode() == spv::Op::OpTypeArray); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); uint32_t array_length = GetArrayLength(def_use_mgr, interface_var_type); @@ -818,9 +818,9 @@ InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForArray( InterfaceVariableScalarReplacement::NestedCompositeComponents InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForMatrix( - Instruction* interface_var_type, SpvStorageClass storage_class, + Instruction* interface_var_type, spv::StorageClass storage_class, uint32_t extra_array_length) { - assert(interface_var_type->opcode() == SpvOpTypeMatrix); + assert(interface_var_type->opcode() == spv::Op::OpTypeMatrix); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); uint32_t column_count = interface_var_type->GetSingleWordInOperand( @@ -841,16 +841,16 @@ InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForMatrix( InterfaceVariableScalarReplacement::NestedCompositeComponents InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForReplacement( - Instruction* interface_var_type, SpvStorageClass storage_class, + Instruction* interface_var_type, spv::StorageClass storage_class, uint32_t extra_array_length) { // Handle array case. - if (interface_var_type->opcode() == SpvOpTypeArray) { + if (interface_var_type->opcode() == spv::Op::OpTypeArray) { return CreateScalarInterfaceVarsForArray(interface_var_type, storage_class, extra_array_length); } // Handle matrix case. - if (interface_var_type->opcode() == SpvOpTypeMatrix) { + if (interface_var_type->opcode() == spv::Op::OpTypeMatrix) { return CreateScalarInterfaceVarsForMatrix(interface_var_type, storage_class, extra_array_length); } @@ -865,7 +865,7 @@ InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForReplacement( context()->get_type_mgr()->FindPointerToType(type_id, storage_class); uint32_t id = TakeNextId(); std::unique_ptr variable( - new Instruction(context(), SpvOpVariable, ptr_type_id, id, + new Instruction(context(), spv::Op::OpVariable, ptr_type_id, id, std::initializer_list{ {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(storage_class)}}})); @@ -948,8 +948,8 @@ InterfaceVariableScalarReplacement::ReplaceInterfaceVarsWithScalars( return Pass::Status::Failure; } - if (interface_var_type->opcode() != SpvOpTypeArray && - interface_var_type->opcode() != SpvOpTypeMatrix) { + if (interface_var_type->opcode() != spv::Op::OpTypeArray && + interface_var_type->opcode() != spv::Op::OpTypeMatrix) { continue; } diff --git a/3rdparty/spirv-tools/source/opt/interface_var_sroa.h b/3rdparty/spirv-tools/source/opt/interface_var_sroa.h index 23baad0ad..df7511bf3 100644 --- a/3rdparty/spirv-tools/source/opt/interface_var_sroa.h +++ b/3rdparty/spirv-tools/source/opt/interface_var_sroa.h @@ -115,7 +115,7 @@ class InterfaceVariableScalarReplacement : public Pass { // |extra_array_length| is not zero, adds the extra arrayness to the created // scalar variables. NestedCompositeComponents CreateScalarInterfaceVarsForReplacement( - Instruction* interface_var_type, SpvStorageClass storage_class, + Instruction* interface_var_type, spv::StorageClass storage_class, uint32_t extra_array_length); // Creates scalar variables with the storage classe |storage_class| to replace @@ -123,7 +123,7 @@ class InterfaceVariableScalarReplacement : public Pass { // If |extra_array_length| is not zero, adds the extra arrayness to all the // scalar variables. NestedCompositeComponents CreateScalarInterfaceVarsForArray( - Instruction* interface_var_type, SpvStorageClass storage_class, + Instruction* interface_var_type, spv::StorageClass storage_class, uint32_t extra_array_length); // Creates scalar variables with the storage classe |storage_class| to replace @@ -131,7 +131,7 @@ class InterfaceVariableScalarReplacement : public Pass { // with. If |extra_array_length| is not zero, adds the extra arrayness to all // the scalar variables. NestedCompositeComponents CreateScalarInterfaceVarsForMatrix( - Instruction* interface_var_type, SpvStorageClass storage_class, + Instruction* interface_var_type, spv::StorageClass storage_class, uint32_t extra_array_length); // Recursively adds Location and Component decorations to variables in @@ -345,7 +345,7 @@ class InterfaceVariableScalarReplacement : public Pass { // Returns the result id of OpTypePointer instrunction whose Type // operand is |type_id| and Storage Class operand is |storage_class|. - uint32_t GetPointerType(uint32_t type_id, SpvStorageClass storage_class); + uint32_t GetPointerType(uint32_t type_id, spv::StorageClass storage_class); // Kills an instrunction |inst| and its users. void KillInstructionAndUsers(Instruction* inst); diff --git a/3rdparty/spirv-tools/source/opt/interp_fixup_pass.cpp b/3rdparty/spirv-tools/source/opt/interp_fixup_pass.cpp index e8cdd99f1..bb6f6108c 100644 --- a/3rdparty/spirv-tools/source/opt/interp_fixup_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/interp_fixup_pass.cpp @@ -25,11 +25,10 @@ namespace spvtools { namespace opt { - namespace { // Input Operand Indices -static const int kSpvVariableStorageClassInIdx = 0; +constexpr int kSpvVariableStorageClassInIdx = 0; // Folding rule function which attempts to replace |op(OpLoad(a),...)| // by |op(a,...)|, where |op| is one of the GLSLstd450 InterpolateAt* @@ -45,12 +44,12 @@ bool ReplaceInternalInterpolate(IRContext* ctx, Instruction* inst, uint32_t op1_id = inst->GetSingleWordInOperand(2); Instruction* load_inst = ctx->get_def_use_mgr()->GetDef(op1_id); - if (load_inst->opcode() != SpvOpLoad) return false; + if (load_inst->opcode() != spv::Op::OpLoad) return false; Instruction* base_inst = load_inst->GetBaseAddress(); - USE_ASSERT(base_inst->opcode() == SpvOpVariable && - base_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx) == - SpvStorageClassInput && + USE_ASSERT(base_inst->opcode() == spv::Op::OpVariable && + spv::StorageClass(base_inst->GetSingleWordInOperand( + kSpvVariableStorageClassInIdx)) == spv::StorageClass::Input && "unexpected interpolant in InterpolateAt*"); uint32_t ptr_id = load_inst->GetSingleWordInOperand(0); diff --git a/3rdparty/spirv-tools/source/opt/ir_builder.h b/3rdparty/spirv-tools/source/opt/ir_builder.h index 9d4fa8fe3..93289a61a 100644 --- a/3rdparty/spirv-tools/source/opt/ir_builder.h +++ b/3rdparty/spirv-tools/source/opt/ir_builder.h @@ -30,7 +30,7 @@ namespace opt { // In SPIR-V, ids are encoded as uint16_t, this id is guaranteed to be always // invalid. -const uint32_t kInvalidId = std::numeric_limits::max(); +constexpr uint32_t kInvalidId = std::numeric_limits::max(); // Helper class to abstract instruction construction and insertion. // The instruction builder can preserve the following analyses (specified via @@ -58,7 +58,7 @@ class InstructionBuilder { : InstructionBuilder(context, parent_block, parent_block->end(), preserved_analyses) {} - Instruction* AddNullaryOp(uint32_t type_id, SpvOp opcode) { + Instruction* AddNullaryOp(uint32_t type_id, spv::Op opcode) { uint32_t result_id = 0; if (type_id != 0) { result_id = GetContext()->TakeNextId(); @@ -71,7 +71,7 @@ class InstructionBuilder { return AddInstruction(std::move(new_inst)); } - Instruction* AddUnaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1) { + Instruction* AddUnaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1) { uint32_t result_id = 0; if (type_id != 0) { result_id = GetContext()->TakeNextId(); @@ -85,7 +85,7 @@ class InstructionBuilder { return AddInstruction(std::move(newUnOp)); } - Instruction* AddBinaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, + Instruction* AddBinaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, uint32_t operand2) { uint32_t result_id = 0; if (type_id != 0) { @@ -95,13 +95,14 @@ class InstructionBuilder { } } std::unique_ptr newBinOp(new Instruction( - GetContext(), opcode, type_id, opcode == SpvOpStore ? 0 : result_id, + GetContext(), opcode, type_id, + opcode == spv::Op::OpStore ? 0 : result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}})); return AddInstruction(std::move(newBinOp)); } - Instruction* AddTernaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, + Instruction* AddTernaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, uint32_t operand2, uint32_t operand3) { uint32_t result_id = 0; if (type_id != 0) { @@ -118,7 +119,7 @@ class InstructionBuilder { return AddInstruction(std::move(newTernOp)); } - Instruction* AddQuadOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, + Instruction* AddQuadOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, uint32_t operand2, uint32_t operand3, uint32_t operand4) { uint32_t result_id = 0; @@ -137,7 +138,7 @@ class InstructionBuilder { return AddInstruction(std::move(newQuadOp)); } - Instruction* AddIdLiteralOp(uint32_t type_id, SpvOp opcode, uint32_t id, + Instruction* AddIdLiteralOp(uint32_t type_id, spv::Op opcode, uint32_t id, uint32_t uliteral) { uint32_t result_id = 0; if (type_id != 0) { @@ -157,7 +158,7 @@ class InstructionBuilder { // |typid| must be the id of the instruction's type. // |operands| must be a sequence of operand ids. // Use |result| for the result id if non-zero. - Instruction* AddNaryOp(uint32_t type_id, SpvOp opcode, + Instruction* AddNaryOp(uint32_t type_id, spv::Op opcode, const std::vector& operands, uint32_t result = 0) { std::vector ops; @@ -174,10 +175,10 @@ class InstructionBuilder { // Creates a new selection merge instruction. // The id |merge_id| is the merge basic block id. Instruction* AddSelectionMerge( - uint32_t merge_id, - uint32_t selection_control = SpvSelectionControlMaskNone) { + uint32_t merge_id, uint32_t selection_control = static_cast( + spv::SelectionControlMask::MaskNone)) { std::unique_ptr new_branch_merge(new Instruction( - GetContext(), SpvOpSelectionMerge, 0, 0, + GetContext(), spv::Op::OpSelectionMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_SELECTION_CONTROL, {selection_control}}})); @@ -189,9 +190,10 @@ class InstructionBuilder { // |continue_id| is the id of the continue block. // |loop_control| are the loop control flags to be added to the instruction. Instruction* AddLoopMerge(uint32_t merge_id, uint32_t continue_id, - uint32_t loop_control = SpvLoopControlMaskNone) { + uint32_t loop_control = static_cast( + spv::LoopControlMask::MaskNone)) { std::unique_ptr new_branch_merge(new Instruction( - GetContext(), SpvOpLoopMerge, 0, 0, + GetContext(), spv::Op::OpLoopMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LOOP_CONTROL, {loop_control}}})); @@ -203,7 +205,7 @@ class InstructionBuilder { // well formed. Instruction* AddBranch(uint32_t label_id) { std::unique_ptr new_branch(new Instruction( - GetContext(), SpvOpBranch, 0, 0, + GetContext(), spv::Op::OpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); return AddInstruction(std::move(new_branch)); } @@ -226,12 +228,13 @@ class InstructionBuilder { Instruction* AddConditionalBranch( uint32_t cond_id, uint32_t true_id, uint32_t false_id, uint32_t merge_id = kInvalidId, - uint32_t selection_control = SpvSelectionControlMaskNone) { + uint32_t selection_control = + static_cast(spv::SelectionControlMask::MaskNone)) { if (merge_id != kInvalidId) { AddSelectionMerge(merge_id, selection_control); } std::unique_ptr new_branch(new Instruction( - GetContext(), SpvOpBranchConditional, 0, 0, + GetContext(), spv::Op::OpBranchConditional, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); @@ -255,7 +258,8 @@ class InstructionBuilder { uint32_t selector_id, uint32_t default_id, const std::vector>& targets, uint32_t merge_id = kInvalidId, - uint32_t selection_control = SpvSelectionControlMaskNone) { + uint32_t selection_control = + static_cast(spv::SelectionControlMask::MaskNone)) { if (merge_id != kInvalidId) { AddSelectionMerge(merge_id, selection_control); } @@ -272,7 +276,7 @@ class InstructionBuilder { Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {target.second}}); } std::unique_ptr new_switch( - new Instruction(GetContext(), SpvOpSwitch, 0, 0, operands)); + new Instruction(GetContext(), spv::Op::OpSwitch, 0, 0, operands)); return AddInstruction(std::move(new_switch)); } @@ -283,7 +287,7 @@ class InstructionBuilder { Instruction* AddPhi(uint32_t type, const std::vector& incomings, uint32_t result = 0) { assert(incomings.size() % 2 == 0 && "A sequence of pairs is expected"); - return AddNaryOp(type, SpvOpPhi, incomings, result); + return AddNaryOp(type, spv::Op::OpPhi, incomings, result); } // Creates an addition instruction. @@ -294,7 +298,7 @@ class InstructionBuilder { Instruction* AddIAdd(uint32_t type, uint32_t op1, uint32_t op2) { // TODO(1841): Handle id overflow. std::unique_ptr inst(new Instruction( - GetContext(), SpvOpIAdd, type, GetContext()->TakeNextId(), + GetContext(), spv::Op::OpIAdd, type, GetContext()->TakeNextId(), {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); return AddInstruction(std::move(inst)); } @@ -308,7 +312,7 @@ class InstructionBuilder { uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type); // TODO(1841): Handle id overflow. std::unique_ptr inst(new Instruction( - GetContext(), SpvOpULessThan, type, GetContext()->TakeNextId(), + GetContext(), spv::Op::OpULessThan, type, GetContext()->TakeNextId(), {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); return AddInstruction(std::move(inst)); } @@ -322,7 +326,7 @@ class InstructionBuilder { uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type); // TODO(1841): Handle id overflow. std::unique_ptr inst(new Instruction( - GetContext(), SpvOpSLessThan, type, GetContext()->TakeNextId(), + GetContext(), spv::Op::OpSLessThan, type, GetContext()->TakeNextId(), {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); return AddInstruction(std::move(inst)); } @@ -352,7 +356,7 @@ class InstructionBuilder { uint32_t false_value) { // TODO(1841): Handle id overflow. std::unique_ptr select(new Instruction( - GetContext(), SpvOpSelect, type, GetContext()->TakeNextId(), + GetContext(), spv::Op::OpSelect, type, GetContext()->TakeNextId(), std::initializer_list{{SPV_OPERAND_TYPE_ID, {cond}}, {SPV_OPERAND_TYPE_ID, {true_value}}, {SPV_OPERAND_TYPE_ID, {false_value}}})); @@ -378,7 +382,7 @@ class InstructionBuilder { } // TODO(1841): Handle id overflow. std::unique_ptr construct( - new Instruction(GetContext(), SpvOpCompositeConstruct, type, + new Instruction(GetContext(), spv::Op::OpCompositeConstruct, type, GetContext()->TakeNextId(), ops)); return AddInstruction(std::move(construct)); } @@ -447,7 +451,7 @@ class InstructionBuilder { // TODO(1841): Handle id overflow. std::unique_ptr new_inst( - new Instruction(GetContext(), SpvOpCompositeExtract, type, + new Instruction(GetContext(), spv::Op::OpCompositeExtract, type, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -455,7 +459,7 @@ class InstructionBuilder { // Creates an unreachable instruction. Instruction* AddUnreachable() { std::unique_ptr select( - new Instruction(GetContext(), SpvOpUnreachable, 0, 0, + new Instruction(GetContext(), spv::Op::OpUnreachable, 0, 0, std::initializer_list{})); return AddInstruction(std::move(select)); } @@ -471,7 +475,7 @@ class InstructionBuilder { // TODO(1841): Handle id overflow. std::unique_ptr new_inst( - new Instruction(GetContext(), SpvOpAccessChain, type_id, + new Instruction(GetContext(), spv::Op::OpAccessChain, type_id, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -482,7 +486,7 @@ class InstructionBuilder { // TODO(1841): Handle id overflow. std::unique_ptr new_inst( - new Instruction(GetContext(), SpvOpLoad, type_id, + new Instruction(GetContext(), spv::Op::OpLoad, type_id, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -491,7 +495,7 @@ class InstructionBuilder { std::vector operands; operands.push_back({SPV_OPERAND_TYPE_ID, {storage_class}}); std::unique_ptr new_inst( - new Instruction(GetContext(), SpvOpVariable, type_id, + new Instruction(GetContext(), spv::Op::OpVariable, type_id, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -502,7 +506,7 @@ class InstructionBuilder { operands.push_back({SPV_OPERAND_TYPE_ID, {obj_id}}); std::unique_ptr new_inst( - new Instruction(GetContext(), SpvOpStore, 0, 0, operands)); + new Instruction(GetContext(), spv::Op::OpStore, 0, 0, operands)); return AddInstruction(std::move(new_inst)); } @@ -518,8 +522,9 @@ class InstructionBuilder { if (result_id == 0) { return nullptr; } - std::unique_ptr new_inst(new Instruction( - GetContext(), SpvOpFunctionCall, result_type, result_id, operands)); + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpFunctionCall, result_type, + result_id, operands)); return AddInstruction(std::move(new_inst)); } @@ -538,8 +543,9 @@ class InstructionBuilder { return nullptr; } - std::unique_ptr new_inst(new Instruction( - GetContext(), SpvOpVectorShuffle, result_type, result_id, operands)); + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpVectorShuffle, result_type, + result_id, operands)); return AddInstruction(std::move(new_inst)); } @@ -560,7 +566,7 @@ class InstructionBuilder { } std::unique_ptr new_inst(new Instruction( - GetContext(), SpvOpExtInst, result_type, result_id, operands)); + GetContext(), spv::Op::OpExtInst, result_type, result_id, operands)); return AddInstruction(std::move(new_inst)); } diff --git a/3rdparty/spirv-tools/source/opt/ir_context.cpp b/3rdparty/spirv-tools/source/opt/ir_context.cpp index c9c3f1b5d..889a671d0 100644 --- a/3rdparty/spirv-tools/source/opt/ir_context.cpp +++ b/3rdparty/spirv-tools/source/opt/ir_context.cpp @@ -22,23 +22,21 @@ #include "source/opt/mem_pass.h" #include "source/opt/reflect.h" +namespace spvtools { +namespace opt { namespace { - -static const int kSpvDecorateTargetIdInIdx = 0; -static const int kSpvDecorateDecorationInIdx = 1; -static const int kSpvDecorateBuiltinInIdx = 2; -static const int kEntryPointInterfaceInIdx = 3; -static const int kEntryPointFunctionIdInIdx = 1; +constexpr int kSpvDecorateTargetIdInIdx = 0; +constexpr int kSpvDecorateDecorationInIdx = 1; +constexpr int kSpvDecorateBuiltinInIdx = 2; +constexpr int kEntryPointInterfaceInIdx = 3; +constexpr int kEntryPointFunctionIdInIdx = 1; +constexpr int kEntryPointExecutionModelInIdx = 0; // Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100 // extension instructions. -static const uint32_t kDebugFunctionOperandFunctionIndex = 13; -static const uint32_t kDebugGlobalVariableOperandVariableIndex = 11; - -} // anonymous namespace - -namespace spvtools { -namespace opt { +constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13; +constexpr uint32_t kDebugGlobalVariableOperandVariableIndex = 11; +} // namespace void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) { set = Analysis(set & ~valid_analyses_); @@ -152,6 +150,9 @@ void IRContext::InvalidateAnalyses(IRContext::Analysis analyses_to_invalidate) { if (analyses_to_invalidate & kAnalysisConstants) { constant_mgr_.reset(nullptr); } + if (analyses_to_invalidate & kAnalysisLiveness) { + liveness_mgr_.reset(nullptr); + } if (analyses_to_invalidate & kAnalysisTypes) { type_mgr_.reset(nullptr); } @@ -195,7 +196,8 @@ Instruction* IRContext::KillInst(Instruction* inst) { if (constant_mgr_ && IsConstantInst(inst->opcode())) { constant_mgr_->RemoveId(inst->result_id()); } - if (inst->opcode() == SpvOpCapability || inst->opcode() == SpvOpExtension) { + if (inst->opcode() == spv::Op::OpCapability || + inst->opcode() == spv::Op::OpExtension) { // We reset the feature manager, instead of updating it, because it is just // as much work. We would have to remove all capabilities implied by this // capability that are not also implied by the remaining OpCapability @@ -398,8 +400,8 @@ void IRContext::AnalyzeUses(Instruction* inst) { if (AreAnalysesValid(kAnalysisDebugInfo)) { get_debug_info_mgr()->AnalyzeDebugInst(inst); } - if (id_to_name_ && - (inst->opcode() == SpvOpName || inst->opcode() == SpvOpMemberName)) { + if (id_to_name_ && (inst->opcode() == spv::Op::OpName || + inst->opcode() == spv::Op::OpMemberName)) { id_to_name_->insert({inst->GetSingleWordInOperand(0), inst}); } } @@ -427,7 +429,7 @@ void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { const auto opcode = inst->opcode(); const uint32_t id = inst->result_id(); // Kill id of OpFunction from DebugFunction. - if (opcode == SpvOpFunction) { + if (opcode == spv::Op::OpFunction) { for (auto it = module()->ext_inst_debuginfo_begin(); it != module()->ext_inst_debuginfo_end(); ++it) { if (it->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugFunction) @@ -441,7 +443,7 @@ void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { } } // Kill id of OpVariable for global variable from DebugGlobalVariable. - if (opcode == SpvOpVariable || IsConstantInst(opcode)) { + if (opcode == spv::Op::OpVariable || IsConstantInst(opcode)) { for (auto it = module()->ext_inst_debuginfo_begin(); it != module()->ext_inst_debuginfo_end(); ++it) { if (it->GetCommonDebugOpcode() != CommonDebugInfoDebugGlobalVariable) @@ -457,255 +459,259 @@ void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { } void IRContext::AddCombinatorsForCapability(uint32_t capability) { - if (capability == SpvCapabilityShader) { - combinator_ops_[0].insert({SpvOpNop, - SpvOpUndef, - SpvOpConstant, - SpvOpConstantTrue, - SpvOpConstantFalse, - SpvOpConstantComposite, - SpvOpConstantSampler, - SpvOpConstantNull, - SpvOpTypeVoid, - SpvOpTypeBool, - SpvOpTypeInt, - SpvOpTypeFloat, - SpvOpTypeVector, - SpvOpTypeMatrix, - SpvOpTypeImage, - SpvOpTypeSampler, - SpvOpTypeSampledImage, - SpvOpTypeAccelerationStructureNV, - SpvOpTypeAccelerationStructureKHR, - SpvOpTypeRayQueryKHR, - SpvOpTypeArray, - SpvOpTypeRuntimeArray, - SpvOpTypeStruct, - SpvOpTypeOpaque, - SpvOpTypePointer, - SpvOpTypeFunction, - SpvOpTypeEvent, - SpvOpTypeDeviceEvent, - SpvOpTypeReserveId, - SpvOpTypeQueue, - SpvOpTypePipe, - SpvOpTypeForwardPointer, - SpvOpVariable, - SpvOpImageTexelPointer, - SpvOpLoad, - SpvOpAccessChain, - SpvOpInBoundsAccessChain, - SpvOpArrayLength, - SpvOpVectorExtractDynamic, - SpvOpVectorInsertDynamic, - SpvOpVectorShuffle, - SpvOpCompositeConstruct, - SpvOpCompositeExtract, - SpvOpCompositeInsert, - SpvOpCopyObject, - SpvOpTranspose, - SpvOpSampledImage, - SpvOpImageSampleImplicitLod, - SpvOpImageSampleExplicitLod, - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleDrefExplicitLod, - SpvOpImageSampleProjImplicitLod, - SpvOpImageSampleProjExplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSampleProjDrefExplicitLod, - SpvOpImageFetch, - SpvOpImageGather, - SpvOpImageDrefGather, - SpvOpImageRead, - SpvOpImage, - SpvOpImageQueryFormat, - SpvOpImageQueryOrder, - SpvOpImageQuerySizeLod, - SpvOpImageQuerySize, - SpvOpImageQueryLevels, - SpvOpImageQuerySamples, - SpvOpConvertFToU, - SpvOpConvertFToS, - SpvOpConvertSToF, - SpvOpConvertUToF, - SpvOpUConvert, - SpvOpSConvert, - SpvOpFConvert, - SpvOpQuantizeToF16, - SpvOpBitcast, - SpvOpSNegate, - SpvOpFNegate, - SpvOpIAdd, - SpvOpFAdd, - SpvOpISub, - SpvOpFSub, - SpvOpIMul, - SpvOpFMul, - SpvOpUDiv, - SpvOpSDiv, - SpvOpFDiv, - SpvOpUMod, - SpvOpSRem, - SpvOpSMod, - SpvOpFRem, - SpvOpFMod, - SpvOpVectorTimesScalar, - SpvOpMatrixTimesScalar, - SpvOpVectorTimesMatrix, - SpvOpMatrixTimesVector, - SpvOpMatrixTimesMatrix, - SpvOpOuterProduct, - SpvOpDot, - SpvOpIAddCarry, - SpvOpISubBorrow, - SpvOpUMulExtended, - SpvOpSMulExtended, - SpvOpAny, - SpvOpAll, - SpvOpIsNan, - SpvOpIsInf, - SpvOpLogicalEqual, - SpvOpLogicalNotEqual, - SpvOpLogicalOr, - SpvOpLogicalAnd, - SpvOpLogicalNot, - SpvOpSelect, - SpvOpIEqual, - SpvOpINotEqual, - SpvOpUGreaterThan, - SpvOpSGreaterThan, - SpvOpUGreaterThanEqual, - SpvOpSGreaterThanEqual, - SpvOpULessThan, - SpvOpSLessThan, - SpvOpULessThanEqual, - SpvOpSLessThanEqual, - SpvOpFOrdEqual, - SpvOpFUnordEqual, - SpvOpFOrdNotEqual, - SpvOpFUnordNotEqual, - SpvOpFOrdLessThan, - SpvOpFUnordLessThan, - SpvOpFOrdGreaterThan, - SpvOpFUnordGreaterThan, - SpvOpFOrdLessThanEqual, - SpvOpFUnordLessThanEqual, - SpvOpFOrdGreaterThanEqual, - SpvOpFUnordGreaterThanEqual, - SpvOpShiftRightLogical, - SpvOpShiftRightArithmetic, - SpvOpShiftLeftLogical, - SpvOpBitwiseOr, - SpvOpBitwiseXor, - SpvOpBitwiseAnd, - SpvOpNot, - SpvOpBitFieldInsert, - SpvOpBitFieldSExtract, - SpvOpBitFieldUExtract, - SpvOpBitReverse, - SpvOpBitCount, - SpvOpPhi, - SpvOpImageSparseSampleImplicitLod, - SpvOpImageSparseSampleExplicitLod, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleDrefExplicitLod, - SpvOpImageSparseSampleProjImplicitLod, - SpvOpImageSparseSampleProjExplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, - SpvOpImageSparseSampleProjDrefExplicitLod, - SpvOpImageSparseFetch, - SpvOpImageSparseGather, - SpvOpImageSparseDrefGather, - SpvOpImageSparseTexelsResident, - SpvOpImageSparseRead, - SpvOpSizeOf}); + spv::Capability cap = spv::Capability(capability); + if (cap == spv::Capability::Shader) { + combinator_ops_[0].insert( + {(uint32_t)spv::Op::OpNop, + (uint32_t)spv::Op::OpUndef, + (uint32_t)spv::Op::OpConstant, + (uint32_t)spv::Op::OpConstantTrue, + (uint32_t)spv::Op::OpConstantFalse, + (uint32_t)spv::Op::OpConstantComposite, + (uint32_t)spv::Op::OpConstantSampler, + (uint32_t)spv::Op::OpConstantNull, + (uint32_t)spv::Op::OpTypeVoid, + (uint32_t)spv::Op::OpTypeBool, + (uint32_t)spv::Op::OpTypeInt, + (uint32_t)spv::Op::OpTypeFloat, + (uint32_t)spv::Op::OpTypeVector, + (uint32_t)spv::Op::OpTypeMatrix, + (uint32_t)spv::Op::OpTypeImage, + (uint32_t)spv::Op::OpTypeSampler, + (uint32_t)spv::Op::OpTypeSampledImage, + (uint32_t)spv::Op::OpTypeAccelerationStructureNV, + (uint32_t)spv::Op::OpTypeAccelerationStructureKHR, + (uint32_t)spv::Op::OpTypeRayQueryKHR, + (uint32_t)spv::Op::OpTypeHitObjectNV, + (uint32_t)spv::Op::OpTypeArray, + (uint32_t)spv::Op::OpTypeRuntimeArray, + (uint32_t)spv::Op::OpTypeStruct, + (uint32_t)spv::Op::OpTypeOpaque, + (uint32_t)spv::Op::OpTypePointer, + (uint32_t)spv::Op::OpTypeFunction, + (uint32_t)spv::Op::OpTypeEvent, + (uint32_t)spv::Op::OpTypeDeviceEvent, + (uint32_t)spv::Op::OpTypeReserveId, + (uint32_t)spv::Op::OpTypeQueue, + (uint32_t)spv::Op::OpTypePipe, + (uint32_t)spv::Op::OpTypeForwardPointer, + (uint32_t)spv::Op::OpVariable, + (uint32_t)spv::Op::OpImageTexelPointer, + (uint32_t)spv::Op::OpLoad, + (uint32_t)spv::Op::OpAccessChain, + (uint32_t)spv::Op::OpInBoundsAccessChain, + (uint32_t)spv::Op::OpArrayLength, + (uint32_t)spv::Op::OpVectorExtractDynamic, + (uint32_t)spv::Op::OpVectorInsertDynamic, + (uint32_t)spv::Op::OpVectorShuffle, + (uint32_t)spv::Op::OpCompositeConstruct, + (uint32_t)spv::Op::OpCompositeExtract, + (uint32_t)spv::Op::OpCompositeInsert, + (uint32_t)spv::Op::OpCopyObject, + (uint32_t)spv::Op::OpTranspose, + (uint32_t)spv::Op::OpSampledImage, + (uint32_t)spv::Op::OpImageSampleImplicitLod, + (uint32_t)spv::Op::OpImageSampleExplicitLod, + (uint32_t)spv::Op::OpImageSampleDrefImplicitLod, + (uint32_t)spv::Op::OpImageSampleDrefExplicitLod, + (uint32_t)spv::Op::OpImageSampleProjImplicitLod, + (uint32_t)spv::Op::OpImageSampleProjExplicitLod, + (uint32_t)spv::Op::OpImageSampleProjDrefImplicitLod, + (uint32_t)spv::Op::OpImageSampleProjDrefExplicitLod, + (uint32_t)spv::Op::OpImageFetch, + (uint32_t)spv::Op::OpImageGather, + (uint32_t)spv::Op::OpImageDrefGather, + (uint32_t)spv::Op::OpImageRead, + (uint32_t)spv::Op::OpImage, + (uint32_t)spv::Op::OpImageQueryFormat, + (uint32_t)spv::Op::OpImageQueryOrder, + (uint32_t)spv::Op::OpImageQuerySizeLod, + (uint32_t)spv::Op::OpImageQuerySize, + (uint32_t)spv::Op::OpImageQueryLevels, + (uint32_t)spv::Op::OpImageQuerySamples, + (uint32_t)spv::Op::OpConvertFToU, + (uint32_t)spv::Op::OpConvertFToS, + (uint32_t)spv::Op::OpConvertSToF, + (uint32_t)spv::Op::OpConvertUToF, + (uint32_t)spv::Op::OpUConvert, + (uint32_t)spv::Op::OpSConvert, + (uint32_t)spv::Op::OpFConvert, + (uint32_t)spv::Op::OpQuantizeToF16, + (uint32_t)spv::Op::OpBitcast, + (uint32_t)spv::Op::OpSNegate, + (uint32_t)spv::Op::OpFNegate, + (uint32_t)spv::Op::OpIAdd, + (uint32_t)spv::Op::OpFAdd, + (uint32_t)spv::Op::OpISub, + (uint32_t)spv::Op::OpFSub, + (uint32_t)spv::Op::OpIMul, + (uint32_t)spv::Op::OpFMul, + (uint32_t)spv::Op::OpUDiv, + (uint32_t)spv::Op::OpSDiv, + (uint32_t)spv::Op::OpFDiv, + (uint32_t)spv::Op::OpUMod, + (uint32_t)spv::Op::OpSRem, + (uint32_t)spv::Op::OpSMod, + (uint32_t)spv::Op::OpFRem, + (uint32_t)spv::Op::OpFMod, + (uint32_t)spv::Op::OpVectorTimesScalar, + (uint32_t)spv::Op::OpMatrixTimesScalar, + (uint32_t)spv::Op::OpVectorTimesMatrix, + (uint32_t)spv::Op::OpMatrixTimesVector, + (uint32_t)spv::Op::OpMatrixTimesMatrix, + (uint32_t)spv::Op::OpOuterProduct, + (uint32_t)spv::Op::OpDot, + (uint32_t)spv::Op::OpIAddCarry, + (uint32_t)spv::Op::OpISubBorrow, + (uint32_t)spv::Op::OpUMulExtended, + (uint32_t)spv::Op::OpSMulExtended, + (uint32_t)spv::Op::OpAny, + (uint32_t)spv::Op::OpAll, + (uint32_t)spv::Op::OpIsNan, + (uint32_t)spv::Op::OpIsInf, + (uint32_t)spv::Op::OpLogicalEqual, + (uint32_t)spv::Op::OpLogicalNotEqual, + (uint32_t)spv::Op::OpLogicalOr, + (uint32_t)spv::Op::OpLogicalAnd, + (uint32_t)spv::Op::OpLogicalNot, + (uint32_t)spv::Op::OpSelect, + (uint32_t)spv::Op::OpIEqual, + (uint32_t)spv::Op::OpINotEqual, + (uint32_t)spv::Op::OpUGreaterThan, + (uint32_t)spv::Op::OpSGreaterThan, + (uint32_t)spv::Op::OpUGreaterThanEqual, + (uint32_t)spv::Op::OpSGreaterThanEqual, + (uint32_t)spv::Op::OpULessThan, + (uint32_t)spv::Op::OpSLessThan, + (uint32_t)spv::Op::OpULessThanEqual, + (uint32_t)spv::Op::OpSLessThanEqual, + (uint32_t)spv::Op::OpFOrdEqual, + (uint32_t)spv::Op::OpFUnordEqual, + (uint32_t)spv::Op::OpFOrdNotEqual, + (uint32_t)spv::Op::OpFUnordNotEqual, + (uint32_t)spv::Op::OpFOrdLessThan, + (uint32_t)spv::Op::OpFUnordLessThan, + (uint32_t)spv::Op::OpFOrdGreaterThan, + (uint32_t)spv::Op::OpFUnordGreaterThan, + (uint32_t)spv::Op::OpFOrdLessThanEqual, + (uint32_t)spv::Op::OpFUnordLessThanEqual, + (uint32_t)spv::Op::OpFOrdGreaterThanEqual, + (uint32_t)spv::Op::OpFUnordGreaterThanEqual, + (uint32_t)spv::Op::OpShiftRightLogical, + (uint32_t)spv::Op::OpShiftRightArithmetic, + (uint32_t)spv::Op::OpShiftLeftLogical, + (uint32_t)spv::Op::OpBitwiseOr, + (uint32_t)spv::Op::OpBitwiseXor, + (uint32_t)spv::Op::OpBitwiseAnd, + (uint32_t)spv::Op::OpNot, + (uint32_t)spv::Op::OpBitFieldInsert, + (uint32_t)spv::Op::OpBitFieldSExtract, + (uint32_t)spv::Op::OpBitFieldUExtract, + (uint32_t)spv::Op::OpBitReverse, + (uint32_t)spv::Op::OpBitCount, + (uint32_t)spv::Op::OpPhi, + (uint32_t)spv::Op::OpImageSparseSampleImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleExplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleDrefImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleDrefExplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjExplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjDrefImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjDrefExplicitLod, + (uint32_t)spv::Op::OpImageSparseFetch, + (uint32_t)spv::Op::OpImageSparseGather, + (uint32_t)spv::Op::OpImageSparseDrefGather, + (uint32_t)spv::Op::OpImageSparseTexelsResident, + (uint32_t)spv::Op::OpImageSparseRead, + (uint32_t)spv::Op::OpSizeOf}); } } void IRContext::AddCombinatorsForExtension(Instruction* extension) { - assert(extension->opcode() == SpvOpExtInstImport && + assert(extension->opcode() == spv::Op::OpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = extension->GetInOperand(0).AsString(); if (extension_name == "GLSL.std.450") { - combinator_ops_[extension->result_id()] = {GLSLstd450Round, - GLSLstd450RoundEven, - GLSLstd450Trunc, - GLSLstd450FAbs, - GLSLstd450SAbs, - GLSLstd450FSign, - GLSLstd450SSign, - GLSLstd450Floor, - GLSLstd450Ceil, - GLSLstd450Fract, - GLSLstd450Radians, - GLSLstd450Degrees, - GLSLstd450Sin, - GLSLstd450Cos, - GLSLstd450Tan, - GLSLstd450Asin, - GLSLstd450Acos, - GLSLstd450Atan, - GLSLstd450Sinh, - GLSLstd450Cosh, - GLSLstd450Tanh, - GLSLstd450Asinh, - GLSLstd450Acosh, - GLSLstd450Atanh, - GLSLstd450Atan2, - GLSLstd450Pow, - GLSLstd450Exp, - GLSLstd450Log, - GLSLstd450Exp2, - GLSLstd450Log2, - GLSLstd450Sqrt, - GLSLstd450InverseSqrt, - GLSLstd450Determinant, - GLSLstd450MatrixInverse, - GLSLstd450ModfStruct, - GLSLstd450FMin, - GLSLstd450UMin, - GLSLstd450SMin, - GLSLstd450FMax, - GLSLstd450UMax, - GLSLstd450SMax, - GLSLstd450FClamp, - GLSLstd450UClamp, - GLSLstd450SClamp, - GLSLstd450FMix, - GLSLstd450IMix, - GLSLstd450Step, - GLSLstd450SmoothStep, - GLSLstd450Fma, - GLSLstd450FrexpStruct, - GLSLstd450Ldexp, - GLSLstd450PackSnorm4x8, - GLSLstd450PackUnorm4x8, - GLSLstd450PackSnorm2x16, - GLSLstd450PackUnorm2x16, - GLSLstd450PackHalf2x16, - GLSLstd450PackDouble2x32, - GLSLstd450UnpackSnorm2x16, - GLSLstd450UnpackUnorm2x16, - GLSLstd450UnpackHalf2x16, - GLSLstd450UnpackSnorm4x8, - GLSLstd450UnpackUnorm4x8, - GLSLstd450UnpackDouble2x32, - GLSLstd450Length, - GLSLstd450Distance, - GLSLstd450Cross, - GLSLstd450Normalize, - GLSLstd450FaceForward, - GLSLstd450Reflect, - GLSLstd450Refract, - GLSLstd450FindILsb, - GLSLstd450FindSMsb, - GLSLstd450FindUMsb, - GLSLstd450InterpolateAtCentroid, - GLSLstd450InterpolateAtSample, - GLSLstd450InterpolateAtOffset, - GLSLstd450NMin, - GLSLstd450NMax, - GLSLstd450NClamp}; + combinator_ops_[extension->result_id()] = { + (uint32_t)GLSLstd450Round, + (uint32_t)GLSLstd450RoundEven, + (uint32_t)GLSLstd450Trunc, + (uint32_t)GLSLstd450FAbs, + (uint32_t)GLSLstd450SAbs, + (uint32_t)GLSLstd450FSign, + (uint32_t)GLSLstd450SSign, + (uint32_t)GLSLstd450Floor, + (uint32_t)GLSLstd450Ceil, + (uint32_t)GLSLstd450Fract, + (uint32_t)GLSLstd450Radians, + (uint32_t)GLSLstd450Degrees, + (uint32_t)GLSLstd450Sin, + (uint32_t)GLSLstd450Cos, + (uint32_t)GLSLstd450Tan, + (uint32_t)GLSLstd450Asin, + (uint32_t)GLSLstd450Acos, + (uint32_t)GLSLstd450Atan, + (uint32_t)GLSLstd450Sinh, + (uint32_t)GLSLstd450Cosh, + (uint32_t)GLSLstd450Tanh, + (uint32_t)GLSLstd450Asinh, + (uint32_t)GLSLstd450Acosh, + (uint32_t)GLSLstd450Atanh, + (uint32_t)GLSLstd450Atan2, + (uint32_t)GLSLstd450Pow, + (uint32_t)GLSLstd450Exp, + (uint32_t)GLSLstd450Log, + (uint32_t)GLSLstd450Exp2, + (uint32_t)GLSLstd450Log2, + (uint32_t)GLSLstd450Sqrt, + (uint32_t)GLSLstd450InverseSqrt, + (uint32_t)GLSLstd450Determinant, + (uint32_t)GLSLstd450MatrixInverse, + (uint32_t)GLSLstd450ModfStruct, + (uint32_t)GLSLstd450FMin, + (uint32_t)GLSLstd450UMin, + (uint32_t)GLSLstd450SMin, + (uint32_t)GLSLstd450FMax, + (uint32_t)GLSLstd450UMax, + (uint32_t)GLSLstd450SMax, + (uint32_t)GLSLstd450FClamp, + (uint32_t)GLSLstd450UClamp, + (uint32_t)GLSLstd450SClamp, + (uint32_t)GLSLstd450FMix, + (uint32_t)GLSLstd450IMix, + (uint32_t)GLSLstd450Step, + (uint32_t)GLSLstd450SmoothStep, + (uint32_t)GLSLstd450Fma, + (uint32_t)GLSLstd450FrexpStruct, + (uint32_t)GLSLstd450Ldexp, + (uint32_t)GLSLstd450PackSnorm4x8, + (uint32_t)GLSLstd450PackUnorm4x8, + (uint32_t)GLSLstd450PackSnorm2x16, + (uint32_t)GLSLstd450PackUnorm2x16, + (uint32_t)GLSLstd450PackHalf2x16, + (uint32_t)GLSLstd450PackDouble2x32, + (uint32_t)GLSLstd450UnpackSnorm2x16, + (uint32_t)GLSLstd450UnpackUnorm2x16, + (uint32_t)GLSLstd450UnpackHalf2x16, + (uint32_t)GLSLstd450UnpackSnorm4x8, + (uint32_t)GLSLstd450UnpackUnorm4x8, + (uint32_t)GLSLstd450UnpackDouble2x32, + (uint32_t)GLSLstd450Length, + (uint32_t)GLSLstd450Distance, + (uint32_t)GLSLstd450Cross, + (uint32_t)GLSLstd450Normalize, + (uint32_t)GLSLstd450FaceForward, + (uint32_t)GLSLstd450Reflect, + (uint32_t)GLSLstd450Refract, + (uint32_t)GLSLstd450FindILsb, + (uint32_t)GLSLstd450FindSMsb, + (uint32_t)GLSLstd450FindUMsb, + (uint32_t)GLSLstd450InterpolateAtCentroid, + (uint32_t)GLSLstd450InterpolateAtSample, + (uint32_t)GLSLstd450InterpolateAtOffset, + (uint32_t)GLSLstd450NMin, + (uint32_t)GLSLstd450NMax, + (uint32_t)GLSLstd450NClamp}; } else { // Map the result id to the empty set. combinator_ops_[extension->result_id()]; @@ -713,8 +719,9 @@ void IRContext::AddCombinatorsForExtension(Instruction* extension) { } void IRContext::InitializeCombinators() { - get_feature_mgr()->GetCapabilities()->ForEach( - [this](SpvCapability cap) { AddCombinatorsForCapability(cap); }); + get_feature_mgr()->GetCapabilities()->ForEach([this](spv::Capability cap) { + AddCombinatorsForCapability(uint32_t(cap)); + }); for (auto& extension : module()->ext_inst_imports()) { AddCombinatorsForExtension(&extension); @@ -724,8 +731,8 @@ void IRContext::InitializeCombinators() { } void IRContext::RemoveFromIdToName(const Instruction* inst) { - if (id_to_name_ && - (inst->opcode() == SpvOpName || inst->opcode() == SpvOpMemberName)) { + if (id_to_name_ && (inst->opcode() == spv::Op::OpName || + inst->opcode() == spv::Op::OpMemberName)) { auto range = id_to_name_->equal_range(inst->GetSingleWordInOperand(0)); for (auto it = range.first; it != range.second; ++it) { if (it->second == inst) { @@ -754,15 +761,17 @@ LoopDescriptor* IRContext::GetLoopDescriptor(const Function* f) { uint32_t IRContext::FindBuiltinInputVar(uint32_t builtin) { for (auto& a : module_->annotations()) { - if (a.opcode() != SpvOpDecorate) continue; - if (a.GetSingleWordInOperand(kSpvDecorateDecorationInIdx) != - SpvDecorationBuiltIn) + if (spv::Op(a.opcode()) != spv::Op::OpDecorate) continue; + if (spv::Decoration(a.GetSingleWordInOperand( + kSpvDecorateDecorationInIdx)) != spv::Decoration::BuiltIn) continue; if (a.GetSingleWordInOperand(kSpvDecorateBuiltinInIdx) != builtin) continue; uint32_t target_id = a.GetSingleWordInOperand(kSpvDecorateTargetIdInIdx); Instruction* b_var = get_def_use_mgr()->GetDef(target_id); - if (b_var->opcode() != SpvOpVariable) continue; - if (b_var->GetSingleWordInOperand(0) != SpvStorageClassInput) continue; + if (b_var->opcode() != spv::Op::OpVariable) continue; + if (spv::StorageClass(b_var->GetSingleWordInOperand(0)) != + spv::StorageClass::Input) + continue; return target_id; } return 0; @@ -798,39 +807,39 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { // TODO(greg-lunarg): Add support for all builtins analysis::TypeManager* type_mgr = get_type_mgr(); analysis::Type* reg_type; - switch (builtin) { - case SpvBuiltInFragCoord: { + switch (spv::BuiltIn(builtin)) { + case spv::BuiltIn::FragCoord: { analysis::Float float_ty(32); analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); analysis::Vector v4float_ty(reg_float_ty, 4); reg_type = type_mgr->GetRegisteredType(&v4float_ty); break; } - case SpvBuiltInVertexIndex: - case SpvBuiltInInstanceIndex: - case SpvBuiltInPrimitiveId: - case SpvBuiltInInvocationId: - case SpvBuiltInSubgroupLocalInvocationId: { + case spv::BuiltIn::VertexIndex: + case spv::BuiltIn::InstanceIndex: + case spv::BuiltIn::PrimitiveId: + case spv::BuiltIn::InvocationId: + case spv::BuiltIn::SubgroupLocalInvocationId: { analysis::Integer uint_ty(32, false); reg_type = type_mgr->GetRegisteredType(&uint_ty); break; } - case SpvBuiltInGlobalInvocationId: - case SpvBuiltInLaunchIdNV: { + case spv::BuiltIn::GlobalInvocationId: + case spv::BuiltIn::LaunchIdNV: { analysis::Integer uint_ty(32, false); analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); analysis::Vector v3uint_ty(reg_uint_ty, 3); reg_type = type_mgr->GetRegisteredType(&v3uint_ty); break; } - case SpvBuiltInTessCoord: { + case spv::BuiltIn::TessCoord: { analysis::Float float_ty(32); analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); analysis::Vector v3float_ty(reg_float_ty, 3); reg_type = type_mgr->GetRegisteredType(&v3float_ty); break; } - case SpvBuiltInSubgroupLtMask: { + case spv::BuiltIn::SubgroupLtMask: { analysis::Integer uint_ty(32, false); analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); analysis::Vector v4uint_ty(reg_uint_ty, 4); @@ -844,17 +853,17 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { } uint32_t type_id = type_mgr->GetTypeInstruction(reg_type); uint32_t varTyPtrId = - type_mgr->FindPointerToType(type_id, SpvStorageClassInput); + type_mgr->FindPointerToType(type_id, spv::StorageClass::Input); // TODO(1841): Handle id overflow. var_id = TakeNextId(); std::unique_ptr newVarOp( - new Instruction(this, SpvOpVariable, varTyPtrId, var_id, + new Instruction(this, spv::Op::OpVariable, varTyPtrId, var_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvStorageClassInput}}})); + {uint32_t(spv::StorageClass::Input)}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*newVarOp); module()->AddGlobalValue(std::move(newVarOp)); - get_decoration_mgr()->AddDecorationVal(var_id, SpvDecorationBuiltIn, - builtin); + get_decoration_mgr()->AddDecorationVal( + var_id, uint32_t(spv::Decoration::BuiltIn), builtin); AddVarToEntryPoints(var_id); } builtin_var_id_map_[builtin] = var_id; @@ -864,7 +873,7 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { void IRContext::AddCalls(const Function* func, std::queue* todo) { for (auto bi = func->begin(); bi != func->end(); ++bi) for (auto ii = bi->begin(); ii != bi->end(); ++ii) - if (ii->opcode() == SpvOpFunctionCall) + if (ii->opcode() == spv::Op::OpFunctionCall) todo->push(ii->GetSingleWordInOperand(0)); } @@ -889,12 +898,12 @@ bool IRContext::ProcessReachableCallTree(ProcessFunction& pfn) { for (auto& a : annotations()) { // TODO: Handle group decorations as well. Currently not generate by any // front-end, but could be coming. - if (a.opcode() == SpvOp::SpvOpDecorate) { - if (a.GetSingleWordOperand(1) == - SpvDecoration::SpvDecorationLinkageAttributes) { + if (a.opcode() == spv::Op::OpDecorate) { + if (spv::Decoration(a.GetSingleWordOperand(1)) == + spv::Decoration::LinkageAttributes) { uint32_t lastOperand = a.NumOperands() - 1; - if (a.GetSingleWordOperand(lastOperand) == - SpvLinkageType::SpvLinkageTypeExport) { + if (spv::LinkageType(a.GetSingleWordOperand(lastOperand)) == + spv::LinkageType::Export) { uint32_t id = a.GetSingleWordOperand(0); if (GetFunction(id)) { roots.push(id); @@ -1058,5 +1067,26 @@ bool IRContext::IsReachable(const opt::BasicBlock& bb) { return GetDominatorAnalysis(enclosing_function) ->Dominates(enclosing_function->entry().get(), &bb); } + +spv::ExecutionModel IRContext::GetStage() { + const auto& entry_points = module()->entry_points(); + if (entry_points.empty()) { + return spv::ExecutionModel::Max; + } + + uint32_t stage = entry_points.begin()->GetSingleWordInOperand( + kEntryPointExecutionModelInIdx); + auto it = std::find_if( + entry_points.begin(), entry_points.end(), [stage](const Instruction& x) { + return x.GetSingleWordInOperand(kEntryPointExecutionModelInIdx) != + stage; + }); + if (it != entry_points.end()) { + EmitErrorMessage("Mixed stage shader module not supported", &(*it)); + } + + return static_cast(stage); +} + } // namespace opt } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/ir_context.h b/3rdparty/spirv-tools/source/opt/ir_context.h index 2f27942b4..35075de17 100644 --- a/3rdparty/spirv-tools/source/opt/ir_context.h +++ b/3rdparty/spirv-tools/source/opt/ir_context.h @@ -35,6 +35,7 @@ #include "source/opt/dominator_analysis.h" #include "source/opt/feature_manager.h" #include "source/opt/fold.h" +#include "source/opt/liveness.h" #include "source/opt/loop_descriptor.h" #include "source/opt/module.h" #include "source/opt/register_pressure.h" @@ -81,6 +82,7 @@ class IRContext { kAnalysisConstants = 1 << 14, kAnalysisTypes = 1 << 15, kAnalysisDebugInfo = 1 << 16, + kAnalysisLiveness = 1 << 17, kAnalysisEnd = 1 << 17 }; @@ -201,7 +203,7 @@ class IRContext { inline IteratorRange ext_inst_debuginfo() const; // Add |capability| to the module, if it is not already enabled. - inline void AddCapability(SpvCapability capability); + inline void AddCapability(spv::Capability capability); // Appends a capability instruction to this module. inline void AddCapability(std::unique_ptr&& c); @@ -248,6 +250,15 @@ class IRContext { return def_use_mgr_.get(); } + // Returns a pointer to a liveness manager. If the liveness manager is + // invalid, it is rebuilt first. + analysis::LivenessManager* get_liveness_mgr() { + if (!AreAnalysesValid(kAnalysisLiveness)) { + BuildLivenessManager(); + } + return liveness_mgr_.get(); + } + // Returns a pointer to a value number table. If the liveness analysis is // invalid, it is rebuilt first. ValueNumberTable* GetValueNumberTable() { @@ -367,6 +378,11 @@ class IRContext { // having more than one name. This method returns the first one it finds. inline Instruction* GetMemberName(uint32_t struct_type_id, uint32_t index); + // Copy names from |old_id| to |new_id|. Only copy member name if index is + // less than |max_member_index|. + inline void CloneNames(const uint32_t old_id, const uint32_t new_id, + const uint32_t max_member_index = UINT32_MAX); + // Sets the message consumer to the given |consumer|. |consumer| which will be // invoked every time there is a message to be communicated to the outside. void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); } @@ -475,14 +491,14 @@ class IRContext { if (!AreAnalysesValid(kAnalysisCombinators)) { InitializeCombinators(); } - const uint32_t kExtInstSetIdInIndx = 0; - const uint32_t kExtInstInstructionInIndx = 1; + constexpr uint32_t kExtInstSetIdInIndx = 0; + constexpr uint32_t kExtInstInstructionInIndx = 1; - if (inst->opcode() != SpvOpExtInst) { - return combinator_ops_[0].count(inst->opcode()) != 0; + if (inst->opcode() != spv::Op::OpExtInst) { + return combinator_ops_[0].count(uint32_t(inst->opcode())) != 0; } else { uint32_t set = inst->GetSingleWordInOperand(kExtInstSetIdInIndx); - uint32_t op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx); + auto op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx); return combinator_ops_[set].count(op) != 0; } } @@ -591,7 +607,7 @@ class IRContext { } Function* GetFunction(Instruction* inst) { - if (inst->opcode() != SpvOpFunction) { + if (inst->opcode() != spv::Op::OpFunction) { return nullptr; } return GetFunction(inst->result_id()); @@ -625,6 +641,10 @@ class IRContext { // the function that contains |bb|. bool IsReachable(const opt::BasicBlock& bb); + // Return the stage of the module. Will generate error if entry points don't + // all have the same stage. + spv::ExecutionModel GetStage(); + private: // Builds the def-use manager from scratch, even if it was already valid. void BuildDefUseManager() { @@ -632,6 +652,12 @@ class IRContext { valid_analyses_ = valid_analyses_ | kAnalysisDefUse; } + // Builds the liveness manager from scratch, even if it was already valid. + void BuildLivenessManager() { + liveness_mgr_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisLiveness; + } + // Builds the instruction-block map for the whole module. void BuildInstrToBlockMapping() { instr_to_block_.clear(); @@ -852,6 +878,9 @@ class IRContext { std::unique_ptr struct_cfg_analysis_; + // The liveness manager for |module_|. + std::unique_ptr liveness_mgr_; + // The maximum legal value for the id bound. uint32_t max_id_bound_; @@ -1014,10 +1043,10 @@ IteratorRange IRContext::ext_inst_debuginfo() return ((const Module*)module_.get())->ext_inst_debuginfo(); } -void IRContext::AddCapability(SpvCapability capability) { +void IRContext::AddCapability(spv::Capability capability) { if (!get_feature_mgr()->HasCapability(capability)) { std::unique_ptr capability_inst(new Instruction( - this, SpvOpCapability, 0, 0, + this, spv::Op::OpCapability, 0, 0, {{SPV_OPERAND_TYPE_CAPABILITY, {static_cast(capability)}}})); AddCapability(std::move(capability_inst)); } @@ -1027,7 +1056,7 @@ void IRContext::AddCapability(std::unique_ptr&& c) { AddCombinatorsForCapability(c->GetSingleWordInOperand(0)); if (feature_mgr_ != nullptr) { feature_mgr_->AddCapability( - static_cast(c->GetSingleWordInOperand(0))); + static_cast(c->GetSingleWordInOperand(0))); } if (AreAnalysesValid(kAnalysisDefUse)) { get_def_use_mgr()->AnalyzeInstDefUse(c.get()); @@ -1038,7 +1067,7 @@ void IRContext::AddCapability(std::unique_ptr&& c) { void IRContext::AddExtension(const std::string& ext_name) { std::vector ext_words = spvtools::utils::MakeVector(ext_name); AddExtension(std::unique_ptr( - new Instruction(this, SpvOpExtension, 0u, 0u, + new Instruction(this, spv::Op::OpExtension, 0u, 0u, {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}}))); } @@ -1055,7 +1084,7 @@ void IRContext::AddExtension(std::unique_ptr&& e) { void IRContext::AddExtInstImport(const std::string& name) { std::vector ext_words = spvtools::utils::MakeVector(name); AddExtInstImport(std::unique_ptr( - new Instruction(this, SpvOpExtInstImport, 0u, TakeNextId(), + new Instruction(this, spv::Op::OpExtInstImport, 0u, TakeNextId(), {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}}))); } @@ -1088,7 +1117,8 @@ void IRContext::AddDebug1Inst(std::unique_ptr&& d) { void IRContext::AddDebug2Inst(std::unique_ptr&& d) { if (AreAnalysesValid(kAnalysisNameMap)) { - if (d->opcode() == SpvOpName || d->opcode() == SpvOpMemberName) { + if (d->opcode() == spv::Op::OpName || + d->opcode() == spv::Op::OpMemberName) { // OpName and OpMemberName do not have result-ids. The target of the // instruction is at InOperand index 0. id_to_name_->insert({d->GetSingleWordInOperand(0), d.get()}); @@ -1151,8 +1181,8 @@ void IRContext::UpdateDefUse(Instruction* inst) { void IRContext::BuildIdToNameMap() { id_to_name_ = MakeUnique>(); for (Instruction& debug_inst : debugs2()) { - if (debug_inst.opcode() == SpvOpMemberName || - debug_inst.opcode() == SpvOpName) { + if (debug_inst.opcode() == spv::Op::OpMemberName || + debug_inst.opcode() == spv::Op::OpName) { id_to_name_->insert({debug_inst.GetSingleWordInOperand(0), &debug_inst}); } } @@ -1175,7 +1205,7 @@ Instruction* IRContext::GetMemberName(uint32_t struct_type_id, uint32_t index) { auto result = id_to_name_->equal_range(struct_type_id); for (auto i = result.first; i != result.second; ++i) { auto* name_instr = i->second; - if (name_instr->opcode() == SpvOpMemberName && + if (name_instr->opcode() == spv::Op::OpMemberName && name_instr->GetSingleWordInOperand(1) == index) { return name_instr; } @@ -1183,6 +1213,25 @@ Instruction* IRContext::GetMemberName(uint32_t struct_type_id, uint32_t index) { return nullptr; } +void IRContext::CloneNames(const uint32_t old_id, const uint32_t new_id, + const uint32_t max_member_index) { + std::vector> names_to_add; + auto names = GetNames(old_id); + for (auto n : names) { + Instruction* old_name_inst = n.second; + if (old_name_inst->opcode() == spv::Op::OpMemberName) { + auto midx = old_name_inst->GetSingleWordInOperand(1); + if (midx >= max_member_index) continue; + } + std::unique_ptr new_name_inst(old_name_inst->Clone(this)); + new_name_inst->SetInOperand(0, {new_id}); + names_to_add.push_back(std::move(new_name_inst)); + } + // We can't add the new names when we are iterating over name range above. + // We can add all the new names now. + for (auto& new_name : names_to_add) AddDebug2Inst(std::move(new_name)); +} + } // namespace opt } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/ir_loader.cpp b/3rdparty/spirv-tools/source/opt/ir_loader.cpp index 734ad554b..e9b7bbfc2 100644 --- a/3rdparty/spirv-tools/source/opt/ir_loader.cpp +++ b/3rdparty/spirv-tools/source/opt/ir_loader.cpp @@ -24,12 +24,13 @@ #include "source/opt/reflect.h" #include "source/util/make_unique.h" -static const uint32_t kExtInstSetIndex = 4; -static const uint32_t kLexicalScopeIndex = 5; -static const uint32_t kInlinedAtIndex = 6; - namespace spvtools { namespace opt { +namespace { +constexpr uint32_t kExtInstSetIndex = 4; +constexpr uint32_t kLexicalScopeIndex = 5; +constexpr uint32_t kInlinedAtIndex = 6; +} // namespace IrLoader::IrLoader(const MessageConsumer& consumer, Module* m) : consumer_(consumer), @@ -39,9 +40,9 @@ IrLoader::IrLoader(const MessageConsumer& consumer, Module* m) last_dbg_scope_(kNoDebugScope, kNoInlinedAt) {} bool IsLineInst(const spv_parsed_instruction_t* inst) { - const auto opcode = static_cast(inst->opcode); + const auto opcode = static_cast(inst->opcode); if (IsOpLineInst(opcode)) return true; - if (opcode != SpvOpExtInst) return false; + if (opcode != spv::Op::OpExtInst) return false; if (inst->ext_inst_type != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) return false; const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; @@ -63,8 +64,9 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { // If it is a DebugScope or DebugNoScope of debug extension, we do not // create a new instruction, but simply keep the information in // struct DebugScope. - const auto opcode = static_cast(inst->opcode); - if (opcode == SpvOpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) { + const auto opcode = static_cast(inst->opcode); + if (opcode == spv::Op::OpExtInst && + spvExtInstIsDebugInfo(inst->ext_inst_type)) { const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 || inst->ext_inst_type == @@ -130,13 +132,13 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { // Handle function and basic block boundaries first, then normal // instructions. - if (opcode == SpvOpFunction) { + if (opcode == spv::Op::OpFunction) { if (function_ != nullptr) { Error(consumer_, src, loc, "function inside function"); return false; } function_ = MakeUnique(std::move(spv_inst)); - } else if (opcode == SpvOpFunctionEnd) { + } else if (opcode == spv::Op::OpFunctionEnd) { if (function_ == nullptr) { Error(consumer_, src, loc, "OpFunctionEnd without corresponding OpFunction"); @@ -149,7 +151,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { function_->SetFunctionEnd(std::move(spv_inst)); module_->AddFunction(std::move(function_)); function_ = nullptr; - } else if (opcode == SpvOpLabel) { + } else if (opcode == spv::Op::OpLabel) { if (function_ == nullptr) { Error(consumer_, src, loc, "OpLabel outside function"); return false; @@ -179,20 +181,20 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { } else { if (function_ == nullptr) { // Outside function definition SPIRV_ASSERT(consumer_, block_ == nullptr); - if (opcode == SpvOpCapability) { + if (opcode == spv::Op::OpCapability) { module_->AddCapability(std::move(spv_inst)); - } else if (opcode == SpvOpExtension) { + } else if (opcode == spv::Op::OpExtension) { module_->AddExtension(std::move(spv_inst)); - } else if (opcode == SpvOpExtInstImport) { + } else if (opcode == spv::Op::OpExtInstImport) { module_->AddExtInstImport(std::move(spv_inst)); - } else if (opcode == SpvOpMemoryModel) { + } else if (opcode == spv::Op::OpMemoryModel) { module_->SetMemoryModel(std::move(spv_inst)); - } else if (opcode == SpvOpSamplerImageAddressingModeNV) { + } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) { module_->SetSampledImageAddressMode(std::move(spv_inst)); - } else if (opcode == SpvOpEntryPoint) { + } else if (opcode == spv::Op::OpEntryPoint) { module_->AddEntryPoint(std::move(spv_inst)); - } else if (opcode == SpvOpExecutionMode || - opcode == SpvOpExecutionModeId) { + } else if (opcode == spv::Op::OpExecutionMode || + opcode == spv::Op::OpExecutionModeId) { module_->AddExecutionMode(std::move(spv_inst)); } else if (IsDebug1Inst(opcode)) { module_->AddDebug1Inst(std::move(spv_inst)); @@ -204,13 +206,13 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { module_->AddAnnotationInst(std::move(spv_inst)); } else if (IsTypeInst(opcode)) { module_->AddType(std::move(spv_inst)); - } else if (IsConstantInst(opcode) || opcode == SpvOpVariable || - opcode == SpvOpUndef) { + } else if (IsConstantInst(opcode) || opcode == spv::Op::OpVariable || + opcode == spv::Op::OpUndef) { module_->AddGlobalValue(std::move(spv_inst)); - } else if (opcode == SpvOpExtInst && + } else if (opcode == spv::Op::OpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) { module_->AddExtInstDebugInfo(std::move(spv_inst)); - } else if (opcode == SpvOpExtInst && + } else if (opcode == spv::Op::OpExtInst && spvExtInstIsNonSemantic(inst->ext_inst_type)) { // If there are no functions, add the non-semantic instructions to the // global values. Otherwise append it to the list of the last function. @@ -229,11 +231,11 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { return false; } } else { - if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) + if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); if (last_dbg_scope_.GetLexicalScope() != kNoDebugScope) spv_inst->SetDebugScope(last_dbg_scope_); - if (opcode == SpvOpExtInst && + if (opcode == spv::Op::OpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) { const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) { @@ -322,7 +324,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { } } else { if (block_ == nullptr) { // Inside function but outside blocks - if (opcode != SpvOpFunctionParameter) { + if (opcode != spv::Op::OpFunctionParameter) { Errorf(consumer_, src, loc, "Non-OpFunctionParameter (opcode: %d) found inside " "function but outside basic block", diff --git a/3rdparty/spirv-tools/source/opt/licm_pass.cpp b/3rdparty/spirv-tools/source/opt/licm_pass.cpp index 82851fd27..514518b46 100644 --- a/3rdparty/spirv-tools/source/opt/licm_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/licm_pass.cpp @@ -126,8 +126,8 @@ bool LICMPass::HoistInstruction(Loop* loop, Instruction* inst) { } Instruction* insertion_point = &*pre_header_bb->tail(); Instruction* previous_node = insertion_point->PreviousNode(); - if (previous_node && (previous_node->opcode() == SpvOpLoopMerge || - previous_node->opcode() == SpvOpSelectionMerge)) { + if (previous_node && (previous_node->opcode() == spv::Op::OpLoopMerge || + previous_node->opcode() == spv::Op::OpSelectionMerge)) { insertion_point = previous_node; } diff --git a/3rdparty/spirv-tools/source/opt/liveness.cpp b/3rdparty/spirv-tools/source/opt/liveness.cpp new file mode 100644 index 000000000..fdf3f4e11 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/liveness.cpp @@ -0,0 +1,332 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/liveness.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace analysis { +namespace { +constexpr uint32_t kDecorationLocationInIdx = 2; +constexpr uint32_t kOpDecorateMemberMemberInIdx = 1; +constexpr uint32_t kOpDecorateMemberLocationInIdx = 3; +constexpr uint32_t kOpDecorateBuiltInLiteralInIdx = 2; +constexpr uint32_t kOpDecorateMemberBuiltInLiteralInIdx = 3; +} // namespace + +LivenessManager::LivenessManager(IRContext* ctx) : ctx_(ctx), computed_(false) { + // Liveness sets computed when queried +} + +void LivenessManager::InitializeAnalysis() { + live_locs_.clear(); + live_builtins_.clear(); + // Mark all builtins live for frag shader. + if (context()->GetStage() == spv::ExecutionModel::Fragment) { + live_builtins_.insert(uint32_t(spv::BuiltIn::PointSize)); + live_builtins_.insert(uint32_t(spv::BuiltIn::ClipDistance)); + live_builtins_.insert(uint32_t(spv::BuiltIn::CullDistance)); + } +} + +bool LivenessManager::IsAnalyzedBuiltin(uint32_t bi) { + // There are only three builtins that can be analyzed and removed between + // two stages: PointSize, ClipDistance and CullDistance. All others are + // always consumed implicitly by the downstream stage. + const auto builtin = spv::BuiltIn(bi); + return builtin == spv::BuiltIn::PointSize || + builtin == spv::BuiltIn::ClipDistance || + builtin == spv::BuiltIn::CullDistance; +} + +bool LivenessManager::AnalyzeBuiltIn(uint32_t id) { + auto deco_mgr = context()->get_decoration_mgr(); + bool saw_builtin = false; + // Analyze all builtin decorations of |id|. + (void)deco_mgr->ForEachDecoration( + id, uint32_t(spv::Decoration::BuiltIn), + [this, &saw_builtin](const Instruction& deco_inst) { + saw_builtin = true; + // No need to process builtins in frag shader. All assumed used. + if (context()->GetStage() == spv::ExecutionModel::Fragment) return; + uint32_t builtin = uint32_t(spv::BuiltIn::Max); + if (deco_inst.opcode() == spv::Op::OpDecorate) + builtin = + deco_inst.GetSingleWordInOperand(kOpDecorateBuiltInLiteralInIdx); + else if (deco_inst.opcode() == spv::Op::OpMemberDecorate) + builtin = deco_inst.GetSingleWordInOperand( + kOpDecorateMemberBuiltInLiteralInIdx); + else + assert(false && "unexpected decoration"); + if (IsAnalyzedBuiltin(builtin)) live_builtins_.insert(builtin); + }); + return saw_builtin; +} + +void LivenessManager::MarkLocsLive(uint32_t start, uint32_t count) { + auto finish = start + count; + for (uint32_t u = start; u < finish; ++u) { + live_locs_.insert(u); + } +} + +uint32_t LivenessManager::GetLocSize(const analysis::Type* type) const { + auto arr_type = type->AsArray(); + if (arr_type) { + auto comp_type = arr_type->element_type(); + auto len_info = arr_type->length_info(); + assert(len_info.words[0] == analysis::Array::LengthInfo::kConstant && + "unexpected array length"); + auto comp_len = len_info.words[1]; + return comp_len * GetLocSize(comp_type); + } + auto struct_type = type->AsStruct(); + if (struct_type) { + uint32_t size = 0u; + for (auto& el_type : struct_type->element_types()) + size += GetLocSize(el_type); + return size; + } + auto mat_type = type->AsMatrix(); + if (mat_type) { + auto cnt = mat_type->element_count(); + auto comp_type = mat_type->element_type(); + return cnt * GetLocSize(comp_type); + } + auto vec_type = type->AsVector(); + if (vec_type) { + auto comp_type = vec_type->element_type(); + if (comp_type->AsInteger()) return 1; + auto float_type = comp_type->AsFloat(); + assert(float_type && "unexpected vector component type"); + auto width = float_type->width(); + if (width == 32 || width == 16) return 1; + assert(width == 64 && "unexpected float type width"); + auto comp_cnt = vec_type->element_count(); + return (comp_cnt > 2) ? 2 : 1; + } + assert((type->AsInteger() || type->AsFloat()) && "unexpected input type"); + return 1; +} + +const analysis::Type* LivenessManager::GetComponentType( + uint32_t index, const analysis::Type* agg_type) const { + auto arr_type = agg_type->AsArray(); + if (arr_type) return arr_type->element_type(); + auto struct_type = agg_type->AsStruct(); + if (struct_type) return struct_type->element_types()[index]; + auto mat_type = agg_type->AsMatrix(); + if (mat_type) return mat_type->element_type(); + auto vec_type = agg_type->AsVector(); + assert(vec_type && "unexpected non-aggregate type"); + return vec_type->element_type(); +} + +uint32_t LivenessManager::GetLocOffset(uint32_t index, + const analysis::Type* agg_type) const { + auto arr_type = agg_type->AsArray(); + if (arr_type) return index * GetLocSize(arr_type->element_type()); + auto struct_type = agg_type->AsStruct(); + if (struct_type) { + uint32_t offset = 0u; + uint32_t cnt = 0u; + for (auto& el_type : struct_type->element_types()) { + if (cnt == index) break; + offset += GetLocSize(el_type); + ++cnt; + } + return offset; + } + auto mat_type = agg_type->AsMatrix(); + if (mat_type) return index * GetLocSize(mat_type->element_type()); + auto vec_type = agg_type->AsVector(); + assert(vec_type && "unexpected non-aggregate type"); + auto comp_type = vec_type->element_type(); + auto flt_type = comp_type->AsFloat(); + if (flt_type && flt_type->width() == 64u && index >= 2u) return 1; + return 0; +} + +void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, + const analysis::Type** curr_type, + uint32_t* offset, bool* no_loc, + bool is_patch, bool input) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + // For tesc, tese and geom input variables, and tesc output variables, + // first array index does not contribute to offset. + auto stage = context()->GetStage(); + bool skip_first_index = false; + if ((input && (stage == spv::ExecutionModel::TessellationControl || + stage == spv::ExecutionModel::TessellationEvaluation || + stage == spv::ExecutionModel::Geometry)) || + (!input && stage == spv::ExecutionModel::TessellationControl)) + skip_first_index = !is_patch; + uint32_t ocnt = 0; + ac->WhileEachInOperand([this, &ocnt, def_use_mgr, type_mgr, deco_mgr, + curr_type, offset, no_loc, + skip_first_index](const uint32_t* opnd) { + if (ocnt >= 1) { + // Skip first index's contribution to offset if indicated + if (ocnt == 1 && skip_first_index) { + auto arr_type = (*curr_type)->AsArray(); + assert(arr_type && "unexpected wrapper type"); + *curr_type = arr_type->element_type(); + ocnt++; + return true; + } + // If any non-constant index, mark the entire current object and return. + auto idx_inst = def_use_mgr->GetDef(*opnd); + if (idx_inst->opcode() != spv::Op::OpConstant) return false; + // If current type is struct, look for location decoration on member and + // reset offset if found. + auto index = idx_inst->GetSingleWordInOperand(0); + auto str_type = (*curr_type)->AsStruct(); + if (str_type) { + uint32_t loc = 0; + auto str_type_id = type_mgr->GetId(str_type); + bool no_mem_loc = deco_mgr->WhileEachDecoration( + str_type_id, uint32_t(spv::Decoration::Location), + [&loc, index, no_loc](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpMemberDecorate && + "unexpected decoration"); + if (deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx) == + index) { + loc = + deco.GetSingleWordInOperand(kOpDecorateMemberLocationInIdx); + *no_loc = false; + return false; + } + return true; + }); + if (!no_mem_loc) { + *offset = loc; + *curr_type = GetComponentType(index, *curr_type); + ocnt++; + return true; + } + } + + // Update offset and current type based on constant index. + *offset += GetLocOffset(index, *curr_type); + *curr_type = GetComponentType(index, *curr_type); + } + ocnt++; + return true; + }); +} + +void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + // Find variable location if present. + uint32_t loc = 0; + auto var_id = var->result_id(); + bool no_loc = deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Location), + [&loc](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); + loc = deco.GetSingleWordInOperand(kDecorationLocationInIdx); + return false; + }); + // Find patch decoration if present + bool is_patch = !deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Patch), [](const Instruction& deco) { + if (deco.opcode() != spv::Op::OpDecorate) + assert(false && "unexpected decoration"); + return false; + }); + // If use is a load, mark all locations of var + auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); + assert(ptr_type && "unexpected var type"); + auto var_type = ptr_type->pointee_type(); + if (ref->opcode() == spv::Op::OpLoad) { + assert(!no_loc && "missing input variable location"); + MarkLocsLive(loc, GetLocSize(var_type)); + return; + } + // Mark just those locations indicated by access chain + assert((ref->opcode() == spv::Op::OpAccessChain || + ref->opcode() == spv::Op::OpInBoundsAccessChain) && + "unexpected use of input variable"); + // Traverse access chain, compute location offset and type of reference + // through constant indices and mark those locs live. Assert if no location + // found. + uint32_t offset = loc; + auto curr_type = var_type; + AnalyzeAccessChainLoc(ref, &curr_type, &offset, &no_loc, is_patch); + assert(!no_loc && "missing input variable location"); + MarkLocsLive(offset, GetLocSize(curr_type)); +} + +void LivenessManager::ComputeLiveness() { + InitializeAnalysis(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + // Process all input variables + for (auto& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type->storage_class() != spv::StorageClass::Input) { + continue; + } + // If var is builtin, mark live if analyzed and continue to next variable + auto var_id = var.result_id(); + if (AnalyzeBuiltIn(var_id)) continue; + // If interface block with builtin members, mark live if analyzed and + // continue to next variable. Input interface blocks will only appear + // in tesc, tese and geom shaders. Will need to strip off one level of + // arrayness to get to block type. + auto pte_type = ptr_type->pointee_type(); + auto arr_type = pte_type->AsArray(); + if (arr_type) { + auto elt_type = arr_type->element_type(); + auto str_type = elt_type->AsStruct(); + if (str_type) { + auto str_type_id = type_mgr->GetId(str_type); + if (AnalyzeBuiltIn(str_type_id)) continue; + } + } + // Mark all used locations of var live + def_use_mgr->ForEachUser(var_id, [this, &var](Instruction* user) { + auto op = user->opcode(); + if (op == spv::Op::OpEntryPoint || op == spv::Op::OpName || + op == spv::Op::OpDecorate) { + return; + } + MarkRefLive(user, &var); + }); + } +} + +void LivenessManager::GetLiveness(std::unordered_set* live_locs, + std::unordered_set* live_builtins) { + if (!computed_) { + ComputeLiveness(); + computed_ = true; + } + *live_locs = live_locs_; + *live_builtins = live_builtins_; +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/liveness.h b/3rdparty/spirv-tools/source/opt/liveness.h new file mode 100644 index 000000000..7d8a9fb40 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/liveness.h @@ -0,0 +1,99 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LIVENESS_H_ +#define SOURCE_OPT_LIVENESS_H_ + +#include +#include + +namespace spvtools { +namespace opt { + +class IRContext; +class Instruction; + +namespace analysis { + +class Type; + +// This class represents the liveness of the input variables of a module +class LivenessManager { + public: + LivenessManager(IRContext* ctx); + + // Copy liveness info into |live_locs| and |builtin_locs|. + void GetLiveness(std::unordered_set* live_locs, + std::unordered_set* live_builtins); + + // Return true if builtin |bi| is being analyzed. + bool IsAnalyzedBuiltin(uint32_t bi); + + // Determine starting loc |offset| and the type |cur_type| of + // access chain |ac|. Set |no_loc| to true if no loc found. + // |is_patch| indicates if patch variable. |input| is true + // if input variable, otherwise output variable. + void AnalyzeAccessChainLoc(const Instruction* ac, + const analysis::Type** curr_type, uint32_t* offset, + bool* no_loc, bool is_patch, bool input = true); + + // Return size of |type_id| in units of locations + uint32_t GetLocSize(const analysis::Type* type) const; + + private: + IRContext* context() const { return ctx_; } + + // Initialize analysis + void InitializeAnalysis(); + + // Analyze |id| for builtin var and struct members. Return true if builtins + // found. + bool AnalyzeBuiltIn(uint32_t id); + + // Mark all live locations resulting from |user| of |var| at |loc|. + void MarkRefLive(const Instruction* user, Instruction* var); + + // Mark |count| locations starting at location |start|. + void MarkLocsLive(uint32_t start, uint32_t count); + + // Return type of component of aggregate type |agg_type| at |index| + const analysis::Type* GetComponentType(uint32_t index, + const analysis::Type* agg_type) const; + + // Return offset of |index| into aggregate type |agg_type| in units of + // input locations + uint32_t GetLocOffset(uint32_t index, const analysis::Type* agg_type) const; + + // Populate live_locs_ and live_builtins_ + void ComputeLiveness(); + + // IR context that owns this liveness manager. + IRContext* ctx_; + + // True if live_locs_ and live_builtins_ are computed + bool computed_; + + // Live locations + std::unordered_set live_locs_; + + // Live builtins + std::unordered_set live_builtins_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LIVENESS_H_ diff --git a/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp b/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp index d11682f34..66e881336 100644 --- a/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp @@ -23,16 +23,13 @@ namespace spvtools { namespace opt { - namespace { - -const uint32_t kStoreValIdInIdx = 1; -const uint32_t kAccessChainPtrIdInIdx = 0; - -} // anonymous namespace +constexpr uint32_t kStoreValIdInIdx = 1; +constexpr uint32_t kAccessChainPtrIdInIdx = 0; +} // namespace void LocalAccessChainConvertPass::BuildAndAppendInst( - SpvOp opcode, uint32_t typeId, uint32_t resultId, + spv::Op opcode, uint32_t typeId, uint32_t resultId, const std::vector& in_opnds, std::vector>* newInsts) { std::unique_ptr newInst( @@ -51,9 +48,9 @@ uint32_t LocalAccessChainConvertPass::BuildAndAppendVarLoad( *varId = ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx); const Instruction* varInst = get_def_use_mgr()->GetDef(*varId); - assert(varInst->opcode() == SpvOpVariable); + assert(varInst->opcode() == spv::Op::OpVariable); *varPteTypeId = GetPointeeTypeId(varInst); - BuildAndAppendInst(SpvOpLoad, *varPteTypeId, ldResultId, + BuildAndAppendInst(spv::Op::OpLoad, *varPteTypeId, ldResultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*varId}}}, newInsts); return ldResultId; @@ -108,7 +105,8 @@ bool LocalAccessChainConvertPass::ReplaceAccessChainLoad( new_inst[0]->UpdateDebugInfoFrom(original_load); context()->get_decoration_mgr()->CloneDecorations( - original_load->result_id(), ldResultId, {SpvDecorationRelaxedPrecision}); + original_load->result_id(), ldResultId, + {spv::Decoration::RelaxedPrecision}); original_load->InsertBefore(std::move(new_inst)); context()->get_debug_info_mgr()->AnalyzeDebugInst( original_load->PreviousNode()); @@ -123,7 +121,7 @@ bool LocalAccessChainConvertPass::ReplaceAccessChainLoad( new_operands.emplace_back( Operand({spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}})); AppendConstantOperands(address_inst, &new_operands); - original_load->SetOpcode(SpvOpCompositeExtract); + original_load->SetOpcode(spv::Op::OpCompositeExtract); original_load->ReplaceOperands(new_operands); context()->UpdateDefUse(original_load); return true; @@ -136,7 +134,7 @@ bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( // An access chain with no indices is essentially a copy. However, we still // have to create a new store because the old ones will be deleted. BuildAndAppendInst( - SpvOpStore, 0, 0, + spv::Op::OpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}}, @@ -154,7 +152,7 @@ bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( } context()->get_decoration_mgr()->CloneDecorations( - varId, ldResultId, {SpvDecorationRelaxedPrecision}); + varId, ldResultId, {spv::Decoration::RelaxedPrecision}); // Build and append Insert const uint32_t insResultId = TakeNextId(); @@ -165,14 +163,14 @@ bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; AppendConstantOperands(ptrInst, &ins_in_opnds); - BuildAndAppendInst(SpvOpCompositeInsert, varPteTypeId, insResultId, + BuildAndAppendInst(spv::Op::OpCompositeInsert, varPteTypeId, insResultId, ins_in_opnds, newInsts); context()->get_decoration_mgr()->CloneDecorations( - varId, insResultId, {SpvDecorationRelaxedPrecision}); + varId, insResultId, {spv::Decoration::RelaxedPrecision}); // Build and append Store - BuildAndAppendInst(SpvOpStore, 0, 0, + BuildAndAppendInst(spv::Op::OpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {insResultId}}}, newInsts); @@ -185,7 +183,7 @@ bool LocalAccessChainConvertPass::Is32BitConstantIndexAccessChain( return acp->WhileEachInId([&inIdx, this](const uint32_t* tid) { if (inIdx > 0) { Instruction* opInst = get_def_use_mgr()->GetDef(*tid); - if (opInst->opcode() != SpvOpConstant) return false; + if (opInst->opcode() != spv::Op::OpConstant) return false; const auto* index = context()->get_constant_mgr()->GetConstantFromInst(opInst); int64_t index_value = index->GetSignExtendedValue(); @@ -204,13 +202,13 @@ bool LocalAccessChainConvertPass::HasOnlySupportedRefs(uint32_t ptrId) { user->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { return true; } - SpvOp op = user->opcode(); - if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) { + spv::Op op = user->opcode(); + if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { if (!HasOnlySupportedRefs(user->result_id())) { return false; } - } else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName && - !IsNonTypeDecorate(op)) { + } else if (op != spv::Op::OpStore && op != spv::Op::OpLoad && + op != spv::Op::OpName && !IsNonTypeDecorate(op)) { return false; } return true; @@ -225,12 +223,12 @@ void LocalAccessChainConvertPass::FindTargetVars(Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case SpvOpStore: - case SpvOpLoad: { + case spv::Op::OpStore: + case spv::Op::OpLoad: { uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsTargetVar(varId)) break; - const SpvOp op = ptrInst->opcode(); + const spv::Op op = ptrInst->opcode(); // Rule out variables with non-supported refs eg function calls if (!HasOnlySupportedRefs(varId)) { seen_non_target_vars_.insert(varId); @@ -276,7 +274,7 @@ Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains( std::vector dead_instructions; for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case SpvOpLoad: { + case spv::Op::OpLoad: { uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) break; @@ -286,7 +284,7 @@ Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains( } modified = true; } break; - case SpvOpStore: { + case spv::Op::OpStore: { uint32_t varId; Instruction* store = &*ii; Instruction* ptrInst = GetPtr(store, &varId); @@ -347,7 +345,7 @@ bool LocalAccessChainConvertPass::AllExtensionsSupported() const { // for the capability. This pass is only looking at function scope symbols, // so we do not care if there are variable pointers on storage buffers. if (context()->get_feature_mgr()->HasCapability( - SpvCapabilityVariablePointers)) + spv::Capability::VariablePointers)) return false; // If any extension not in allowlist, return false for (auto& ei : get_module()->extensions()) { @@ -359,7 +357,7 @@ bool LocalAccessChainConvertPass::AllExtensionsSupported() const { // around unknown extended // instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == SpvOpExtInstImport && + assert(inst.opcode() == spv::Op::OpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -375,7 +373,8 @@ Pass::Status LocalAccessChainConvertPass::ProcessImpl() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; + if (ai.opcode() == spv::Op::OpGroupDecorate) + return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; diff --git a/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.h b/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.h index c3731b1c9..0cda196f6 100644 --- a/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.h +++ b/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.h @@ -64,7 +64,7 @@ class LocalAccessChainConvertPass : public MemPass { // Build instruction from |opcode|, |typeId|, |resultId|, and |in_opnds|. // Append to |newInsts|. - void BuildAndAppendInst(SpvOp opcode, uint32_t typeId, uint32_t resultId, + void BuildAndAppendInst(spv::Op opcode, uint32_t typeId, uint32_t resultId, const std::vector& in_opnds, std::vector>* newInsts); diff --git a/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp b/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp index a58e8e4cc..c1789c885 100644 --- a/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp @@ -24,10 +24,8 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kStoreValIdInIdx = 1; - -} // anonymous namespace +constexpr uint32_t kStoreValIdInIdx = 1; +} // namespace bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; @@ -37,13 +35,13 @@ bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { dbg_op == CommonDebugInfoDebugValue) { return true; } - SpvOp op = user->opcode(); - if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) { + spv::Op op = user->opcode(); + if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { if (!HasOnlySupportedRefs(user->result_id())) { return false; } - } else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName && - !IsNonTypeDecorate(op)) { + } else if (op != spv::Op::OpStore && op != spv::Op::OpLoad && + op != spv::Op::OpName && !IsNonTypeDecorate(op)) { return false; } return true; @@ -68,7 +66,7 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( for (auto ii = next; ii != bi->end(); ii = next) { ++next; switch (ii->opcode()) { - case SpvOpStore: { + case spv::Op::OpStore: { // Verify store variable is target type uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); @@ -77,7 +75,7 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( // If a store to the whole variable, remember it for succeeding // loads and stores. Otherwise forget any previous store to that // variable. - if (ptrInst->opcode() == SpvOpVariable) { + if (ptrInst->opcode() == spv::Op::OpVariable) { // If a previous store to same variable, mark the store // for deletion if not still used. Don't delete store // if debugging; let ssa-rewrite and DCE handle it @@ -114,14 +112,14 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( var2load_.erase(varId); } } break; - case SpvOpLoad: { + case spv::Op::OpLoad: { // Verify store variable is target type uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsTargetVar(varId)) continue; if (!HasOnlySupportedRefs(varId)) continue; uint32_t replId = 0; - if (ptrInst->opcode() == SpvOpVariable) { + if (ptrInst->opcode() == spv::Op::OpVariable) { // If a load from a variable, look for a previous store or // load from that variable and use its value. auto si = var2store_.find(varId); @@ -146,11 +144,11 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( instructions_to_kill.push_back(&*ii); modified = true; } else { - if (ptrInst->opcode() == SpvOpVariable) + if (ptrInst->opcode() == spv::Op::OpVariable) var2load_[varId] = &*ii; // register load } } break; - case SpvOpFunctionCall: { + case spv::Op::OpFunctionCall: { // Conservatively assume all locals are redefined for now. // TODO(): Handle more optimally var2store_.clear(); @@ -192,7 +190,7 @@ bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const { // around unknown extended // instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == SpvOpExtInstImport && + assert(inst.opcode() == spv::Op::OpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -205,14 +203,15 @@ bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const { Pass::Status LocalSingleBlockLoadStoreElimPass::ProcessImpl() { // Assumes relaxed logical addressing only (see instruction.h). - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) return Status::SuccessWithoutChange; // Do not process if module contains OpGroupDecorate. Additional // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; + if (ai.opcode() == spv::Op::OpGroupDecorate) + return Status::SuccessWithoutChange; // If any extensions in the module are not explicitly supported, // return unmodified. if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; diff --git a/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp b/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp index 81648c7ba..e494689fa 100644 --- a/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp @@ -23,13 +23,10 @@ namespace spvtools { namespace opt { - namespace { - -const uint32_t kStoreValIdInIdx = 1; -const uint32_t kVariableInitIdInIdx = 1; - -} // anonymous namespace +constexpr uint32_t kStoreValIdInIdx = 1; +constexpr uint32_t kVariableInitIdInIdx = 1; +} // namespace bool LocalSingleStoreElimPass::LocalSingleStoreElim(Function* func) { bool modified = false; @@ -37,7 +34,7 @@ bool LocalSingleStoreElimPass::LocalSingleStoreElim(Function* func) { // Check all function scope variables in |func|. BasicBlock* entry_block = &*func->begin(); for (Instruction& inst : *entry_block) { - if (inst.opcode() != SpvOpVariable) { + if (inst.opcode() != spv::Op::OpVariable) { break; } @@ -57,7 +54,7 @@ bool LocalSingleStoreElimPass::AllExtensionsSupported() const { // around unknown extended // instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == SpvOpExtInstImport && + assert(inst.opcode() == spv::Op::OpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -70,7 +67,7 @@ bool LocalSingleStoreElimPass::AllExtensionsSupported() const { Pass::Status LocalSingleStoreElimPass::ProcessImpl() { // Assumes relaxed logical addressing only (see instruction.h) - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled @@ -194,7 +191,7 @@ Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses( for (Instruction* user : users) { switch (user->opcode()) { - case SpvOpStore: + case spv::Op::OpStore: // Since we are in the relaxed addressing mode, the use has to be the // base address of the store, and not the value being store. Otherwise, // we would have a pointer to a pointer to function scope memory, which @@ -206,19 +203,19 @@ Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses( return nullptr; } break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: if (FeedsAStore(user)) { // Has a partial store. Cannot propagate that. return nullptr; } break; - case SpvOpLoad: - case SpvOpImageTexelPointer: - case SpvOpName: - case SpvOpCopyObject: + case spv::Op::OpLoad: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpName: + case spv::Op::OpCopyObject: break; - case SpvOpExtInst: { + case spv::Op::OpExtInst: { auto dbg_op = user->GetCommonDebugOpcode(); if (dbg_op == CommonDebugInfoDebugDeclare || dbg_op == CommonDebugInfoDebugValue) { @@ -243,7 +240,7 @@ void LocalSingleStoreElimPass::FindUses( analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); def_use_mgr->ForEachUser(var_inst, [users, this](Instruction* user) { users->push_back(user); - if (user->opcode() == SpvOpCopyObject) { + if (user->opcode() == spv::Op::OpCopyObject) { FindUses(user, users); } }); @@ -253,15 +250,15 @@ bool LocalSingleStoreElimPass::FeedsAStore(Instruction* inst) const { analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); return !def_use_mgr->WhileEachUser(inst, [this](Instruction* user) { switch (user->opcode()) { - case SpvOpStore: + case spv::Op::OpStore: return false; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpCopyObject: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpCopyObject: return !FeedsAStore(user); - case SpvOpLoad: - case SpvOpImageTexelPointer: - case SpvOpName: + case spv::Op::OpLoad: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpName: return true; default: // Don't know if this instruction modifies the variable. @@ -279,7 +276,7 @@ bool LocalSingleStoreElimPass::RewriteLoads( context()->GetDominatorAnalysis(store_block->GetParent()); uint32_t stored_id; - if (store_inst->opcode() == SpvOpStore) + if (store_inst->opcode() == spv::Op::OpStore) stored_id = store_inst->GetSingleWordInOperand(kStoreValIdInIdx); else stored_id = store_inst->GetSingleWordInOperand(kVariableInitIdInIdx); @@ -287,12 +284,12 @@ bool LocalSingleStoreElimPass::RewriteLoads( *all_rewritten = true; bool modified = false; for (Instruction* use : uses) { - if (use->opcode() == SpvOpStore) continue; + if (use->opcode() == spv::Op::OpStore) continue; auto dbg_op = use->GetCommonDebugOpcode(); if (dbg_op == CommonDebugInfoDebugDeclare || dbg_op == CommonDebugInfoDebugValue) continue; - if (use->opcode() == SpvOpLoad && + if (use->opcode() == spv::Op::OpLoad && dominator_analysis->Dominates(store_inst, use)) { modified = true; context()->KillNamesAndDecorates(use->result_id()); diff --git a/3rdparty/spirv-tools/source/opt/loop_dependence.cpp b/3rdparty/spirv-tools/source/opt/loop_dependence.cpp index d8de699bf..d7256bf84 100644 --- a/3rdparty/spirv-tools/source/opt/loop_dependence.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_dependence.cpp @@ -192,8 +192,8 @@ bool LoopDependenceAnalysis::GetDependence(const Instruction* source, Instruction* destination_access_chain = GetOperandDefinition(destination, 0); auto num_access_chains = - (source_access_chain->opcode() == SpvOpAccessChain) + - (destination_access_chain->opcode() == SpvOpAccessChain); + (source_access_chain->opcode() == spv::Op::OpAccessChain) + + (destination_access_chain->opcode() == spv::Op::OpAccessChain); // If neither is an access chain, then they are load/store to a variable. if (num_access_chains == 0) { @@ -211,7 +211,8 @@ bool LoopDependenceAnalysis::GetDependence(const Instruction* source, // If only one is an access chain, it could be accessing a part of a struct if (num_access_chains == 1) { - auto source_is_chain = source_access_chain->opcode() == SpvOpAccessChain; + auto source_is_chain = + source_access_chain->opcode() == spv::Op::OpAccessChain; auto access_chain = source_is_chain ? source_access_chain : destination_access_chain; auto variable = @@ -238,8 +239,8 @@ bool LoopDependenceAnalysis::GetDependence(const Instruction* source, GetOperandDefinition(destination_access_chain, 0); // Nested access chains are not supported yet, bail out. - if (source_array->opcode() == SpvOpAccessChain || - destination_array->opcode() == SpvOpAccessChain) { + if (source_array->opcode() == spv::Op::OpAccessChain || + destination_array->opcode() == spv::Op::OpAccessChain) { for (auto& entry : distance_vector->GetEntries()) { entry = DistanceEntry(); } diff --git a/3rdparty/spirv-tools/source/opt/loop_dependence_helpers.cpp b/3rdparty/spirv-tools/source/opt/loop_dependence_helpers.cpp index de27a0a72..929c9404b 100644 --- a/3rdparty/spirv-tools/source/opt/loop_dependence_helpers.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_dependence_helpers.cpp @@ -54,20 +54,20 @@ SENode* LoopDependenceAnalysis::GetLowerBound(const Loop* loop) { } Instruction* lower_inst = GetOperandDefinition(cond_inst, 0); switch (cond_inst->opcode()) { - case SpvOpULessThan: - case SpvOpSLessThan: - case SpvOpULessThanEqual: - case SpvOpSLessThanEqual: - case SpvOpUGreaterThan: - case SpvOpSGreaterThan: - case SpvOpUGreaterThanEqual: - case SpvOpSGreaterThanEqual: { + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: { // If we have a phi we are looking at the induction variable. We look // through the phi to the initial value of the phi upon entering the loop. - if (lower_inst->opcode() == SpvOpPhi) { + if (lower_inst->opcode() == spv::Op::OpPhi) { lower_inst = GetOperandDefinition(lower_inst, 0); // We don't handle looking through multiple phis. - if (lower_inst->opcode() == SpvOpPhi) { + if (lower_inst->opcode() == spv::Op::OpPhi) { return nullptr; } } @@ -86,8 +86,8 @@ SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { } Instruction* upper_inst = GetOperandDefinition(cond_inst, 1); switch (cond_inst->opcode()) { - case SpvOpULessThan: - case SpvOpSLessThan: { + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: { // When we have a < condition we must subtract 1 from the analyzed upper // instruction. SENode* upper_bound = scalar_evolution_.SimplifyExpression( @@ -96,8 +96,8 @@ SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { scalar_evolution_.CreateConstant(1))); return upper_bound; } - case SpvOpUGreaterThan: - case SpvOpSGreaterThan: { + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: { // When we have a > condition we must add 1 to the analyzed upper // instruction. SENode* upper_bound = @@ -106,10 +106,10 @@ SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { scalar_evolution_.CreateConstant(1))); return upper_bound; } - case SpvOpULessThanEqual: - case SpvOpSLessThanEqual: - case SpvOpUGreaterThanEqual: - case SpvOpSGreaterThanEqual: { + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: { // We don't need to modify the results of analyzing when we have <= or >=. SENode* upper_bound = scalar_evolution_.SimplifyExpression( scalar_evolution_.AnalyzeInstruction(upper_inst)); diff --git a/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp b/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp index 13982d181..172b97815 100644 --- a/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp @@ -39,7 +39,7 @@ namespace opt { Instruction* Loop::GetInductionStepOperation( const Instruction* induction) const { // Induction must be a phi instruction. - assert(induction->opcode() == SpvOpPhi); + assert(induction->opcode() == spv::Op::OpPhi); Instruction* step = nullptr; @@ -75,8 +75,8 @@ Instruction* Loop::GetInductionStepOperation( return nullptr; } - if (def_use_manager->GetDef(lhs)->opcode() != SpvOp::SpvOpConstant && - def_use_manager->GetDef(rhs)->opcode() != SpvOp::SpvOpConstant) { + if (def_use_manager->GetDef(lhs)->opcode() != spv::Op::OpConstant && + def_use_manager->GetDef(rhs)->opcode() != spv::Op::OpConstant) { return nullptr; } @@ -85,31 +85,31 @@ Instruction* Loop::GetInductionStepOperation( // Returns true if the |step| operation is an induction variable step operation // which is currently handled. -bool Loop::IsSupportedStepOp(SpvOp step) const { +bool Loop::IsSupportedStepOp(spv::Op step) const { switch (step) { - case SpvOp::SpvOpISub: - case SpvOp::SpvOpIAdd: + case spv::Op::OpISub: + case spv::Op::OpIAdd: return true; default: return false; } } -bool Loop::IsSupportedCondition(SpvOp condition) const { +bool Loop::IsSupportedCondition(spv::Op condition) const { switch (condition) { // < - case SpvOp::SpvOpULessThan: - case SpvOp::SpvOpSLessThan: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: // > - case SpvOp::SpvOpUGreaterThan: - case SpvOp::SpvOpSGreaterThan: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: // >= - case SpvOp::SpvOpSGreaterThanEqual: - case SpvOp::SpvOpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: // <= - case SpvOp::SpvOpSLessThanEqual: - case SpvOp::SpvOpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpULessThanEqual: return true; default: @@ -117,7 +117,8 @@ bool Loop::IsSupportedCondition(SpvOp condition) const { } } -int64_t Loop::GetResidualConditionValue(SpvOp condition, int64_t initial_value, +int64_t Loop::GetResidualConditionValue(spv::Op condition, + int64_t initial_value, int64_t step_value, size_t number_of_iterations, size_t factor) { @@ -128,13 +129,13 @@ int64_t Loop::GetResidualConditionValue(SpvOp condition, int64_t initial_value, // loop where just less than or greater than. Adding or subtracting one should // give a functionally equivalent value. switch (condition) { - case SpvOp::SpvOpSGreaterThanEqual: - case SpvOp::SpvOpUGreaterThanEqual: { + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: { remainder -= 1; break; } - case SpvOp::SpvOpSLessThanEqual: - case SpvOp::SpvOpULessThanEqual: { + case spv::Op::OpSLessThanEqual: + case spv::Op::OpULessThanEqual: { remainder += 1; break; } @@ -152,7 +153,7 @@ Instruction* Loop::GetConditionInst() const { } Instruction* branch_conditional = &*condition_block->tail(); if (!branch_conditional || - branch_conditional->opcode() != SpvOpBranchConditional) { + branch_conditional->opcode() != spv::Op::OpBranchConditional) { return nullptr; } Instruction* condition_inst = context_->get_def_use_mgr()->GetDef( @@ -318,7 +319,7 @@ void Loop::SetMergeBlock(BasicBlock* merge) { void Loop::SetPreHeaderBlock(BasicBlock* preheader) { if (preheader) { assert(!IsInsideLoop(preheader) && "The preheader block is in the loop"); - assert(preheader->tail()->opcode() == SpvOpBranch && + assert(preheader->tail()->opcode() == spv::Op::OpBranch && "The preheader block does not unconditionally branch to the header " "block"); assert(preheader->tail()->GetSingleWordOperand(0) == @@ -387,7 +388,7 @@ void Loop::GetMergingBlocks( namespace { -static inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) { +inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) { for (Instruction& inst : *bb) { if (!inst.IsBranch() && !context->IsCombinatorInstruction(&inst)) return false; @@ -443,7 +444,7 @@ bool Loop::IsLCSSA() const { BasicBlock* parent = ir_context->get_instr_block(use); assert(parent && "Invalid analysis"); if (IsInsideLoop(parent)) return true; - if (use->opcode() != SpvOpPhi) return false; + if (use->opcode() != spv::Op::OpPhi) return false; return exit_blocks.count(parent->id()); })) return false; @@ -486,7 +487,7 @@ void Loop::ComputeLoopStructuredOrder( ordered_loop_blocks->push_back(loop_preheader_); bool is_shader = - context_->get_feature_mgr()->HasCapability(SpvCapabilityShader); + context_->get_feature_mgr()->HasCapability(spv::Capability::Shader); if (!is_shader) { cfg.ForEachBlockInReversePostOrder( loop_header_, [ordered_loop_blocks, this](BasicBlock* bb) { @@ -647,7 +648,7 @@ BasicBlock* Loop::FindConditionBlock() const { const Instruction& branch = *bb->ctail(); // Make sure the branch is a conditional branch. - if (branch.opcode() != SpvOpBranchConditional) return nullptr; + if (branch.opcode() != spv::Op::OpBranchConditional) return nullptr; // Make sure one of the two possible branches is to the merge block. if (branch.GetSingleWordInOperand(1) == loop_merge_->id() || @@ -716,7 +717,7 @@ bool Loop::FindNumberOfIterations(const Instruction* induction, } // If this is a subtraction step we should negate the step value. - if (step_inst->opcode() == SpvOp::SpvOpISub) { + if (step_inst->opcode() == spv::Op::OpISub) { step_value = -step_value; } @@ -753,7 +754,7 @@ bool Loop::FindNumberOfIterations(const Instruction* induction, // |step_value| where diff is calculated differently according to the // |condition| and uses the |condition_value| and |init_value|. If diff / // |step_value| is NOT cleanly divisible then we add one to the sum. -int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, +int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, int64_t init_value, int64_t step_value) const { if (step_value == 0) { return 0; @@ -762,8 +763,8 @@ int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, int64_t diff = 0; switch (condition) { - case SpvOp::SpvOpSLessThan: - case SpvOp::SpvOpULessThan: { + case spv::Op::OpSLessThan: + case spv::Op::OpULessThan: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value < condition_value)) return 0; @@ -778,8 +779,8 @@ int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, break; } - case SpvOp::SpvOpSGreaterThan: - case SpvOp::SpvOpUGreaterThan: { + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThan: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value > condition_value)) return 0; @@ -795,12 +796,12 @@ int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, break; } - case SpvOp::SpvOpSGreaterThanEqual: - case SpvOp::SpvOpUGreaterThanEqual: { + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value >= condition_value)) return 0; - // We subtract one to make it the same as SpvOpGreaterThan as it is + // We subtract one to make it the same as spv::Op::OpGreaterThan as it is // functionally equivalent. diff = init_value - (condition_value - 1); @@ -814,13 +815,13 @@ int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, break; } - case SpvOp::SpvOpSLessThanEqual: - case SpvOp::SpvOpULessThanEqual: { + case spv::Op::OpSLessThanEqual: + case spv::Op::OpULessThanEqual: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value <= condition_value)) return 0; - // We add one to make it the same as SpvOpLessThan as it is functionally - // equivalent. + // We add one to make it the same as spv::Op::OpLessThan as it is + // functionally equivalent. diff = (condition_value + 1) - init_value; // If the operation is a less than operation then the diff and step must @@ -854,7 +855,7 @@ int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, void Loop::GetInductionVariables( std::vector& induction_variables) const { for (Instruction& inst : *loop_header_) { - if (inst.opcode() == SpvOp::SpvOpPhi) { + if (inst.opcode() == spv::Op::OpPhi) { induction_variables.push_back(&inst); } } @@ -867,7 +868,7 @@ Instruction* Loop::FindConditionVariable( Instruction* induction = nullptr; // Verify that the branch instruction is a conditional branch. - if (branch_inst.opcode() == SpvOp::SpvOpBranchConditional) { + if (branch_inst.opcode() == spv::Op::OpBranchConditional) { // From the branch instruction find the branch condition. analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); @@ -883,7 +884,8 @@ Instruction* Loop::FindConditionVariable( def_use_manager->GetDef(condition->GetSingleWordOperand(2)); // Make sure the variable instruction used is a phi. - if (!variable_inst || variable_inst->opcode() != SpvOpPhi) return nullptr; + if (!variable_inst || variable_inst->opcode() != spv::Op::OpPhi) + return nullptr; // Make sure the phi instruction only has two incoming blocks. Each // incoming block will be represented by two in operands in the phi diff --git a/3rdparty/spirv-tools/source/opt/loop_descriptor.h b/3rdparty/spirv-tools/source/opt/loop_descriptor.h index df012274c..35256bc3f 100644 --- a/3rdparty/spirv-tools/source/opt/loop_descriptor.h +++ b/3rdparty/spirv-tools/source/opt/loop_descriptor.h @@ -316,12 +316,12 @@ class Loop { // Returns true if we can deduce the number of loop iterations in the step // operation |step|. IsSupportedCondition must also be true for the condition // instruction. - bool IsSupportedStepOp(SpvOp step) const; + bool IsSupportedStepOp(spv::Op step) const; // Returns true if we can deduce the number of loop iterations in the // condition operation |condition|. IsSupportedStepOp must also be true for // the step instruction. - bool IsSupportedCondition(SpvOp condition) const; + bool IsSupportedCondition(spv::Op condition) const; // Creates the list of the loop's basic block in structured order and store // the result in |ordered_loop_blocks|. If |include_pre_header| is true, the @@ -335,7 +335,7 @@ class Loop { // Given the loop |condition|, |initial_value|, |step_value|, the trip count // |number_of_iterations|, and the |unroll_factor| requested, get the new // condition value for the residual loop. - static int64_t GetResidualConditionValue(SpvOp condition, + static int64_t GetResidualConditionValue(spv::Op condition, int64_t initial_value, int64_t step_value, size_t number_of_iterations, @@ -400,7 +400,7 @@ class Loop { // the induction variable. This method will return the number of iterations in // a loop with those values for a given |condition|. Returns 0 if the number // of iterations could not be computed. - int64_t GetIterations(SpvOp condition, int64_t condition_value, + int64_t GetIterations(spv::Op condition, int64_t condition_value, int64_t init_value, int64_t step_value) const; // This is to allow for loops to be removed mid iteration without invalidating diff --git a/3rdparty/spirv-tools/source/opt/loop_fission.cpp b/3rdparty/spirv-tools/source/opt/loop_fission.cpp index b4df8c621..2ae05c3c3 100644 --- a/3rdparty/spirv-tools/source/opt/loop_fission.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_fission.cpp @@ -110,10 +110,10 @@ class LoopFissionImpl { }; bool LoopFissionImpl::MovableInstruction(const Instruction& inst) const { - return inst.opcode() == SpvOp::SpvOpLoad || - inst.opcode() == SpvOp::SpvOpStore || - inst.opcode() == SpvOp::SpvOpSelectionMerge || - inst.opcode() == SpvOp::SpvOpPhi || inst.IsOpcodeCodeMotionSafe(); + return inst.opcode() == spv::Op::OpLoad || + inst.opcode() == spv::Op::OpStore || + inst.opcode() == spv::Op::OpSelectionMerge || + inst.opcode() == spv::Op::OpPhi || inst.IsOpcodeCodeMotionSafe(); } void LoopFissionImpl::TraverseUseDef(Instruction* inst, @@ -143,14 +143,14 @@ void LoopFissionImpl::TraverseUseDef(Instruction* inst, // same labels (i.e phis). We already preempt the inclusion of // OpSelectionMerge by adding related instructions to the seen_instructions_ // set. - if (user->opcode() == SpvOp::SpvOpLoopMerge || - user->opcode() == SpvOp::SpvOpLabel) + if (user->opcode() == spv::Op::OpLoopMerge || + user->opcode() == spv::Op::OpLabel) return; // If the |report_loads| flag is set, set the class field // load_used_in_condition_ to false. This is used to check that none of the // condition checks in the loop rely on loads. - if (user->opcode() == SpvOp::SpvOpLoad && report_loads) { + if (user->opcode() == spv::Op::OpLoad && report_loads) { load_used_in_condition_ = true; } @@ -167,7 +167,7 @@ void LoopFissionImpl::TraverseUseDef(Instruction* inst, user->ForEachInOperand(traverse_operand); // For the first traversal we want to ignore the users of the phi. - if (ignore_phi_users && user->opcode() == SpvOp::SpvOpPhi) return; + if (ignore_phi_users && user->opcode() == spv::Op::OpPhi) return; // Traverse each user with this lambda. def_use->ForEachUser(user, traverser_functor); @@ -214,7 +214,7 @@ bool LoopFissionImpl::GroupInstructionsByUseDef() { for (Instruction& inst : block) { // Ignore all instructions related to control flow. - if (inst.opcode() == SpvOp::SpvOpSelectionMerge || inst.IsBranch()) { + if (inst.opcode() == spv::Op::OpSelectionMerge || inst.IsBranch()) { TraverseUseDef(&inst, &instructions_to_ignore, true, true); } } @@ -229,8 +229,8 @@ bool LoopFissionImpl::GroupInstructionsByUseDef() { for (Instruction& inst : block) { // Record the order that each load/store is seen. - if (inst.opcode() == SpvOp::SpvOpLoad || - inst.opcode() == SpvOp::SpvOpStore) { + if (inst.opcode() == spv::Op::OpLoad || + inst.opcode() == spv::Op::OpStore) { instruction_order_[&inst] = instruction_order_.size(); } @@ -292,9 +292,9 @@ bool LoopFissionImpl::CanPerformSplit() { // Populate the above lists. for (Instruction* inst : cloned_loop_instructions_) { - if (inst->opcode() == SpvOp::SpvOpStore) { + if (inst->opcode() == spv::Op::OpStore) { set_one_stores.push_back(inst); - } else if (inst->opcode() == SpvOp::SpvOpLoad) { + } else if (inst->opcode() == spv::Op::OpLoad) { set_one_loads.push_back(inst); } @@ -316,7 +316,7 @@ bool LoopFissionImpl::CanPerformSplit() { // Look at the dependency between the loads in the original and stores in // the cloned loops. - if (inst->opcode() == SpvOp::SpvOpLoad) { + if (inst->opcode() == spv::Op::OpLoad) { for (Instruction* store : set_one_stores) { DistanceVector vec{loop_depth}; @@ -334,7 +334,7 @@ bool LoopFissionImpl::CanPerformSplit() { } } } - } else if (inst->opcode() == SpvOp::SpvOpStore) { + } else if (inst->opcode() == spv::Op::OpStore) { for (Instruction* load : set_one_loads) { DistanceVector vec{loop_depth}; @@ -387,7 +387,7 @@ Loop* LoopFissionImpl::SplitLoop() { if (cloned_loop_instructions_.count(&inst) == 1 && original_loop_instructions_.count(&inst) == 0) { instructions_to_kill.push_back(&inst); - if (inst.opcode() == SpvOp::SpvOpPhi) { + if (inst.opcode() == spv::Op::OpPhi) { context_->ReplaceAllUsesWith( inst.result_id(), clone_results.value_map_[inst.result_id()]); } diff --git a/3rdparty/spirv-tools/source/opt/loop_fusion.cpp b/3rdparty/spirv-tools/source/opt/loop_fusion.cpp index f3aab2837..dc6355306 100644 --- a/3rdparty/spirv-tools/source/opt/loop_fusion.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_fusion.cpp @@ -23,7 +23,6 @@ namespace spvtools { namespace opt { - namespace { // Append all the loops nested in |loop| to |loops|. @@ -193,14 +192,15 @@ bool LoopFusion::AreCompatible() { // in LCSSA form. for (auto block : block_to_check) { for (auto& inst : *block) { - if (inst.opcode() == SpvOpStore) { + if (inst.opcode() == spv::Op::OpStore) { // Get the definition of the target to check it's function scope so // there are no observable side effects. auto variable = context_->get_def_use_mgr()->GetDef(inst.GetSingleWordInOperand(0)); - if (variable->opcode() != SpvOpVariable || - variable->GetSingleWordInOperand(0) != SpvStorageClassFunction) { + if (variable->opcode() != spv::Op::OpVariable || + spv::StorageClass(variable->GetSingleWordInOperand(0)) != + spv::StorageClass::Function) { return false; } @@ -209,7 +209,7 @@ bool LoopFusion::AreCompatible() { context_->get_def_use_mgr()->ForEachUse( inst.GetSingleWordInOperand(0), [&is_used](Instruction* use_inst, uint32_t) { - if (use_inst->opcode() == SpvOpLoad) { + if (use_inst->opcode() == spv::Op::OpLoad) { is_used = true; } }); @@ -217,11 +217,11 @@ bool LoopFusion::AreCompatible() { if (is_used) { return false; } - } else if (inst.opcode() == SpvOpPhi) { + } else if (inst.opcode() == spv::Op::OpPhi) { if (inst.NumInOperands() != 2) { return false; } - } else if (inst.opcode() != SpvOpBranch) { + } else if (inst.opcode() != spv::Op::OpBranch) { return false; } } @@ -234,10 +234,12 @@ bool LoopFusion::ContainsBarriersOrFunctionCalls(Loop* loop) { for (const auto& block : loop->GetBlocks()) { for (const auto& inst : *containing_function_->FindBlock(block)) { auto opcode = inst.opcode(); - if (opcode == SpvOpFunctionCall || opcode == SpvOpControlBarrier || - opcode == SpvOpMemoryBarrier || opcode == SpvOpTypeNamedBarrier || - opcode == SpvOpNamedBarrierInitialize || - opcode == SpvOpMemoryNamedBarrier) { + if (opcode == spv::Op::OpFunctionCall || + opcode == spv::Op::OpControlBarrier || + opcode == spv::Op::OpMemoryBarrier || + opcode == spv::Op::OpTypeNamedBarrier || + opcode == spv::Op::OpNamedBarrierInitialize || + opcode == spv::Op::OpMemoryNamedBarrier) { return true; } } @@ -344,7 +346,7 @@ std::map> LoopFusion::LocationToMemOps( auto access_location = context_->get_def_use_mgr()->GetDef( instruction->GetSingleWordInOperand(0)); - while (access_location->opcode() == SpvOpAccessChain) { + while (access_location->opcode() == spv::Op::OpAccessChain) { access_location = context_->get_def_use_mgr()->GetDef( access_location->GetSingleWordInOperand(0)); } @@ -366,9 +368,9 @@ LoopFusion::GetLoadsAndStoresInLoop(Loop* loop) { } for (auto& instruction : *containing_function_->FindBlock(block_id)) { - if (instruction.opcode() == SpvOpLoad) { + if (instruction.opcode() == spv::Op::OpLoad) { loads.push_back(&instruction); - } else if (instruction.opcode() == SpvOpStore) { + } else if (instruction.opcode() == spv::Op::OpStore) { stores.push_back(&instruction); } } @@ -556,7 +558,7 @@ void LoopFusion::Fuse() { // Update merge block id in the header of |loop_0_| to the merge block of // |loop_1_|. loop_0_->GetHeaderBlock()->ForEachInst([this](Instruction* inst) { - if (inst->opcode() == SpvOpLoopMerge) { + if (inst->opcode() == spv::Op::OpLoopMerge) { inst->SetInOperand(0, {loop_1_->GetMergeBlock()->id()}); } }); @@ -564,7 +566,7 @@ void LoopFusion::Fuse() { // Update condition branch target in |loop_0_| to the merge block of // |loop_1_|. condition_block_of_0->ForEachInst([this](Instruction* inst) { - if (inst->opcode() == SpvOpBranchConditional) { + if (inst->opcode() == spv::Op::OpBranchConditional) { auto loop_0_merge_block_id = loop_0_->GetMergeBlock()->id(); if (inst->GetSingleWordInOperand(1) == loop_0_merge_block_id) { @@ -579,7 +581,8 @@ void LoopFusion::Fuse() { // the header of |loop_1_| to the header of |loop_0_|. std::vector instructions_to_move{}; for (auto& instruction : *loop_1_->GetHeaderBlock()) { - if (instruction.opcode() == SpvOpPhi && &instruction != induction_1_) { + if (instruction.opcode() == spv::Op::OpPhi && + &instruction != induction_1_) { instructions_to_move.push_back(&instruction); } } diff --git a/3rdparty/spirv-tools/source/opt/loop_peeling.cpp b/3rdparty/spirv-tools/source/opt/loop_peeling.cpp index 34f0a8d26..d51227303 100644 --- a/3rdparty/spirv-tools/source/opt/loop_peeling.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_peeling.cpp @@ -29,6 +29,21 @@ namespace spvtools { namespace opt { +namespace { +// Gather the set of blocks for all the path from |entry| to |root|. +void GetBlocksInPath(uint32_t block, uint32_t entry, + std::unordered_set* blocks_in_path, + const CFG& cfg) { + for (uint32_t pid : cfg.preds(block)) { + if (blocks_in_path->insert(pid).second) { + if (pid != entry) { + GetBlocksInPath(pid, entry, blocks_in_path, cfg); + } + } + } +} +} // namespace + size_t LoopPeelingPass::code_grow_threshold_ = 1000; void LoopPeeling::DuplicateAndConnectLoop( @@ -186,7 +201,7 @@ void LoopPeeling::GetIteratorUpdateOperations( operations->insert(iterator); iterator->ForEachInId([def_use_mgr, loop, operations, this](uint32_t* id) { Instruction* insn = def_use_mgr->GetDef(*id); - if (insn->opcode() == SpvOpLabel) { + if (insn->opcode() == spv::Op::OpLabel) { return; } if (operations->count(insn)) { @@ -199,19 +214,6 @@ void LoopPeeling::GetIteratorUpdateOperations( }); } -// Gather the set of blocks for all the path from |entry| to |root|. -static void GetBlocksInPath(uint32_t block, uint32_t entry, - std::unordered_set* blocks_in_path, - const CFG& cfg) { - for (uint32_t pid : cfg.preds(block)) { - if (blocks_in_path->insert(pid).second) { - if (pid != entry) { - GetBlocksInPath(pid, entry, blocks_in_path, cfg); - } - } - } -} - bool LoopPeeling::IsConditionCheckSideEffectFree() const { CFG& cfg = *context_->cfg(); @@ -231,9 +233,9 @@ bool LoopPeeling::IsConditionCheckSideEffectFree() const { if (!bb->WhileEachInst([this](Instruction* insn) { if (insn->IsBranch()) return true; switch (insn->opcode()) { - case SpvOpLabel: - case SpvOpSelectionMerge: - case SpvOpLoopMerge: + case spv::Op::OpLabel: + case spv::Op::OpSelectionMerge: + case spv::Op::OpLoopMerge: return true; default: break; @@ -322,7 +324,7 @@ void LoopPeeling::FixExitCondition( BasicBlock* condition_block = cfg.block(condition_block_id); Instruction* exit_condition = condition_block->terminator(); - assert(exit_condition->opcode() == SpvOpBranchConditional); + assert(exit_condition->opcode() == spv::Op::OpBranchConditional); BasicBlock::iterator insert_point = condition_block->tail(); if (condition_block->GetMergeInst()) { --insert_point; @@ -350,7 +352,7 @@ BasicBlock* LoopPeeling::CreateBlockBefore(BasicBlock* bb) { // TODO(1841): Handle id overflow. std::unique_ptr new_bb = MakeUnique(std::unique_ptr(new Instruction( - context_, SpvOpLabel, 0, context_->TakeNextId(), {}))); + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))); // Update the loop descriptor. Loop* in_loop = (*loop_utils_.GetLoopDescriptor())[bb]; if (in_loop) { @@ -791,18 +793,18 @@ uint32_t LoopPeelingPass::LoopPeelingInfo::GetFirstNonLoopInvariantOperand( return 0; } -static bool IsHandledCondition(SpvOp opcode) { +static bool IsHandledCondition(spv::Op opcode) { switch (opcode) { - case SpvOpIEqual: - case SpvOpINotEqual: - case SpvOpUGreaterThan: - case SpvOpSGreaterThan: - case SpvOpUGreaterThanEqual: - case SpvOpSGreaterThanEqual: - case SpvOpULessThan: - case SpvOpSLessThan: - case SpvOpULessThanEqual: - case SpvOpSLessThanEqual: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: return true; default: return false; @@ -811,7 +813,7 @@ static bool IsHandledCondition(SpvOp opcode) { LoopPeelingPass::LoopPeelingInfo::Direction LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(BasicBlock* bb) const { - if (bb->terminator()->opcode() != SpvOpBranchConditional) { + if (bb->terminator()->opcode() != spv::Op::OpBranchConditional) { return GetNoneDirection(); } @@ -886,27 +888,27 @@ LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(BasicBlock* bb) const { switch (condition->opcode()) { default: return GetNoneDirection(); - case SpvOpIEqual: - case SpvOpINotEqual: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: return HandleEquality(lhs, rhs); - case SpvOpUGreaterThan: - case SpvOpSGreaterThan: { + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: { cmp_operator = CmpOperator::kGT; break; } - case SpvOpULessThan: - case SpvOpSLessThan: { + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: { cmp_operator = CmpOperator::kLT; break; } // We add one to transform >= into > and <= into <. - case SpvOpUGreaterThanEqual: - case SpvOpSGreaterThanEqual: { + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: { cmp_operator = CmpOperator::kGE; break; } - case SpvOpULessThanEqual: - case SpvOpSLessThanEqual: { + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: { cmp_operator = CmpOperator::kLE; break; } diff --git a/3rdparty/spirv-tools/source/opt/loop_unroller.cpp b/3rdparty/spirv-tools/source/opt/loop_unroller.cpp index 6f4e6f413..07b529d49 100644 --- a/3rdparty/spirv-tools/source/opt/loop_unroller.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_unroller.cpp @@ -68,10 +68,10 @@ namespace opt { namespace { // Loop control constant value for DontUnroll flag. -static const uint32_t kLoopControlDontUnrollIndex = 2; +constexpr uint32_t kLoopControlDontUnrollIndex = 2; // Operand index of the loop control parameter of the OpLoopMerge. -static const uint32_t kLoopControlIndex = 2; +constexpr uint32_t kLoopControlIndex = 2; // This utility class encapsulates some of the state we need to maintain between // loop unrolls. Specifically it maintains key blocks and the induction variable @@ -336,8 +336,7 @@ class LoopUnrollerUtilsImpl { // Retrieve the index of the OpPhi instruction |phi| which corresponds to the // incoming |block| id. -static uint32_t GetPhiIndexFromLabel(const BasicBlock* block, - const Instruction* phi) { +uint32_t GetPhiIndexFromLabel(const BasicBlock* block, const Instruction* phi) { for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) { if (block->id() == phi->GetSingleWordInOperand(i)) { return i; @@ -382,7 +381,7 @@ void LoopUnrollerUtilsImpl::PartiallyUnrollResidualFactor(Loop* loop, size_t factor) { // TODO(1841): Handle id overflow. std::unique_ptr new_label{new Instruction( - context_, SpvOp::SpvOpLabel, 0, context_->TakeNextId(), {})}; + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {})}; std::unique_ptr new_exit_bb{new BasicBlock(std::move(new_label))}; new_exit_bb->SetParent(&function_); @@ -991,7 +990,7 @@ bool LoopUtils::CanPerformUnroll() { // Check that we can find and process the induction variable. const Instruction* induction = loop_->FindConditionVariable(condition); - if (!induction || induction->opcode() != SpvOpPhi) return false; + if (!induction || induction->opcode() != spv::Op::OpPhi) return false; // Check that we can find the number of loop iterations. if (!loop_->FindNumberOfIterations(induction, &*condition->ctail(), nullptr)) @@ -1002,7 +1001,7 @@ bool LoopUtils::CanPerformUnroll() { // iteration counts. This can cause timeouts and memouts during fuzzing that // are not classed as bugs. To avoid this noise, loop unrolling is not applied // to loops with large iteration counts when fuzzing. - const size_t kFuzzerIterationLimit = 100; + constexpr size_t kFuzzerIterationLimit = 100; size_t num_iterations; loop_->FindNumberOfIterations(induction, &*condition->ctail(), &num_iterations); @@ -1015,7 +1014,7 @@ bool LoopUtils::CanPerformUnroll() { // block. const Instruction& branch = *loop_->GetLatchBlock()->ctail(); bool branching_assumption = - branch.opcode() == SpvOpBranch && + branch.opcode() == spv::Op::OpBranch && branch.GetSingleWordInOperand(0) == loop_->GetHeaderBlock()->id(); if (!branching_assumption) { return false; @@ -1043,10 +1042,10 @@ bool LoopUtils::CanPerformUnroll() { // exit the loop. for (uint32_t label_id : loop_->GetBlocks()) { const BasicBlock* block = context_->cfg()->block(label_id); - if (block->ctail()->opcode() == SpvOp::SpvOpKill || - block->ctail()->opcode() == SpvOp::SpvOpReturn || - block->ctail()->opcode() == SpvOp::SpvOpReturnValue || - block->ctail()->opcode() == SpvOp::SpvOpTerminateInvocation) { + if (block->ctail()->opcode() == spv::Op::OpKill || + block->ctail()->opcode() == spv::Op::OpReturn || + block->ctail()->opcode() == spv::Op::OpReturnValue || + block->ctail()->opcode() == spv::Op::OpTerminateInvocation) { return false; } } diff --git a/3rdparty/spirv-tools/source/opt/loop_unswitch_pass.cpp b/3rdparty/spirv-tools/source/opt/loop_unswitch_pass.cpp index 1ee7e5e22..b00d66de8 100644 --- a/3rdparty/spirv-tools/source/opt/loop_unswitch_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_unswitch_pass.cpp @@ -37,12 +37,7 @@ namespace spvtools { namespace opt { namespace { - -static const uint32_t kTypePointerStorageClassInIdx = 0; - -} // anonymous namespace - -namespace { +constexpr uint32_t kTypePointerStorageClassInIdx = 0; // This class handle the unswitch procedure for a given loop. // The unswitch will not happen if: @@ -77,7 +72,7 @@ class LoopUnswitch { } if (bb->terminator()->IsBranch() && - bb->terminator()->opcode() != SpvOpBranch) { + bb->terminator()->opcode() != spv::Op::OpBranch) { if (IsConditionNonConstantLoopInvariant(bb->terminator())) { switch_block_ = bb; break; @@ -104,7 +99,7 @@ class LoopUnswitch { // TODO(1841): Handle id overflow. BasicBlock* bb = &*ip.InsertBefore(std::unique_ptr( new BasicBlock(std::unique_ptr(new Instruction( - context_, SpvOpLabel, 0, context_->TakeNextId(), {}))))); + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))))); bb->SetParent(function_); def_use_mgr->AnalyzeInstDef(bb->GetLabelInst()); context_->set_instr_block(bb->GetLabelInst(), bb); @@ -113,7 +108,7 @@ class LoopUnswitch { } Instruction* GetValueForDefaultPathForSwitch(Instruction* switch_inst) { - assert(switch_inst->opcode() == SpvOpSwitch && + assert(switch_inst->opcode() == spv::Op::OpSwitch && "The given instructoin must be an OpSwitch."); // Find a value that can be used to select the default path. @@ -291,7 +286,7 @@ class LoopUnswitch { ///////////////////////////// Instruction* iv_condition = &*switch_block_->tail(); - SpvOp iv_opcode = iv_condition->opcode(); + spv::Op iv_opcode = iv_condition->opcode(); Instruction* condition = def_use_mgr->GetDef(iv_condition->GetOperand(0).words[0]); @@ -304,7 +299,7 @@ class LoopUnswitch { std::vector> constant_branch; // Special case for the original loop Instruction* original_loop_constant_value; - if (iv_opcode == SpvOpBranchConditional) { + if (iv_opcode == spv::Op::OpBranchConditional) { constant_branch.emplace_back( cst_mgr->GetDefiningInstruction(cst_mgr->GetConstant(cond_type, {0})), nullptr); @@ -401,7 +396,7 @@ class LoopUnswitch { // Delete the old jump context_->KillInst(&*if_block->tail()); InstructionBuilder builder(context_, if_block); - if (iv_opcode == SpvOpBranchConditional) { + if (iv_opcode == spv::Op::OpBranchConditional) { assert(constant_branch.size() == 1); builder.AddConditionalBranch( condition->result_id(), original_loop_target->id(), @@ -509,7 +504,8 @@ class LoopUnswitch { bool& is_uniform = dynamically_uniform_[var->result_id()]; is_uniform = false; - dec_mgr->WhileEachDecoration(var->result_id(), SpvDecorationUniform, + dec_mgr->WhileEachDecoration(var->result_id(), + uint32_t(spv::Decoration::Uniform), [&is_uniform](const Instruction&) { is_uniform = true; return false; @@ -526,14 +522,14 @@ class LoopUnswitch { if (!post_dom_tree.Dominates(parent->id(), entry->id())) { return is_uniform = false; } - if (var->opcode() == SpvOpLoad) { + if (var->opcode() == spv::Op::OpLoad) { const uint32_t PtrTypeId = def_use_mgr->GetDef(var->GetSingleWordInOperand(0))->type_id(); const Instruction* PtrTypeInst = def_use_mgr->GetDef(PtrTypeId); - uint32_t storage_class = - PtrTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx); - if (storage_class != SpvStorageClassUniform && - storage_class != SpvStorageClassUniformConstant) { + auto storage_class = spv::StorageClass( + PtrTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx)); + if (storage_class != spv::StorageClass::Uniform && + storage_class != spv::StorageClass::UniformConstant) { return is_uniform = false; } } else { @@ -553,7 +549,7 @@ class LoopUnswitch { // dynamically uniform. bool IsConditionNonConstantLoopInvariant(Instruction* insn) { assert(insn->IsBranch()); - assert(insn->opcode() != SpvOpBranch); + assert(insn->opcode() != spv::Op::OpBranch); analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); Instruction* condition = def_use_mgr->GetDef(insn->GetOperand(0).words[0]); diff --git a/3rdparty/spirv-tools/source/opt/loop_utils.cpp b/3rdparty/spirv-tools/source/opt/loop_utils.cpp index 8c6d355d6..20494e12b 100644 --- a/3rdparty/spirv-tools/source/opt/loop_utils.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_utils.cpp @@ -28,12 +28,11 @@ namespace spvtools { namespace opt { - namespace { // Return true if |bb| is dominated by at least one block in |exits| -static inline bool DominatesAnExit(BasicBlock* bb, - const std::unordered_set& exits, - const DominatorTree& dom_tree) { +inline bool DominatesAnExit(BasicBlock* bb, + const std::unordered_set& exits, + const DominatorTree& dom_tree) { for (BasicBlock* e_bb : exits) if (dom_tree.Dominates(bb, e_bb)) return true; return false; @@ -71,10 +70,10 @@ class LCSSARewriter { // UpdateManagers. void RewriteUse(BasicBlock* bb, Instruction* user, uint32_t operand_index) { assert( - (user->opcode() != SpvOpPhi || bb != GetParent(user)) && + (user->opcode() != spv::Op::OpPhi || bb != GetParent(user)) && "The root basic block must be the incoming edge if |user| is a phi " "instruction"); - assert((user->opcode() == SpvOpPhi || bb == GetParent(user)) && + assert((user->opcode() == spv::Op::OpPhi || bb == GetParent(user)) && "The root basic block must be the instruction parent if |user| is " "not " "phi instruction"); @@ -293,7 +292,7 @@ inline void MakeSetClosedSSA(IRContext* context, Function* function, assert(use_parent); if (blocks.count(use_parent->id())) return; - if (use->opcode() == SpvOpPhi) { + if (use->opcode() == spv::Op::OpPhi) { // If the use is a Phi instruction and the incoming block is // coming from the loop, then that's consistent with LCSSA form. if (exit_bb.count(use_parent)) { @@ -355,7 +354,7 @@ void LoopUtils::CreateLoopDedicatedExits() { // TODO(1841): Handle id overflow. BasicBlock& exit = *insert_pt.InsertBefore(std::unique_ptr( new BasicBlock(std::unique_ptr(new Instruction( - context_, SpvOpLabel, 0, context_->TakeNextId(), {}))))); + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))))); exit.SetParent(function); // Redirect in loop predecessors to |exit| block. @@ -494,7 +493,7 @@ Loop* LoopUtils::CloneAndAttachLoopToHeader(LoopCloningResult* cloning_result) { // Create a new exit block/label for the new loop. // TODO(1841): Handle id overflow. std::unique_ptr new_label{new Instruction( - context_, SpvOp::SpvOpLabel, 0, context_->TakeNextId(), {})}; + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {})}; std::unique_ptr new_exit_bb{new BasicBlock(std::move(new_label))}; new_exit_bb->SetParent(loop_->GetMergeBlock()->GetParent()); @@ -680,9 +679,9 @@ void CodeMetrics::Analyze(const Loop& loop) { const BasicBlock* bb = cfg.block(id); size_t bb_size = 0; bb->ForEachInst([&bb_size](const Instruction* insn) { - if (insn->opcode() == SpvOpLabel) return; + if (insn->opcode() == spv::Op::OpLabel) return; if (insn->IsNop()) return; - if (insn->opcode() == SpvOpPhi) return; + if (insn->opcode() == spv::Op::OpPhi) return; bb_size++; }); block_sizes_[bb->id()] = bb_size; diff --git a/3rdparty/spirv-tools/source/opt/mem_pass.cpp b/3rdparty/spirv-tools/source/opt/mem_pass.cpp index ca4889b7c..5f5929186 100644 --- a/3rdparty/spirv-tools/source/opt/mem_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/mem_pass.cpp @@ -28,26 +28,23 @@ namespace spvtools { namespace opt { - namespace { - -const uint32_t kCopyObjectOperandInIdx = 0; -const uint32_t kTypePointerStorageClassInIdx = 0; -const uint32_t kTypePointerTypeIdInIdx = 1; - +constexpr uint32_t kCopyObjectOperandInIdx = 0; +constexpr uint32_t kTypePointerStorageClassInIdx = 0; +constexpr uint32_t kTypePointerTypeIdInIdx = 1; } // namespace bool MemPass::IsBaseTargetType(const Instruction* typeInst) const { switch (typeInst->opcode()) { - case SpvOpTypeInt: - case SpvOpTypeFloat: - case SpvOpTypeBool: - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeImage: - case SpvOpTypeSampler: - case SpvOpTypeSampledImage: - case SpvOpTypePointer: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeBool: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypePointer: return true; default: break; @@ -57,14 +54,14 @@ bool MemPass::IsBaseTargetType(const Instruction* typeInst) const { bool MemPass::IsTargetType(const Instruction* typeInst) const { if (IsBaseTargetType(typeInst)) return true; - if (typeInst->opcode() == SpvOpTypeArray) { + if (typeInst->opcode() == spv::Op::OpTypeArray) { if (!IsTargetType( get_def_use_mgr()->GetDef(typeInst->GetSingleWordOperand(1)))) { return false; } return true; } - if (typeInst->opcode() != SpvOpTypeStruct) return false; + if (typeInst->opcode() != spv::Op::OpTypeStruct) return false; // All struct members must be math type return typeInst->WhileEachInId([this](const uint32_t* tid) { Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid); @@ -73,23 +70,24 @@ bool MemPass::IsTargetType(const Instruction* typeInst) const { }); } -bool MemPass::IsNonPtrAccessChain(const SpvOp opcode) const { - return opcode == SpvOpAccessChain || opcode == SpvOpInBoundsAccessChain; +bool MemPass::IsNonPtrAccessChain(const spv::Op opcode) const { + return opcode == spv::Op::OpAccessChain || + opcode == spv::Op::OpInBoundsAccessChain; } bool MemPass::IsPtr(uint32_t ptrId) { uint32_t varId = ptrId; Instruction* ptrInst = get_def_use_mgr()->GetDef(varId); - while (ptrInst->opcode() == SpvOpCopyObject) { + while (ptrInst->opcode() == spv::Op::OpCopyObject) { varId = ptrInst->GetSingleWordInOperand(kCopyObjectOperandInIdx); ptrInst = get_def_use_mgr()->GetDef(varId); } - const SpvOp op = ptrInst->opcode(); - if (op == SpvOpVariable || IsNonPtrAccessChain(op)) return true; + const spv::Op op = ptrInst->opcode(); + if (op == spv::Op::OpVariable || IsNonPtrAccessChain(op)) return true; const uint32_t varTypeId = ptrInst->type_id(); if (varTypeId == 0) return false; const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - return varTypeInst->opcode() == SpvOpTypePointer; + return varTypeInst->opcode() == spv::Op::OpTypePointer; } Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { @@ -97,24 +95,24 @@ Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { Instruction* ptrInst = get_def_use_mgr()->GetDef(*varId); Instruction* varInst; - if (ptrInst->opcode() == SpvOpConstantNull) { + if (ptrInst->opcode() == spv::Op::OpConstantNull) { *varId = 0; return ptrInst; } - if (ptrInst->opcode() != SpvOpVariable && - ptrInst->opcode() != SpvOpFunctionParameter) { + if (ptrInst->opcode() != spv::Op::OpVariable && + ptrInst->opcode() != spv::Op::OpFunctionParameter) { varInst = ptrInst->GetBaseAddress(); } else { varInst = ptrInst; } - if (varInst->opcode() == SpvOpVariable) { + if (varInst->opcode() == spv::Op::OpVariable) { *varId = varInst->result_id(); } else { *varId = 0; } - while (ptrInst->opcode() == SpvOpCopyObject) { + while (ptrInst->opcode() == spv::Op::OpCopyObject) { uint32_t temp = ptrInst->GetSingleWordInOperand(0); ptrInst = get_def_use_mgr()->GetDef(temp); } @@ -123,8 +121,9 @@ Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { } Instruction* MemPass::GetPtr(Instruction* ip, uint32_t* varId) { - assert(ip->opcode() == SpvOpStore || ip->opcode() == SpvOpLoad || - ip->opcode() == SpvOpImageTexelPointer || ip->IsAtomicWithLoad()); + assert(ip->opcode() == spv::Op::OpStore || ip->opcode() == spv::Op::OpLoad || + ip->opcode() == spv::Op::OpImageTexelPointer || + ip->IsAtomicWithLoad()); // All of these opcode place the pointer in position 0. const uint32_t ptrId = ip->GetSingleWordInOperand(0); @@ -133,8 +132,8 @@ Instruction* MemPass::GetPtr(Instruction* ip, uint32_t* varId) { bool MemPass::HasOnlyNamesAndDecorates(uint32_t id) const { return get_def_use_mgr()->WhileEachUser(id, [this](Instruction* user) { - SpvOp op = user->opcode(); - if (op != SpvOpName && !IsNonTypeDecorate(op)) { + spv::Op op = user->opcode(); + if (op != spv::Op::OpName && !IsNonTypeDecorate(op)) { return false; } return true; @@ -147,14 +146,15 @@ void MemPass::KillAllInsts(BasicBlock* bp, bool killLabel) { bool MemPass::HasLoads(uint32_t varId) const { return !get_def_use_mgr()->WhileEachUser(varId, [this](Instruction* user) { - SpvOp op = user->opcode(); + spv::Op op = user->opcode(); // TODO(): The following is slightly conservative. Could be // better handling of non-store/name. - if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) { + if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { if (HasLoads(user->result_id())) { return false; } - } else if (op != SpvOpStore && op != SpvOpName && !IsNonTypeDecorate(op)) { + } else if (op != spv::Op::OpStore && op != spv::Op::OpName && + !IsNonTypeDecorate(op)) { return false; } return true; @@ -164,12 +164,12 @@ bool MemPass::HasLoads(uint32_t varId) const { bool MemPass::IsLiveVar(uint32_t varId) const { const Instruction* varInst = get_def_use_mgr()->GetDef(varId); // assume live if not a variable eg. function parameter - if (varInst->opcode() != SpvOpVariable) return true; + if (varInst->opcode() != spv::Op::OpVariable) return true; // non-function scope vars are live const uint32_t varTypeId = varInst->type_id(); const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) != - SpvStorageClassFunction) + if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) return true; // test if variable is loaded from return HasLoads(varId); @@ -177,10 +177,10 @@ bool MemPass::IsLiveVar(uint32_t varId) const { void MemPass::AddStores(uint32_t ptr_id, std::queue* insts) { get_def_use_mgr()->ForEachUser(ptr_id, [this, insts](Instruction* user) { - SpvOp op = user->opcode(); + spv::Op op = user->opcode(); if (IsNonPtrAccessChain(op)) { AddStores(user->result_id(), insts); - } else if (op == SpvOpStore) { + } else if (op == spv::Op::OpStore) { insts->push(user); } }); @@ -193,7 +193,7 @@ void MemPass::DCEInst(Instruction* inst, while (!deadInsts.empty()) { Instruction* di = deadInsts.front(); // Don't delete labels - if (di->opcode() == SpvOpLabel) { + if (di->opcode() == spv::Op::OpLabel) { deadInsts.pop(); continue; } @@ -202,7 +202,7 @@ void MemPass::DCEInst(Instruction* inst, di->ForEachInId([&ids](uint32_t* iid) { ids.insert(*iid); }); uint32_t varId = 0; // Remember variable if dead load - if (di->opcode() == SpvOpLoad) (void)GetPtr(di, &varId); + if (di->opcode() == spv::Op::OpLoad) (void)GetPtr(di, &varId); if (call_back) { call_back(di); } @@ -230,9 +230,9 @@ bool MemPass::HasOnlySupportedRefs(uint32_t varId) { dbg_op == CommonDebugInfoDebugValue) { return true; } - SpvOp op = user->opcode(); - if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName && - !IsNonTypeDecorate(op)) { + spv::Op op = user->opcode(); + if (op != spv::Op::OpStore && op != spv::Op::OpLoad && + op != spv::Op::OpName && !IsNonTypeDecorate(op)) { return false; } return true; @@ -248,7 +248,7 @@ uint32_t MemPass::Type2Undef(uint32_t type_id) { } std::unique_ptr undef_inst( - new Instruction(context(), SpvOpUndef, type_id, undefId, {})); + new Instruction(context(), spv::Op::OpUndef, type_id, undefId, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*undef_inst); get_module()->AddGlobalValue(std::move(undef_inst)); type2undefs_[type_id] = undefId; @@ -264,11 +264,11 @@ bool MemPass::IsTargetVar(uint32_t varId) { return false; if (seen_target_vars_.find(varId) != seen_target_vars_.end()) return true; const Instruction* varInst = get_def_use_mgr()->GetDef(varId); - if (varInst->opcode() != SpvOpVariable) return false; + if (varInst->opcode() != spv::Op::OpVariable) return false; const uint32_t varTypeId = varInst->type_id(); const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) != - SpvStorageClassFunction) { + if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) { seen_non_target_vars_.insert(varId); return false; } @@ -489,8 +489,8 @@ void MemPass::CollectTargetVars(Function* func) { for (auto& blk : *func) { for (auto& inst : blk) { switch (inst.opcode()) { - case SpvOpStore: - case SpvOpLoad: { + case spv::Op::OpStore: + case spv::Op::OpLoad: { uint32_t varId; (void)GetPtr(&inst, &varId); if (!IsTargetVar(varId)) break; diff --git a/3rdparty/spirv-tools/source/opt/mem_pass.h b/3rdparty/spirv-tools/source/opt/mem_pass.h index 5a77670dd..aef9e5ffa 100644 --- a/3rdparty/spirv-tools/source/opt/mem_pass.h +++ b/3rdparty/spirv-tools/source/opt/mem_pass.h @@ -80,7 +80,7 @@ class MemPass : public Pass { bool IsTargetType(const Instruction* typeInst) const; // Returns true if |opcode| is a non-ptr access chain op - bool IsNonPtrAccessChain(const SpvOp opcode) const; + bool IsNonPtrAccessChain(const spv::Op opcode) const; // Given the id |ptrId|, return true if the top-most non-CopyObj is // a variable, a non-ptr access chain or a parameter of pointer type. @@ -117,8 +117,8 @@ class MemPass : public Pass { bool CFGCleanup(Function* func); // Return true if |op| is supported decorate. - inline bool IsNonTypeDecorate(uint32_t op) const { - return (op == SpvOpDecorate || op == SpvOpDecorateId); + inline bool IsNonTypeDecorate(spv::Op op) const { + return (op == spv::Op::OpDecorate || op == spv::Op::OpDecorateId); } // Return the id of an undef value with type |type_id|. Create and insert an diff --git a/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp b/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp index 7710deae2..c262ea073 100644 --- a/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp @@ -30,7 +30,7 @@ namespace opt { Pass::Status MergeReturnPass::Process() { bool is_shader = - context()->get_feature_mgr()->HasCapability(SpvCapabilityShader); + context()->get_feature_mgr()->HasCapability(spv::Capability::Shader); bool failed = false; ProcessFunction pfn = [&failed, is_shader, this](Function* function) { @@ -74,16 +74,16 @@ Pass::Status MergeReturnPass::Process() { void MergeReturnPass::GenerateState(BasicBlock* block) { if (Instruction* mergeInst = block->GetMergeInst()) { - if (mergeInst->opcode() == SpvOpLoopMerge) { + if (mergeInst->opcode() == spv::Op::OpLoopMerge) { // If new loop, break to this loop merge block state_.emplace_back(mergeInst, mergeInst); } else { auto branchInst = mergeInst->NextNode(); - if (branchInst->opcode() == SpvOpSwitch) { + if (branchInst->opcode() == spv::Op::OpSwitch) { // If switch inside of loop, break to innermost loop merge block. // Otherwise need to break to this switch merge block. auto lastMergeInst = state_.back().BreakMergeInst(); - if (lastMergeInst && lastMergeInst->opcode() == SpvOpLoopMerge) + if (lastMergeInst && lastMergeInst->opcode() == spv::Op::OpLoopMerge) state_.emplace_back(lastMergeInst, mergeInst); else state_.emplace_back(mergeInst, mergeInst); @@ -174,7 +174,7 @@ bool MergeReturnPass::ProcessStructured( void MergeReturnPass::CreateReturnBlock() { // Create a label for the new return block std::unique_ptr return_label( - new Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {})); + new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {})); // Create the new basic block std::unique_ptr return_block( @@ -195,37 +195,41 @@ void MergeReturnPass::CreateReturn(BasicBlock* block) { // Load and return the final return value uint32_t loadId = TakeNextId(); block->AddInstruction(MakeUnique( - context(), SpvOpLoad, function_->type_id(), loadId, + context(), spv::Op::OpLoad, function_->type_id(), loadId, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}})); Instruction* var_inst = block->terminator(); context()->AnalyzeDefUse(var_inst); context()->set_instr_block(var_inst, block); context()->get_decoration_mgr()->CloneDecorations( - return_value_->result_id(), loadId, {SpvDecorationRelaxedPrecision}); + return_value_->result_id(), loadId, + {spv::Decoration::RelaxedPrecision}); block->AddInstruction(MakeUnique( - context(), SpvOpReturnValue, 0, 0, + context(), spv::Op::OpReturnValue, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {loadId}}})); context()->AnalyzeDefUse(block->terminator()); context()->set_instr_block(block->terminator(), block); } else { - block->AddInstruction(MakeUnique(context(), SpvOpReturn)); + block->AddInstruction( + MakeUnique(context(), spv::Op::OpReturn)); context()->AnalyzeDefUse(block->terminator()); context()->set_instr_block(block->terminator(), block); } } void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) { - SpvOp tail_opcode = block->tail()->opcode(); - if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue) { + spv::Op tail_opcode = block->tail()->opcode(); + if (tail_opcode == spv::Op::OpReturn || + tail_opcode == spv::Op::OpReturnValue) { if (!return_flag_) { AddReturnFlag(); } } - if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue || - tail_opcode == SpvOpUnreachable) { + if (tail_opcode == spv::Op::OpReturn || + tail_opcode == spv::Op::OpReturnValue || + tail_opcode == spv::Op::OpUnreachable) { assert(CurrentState().InBreakable() && "Should be in the placeholder construct."); BranchToBlock(block, CurrentState().BreakMergeId()); @@ -234,8 +238,8 @@ void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) { } void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) { - if (block->tail()->opcode() == SpvOpReturn || - block->tail()->opcode() == SpvOpReturnValue) { + if (block->tail()->opcode() == spv::Op::OpReturn || + block->tail()->opcode() == spv::Op::OpReturnValue) { RecordReturned(block); RecordReturnValue(block); } @@ -247,7 +251,7 @@ void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) { UpdatePhiNodes(block, target_block); Instruction* return_inst = block->terminator(); - return_inst->SetOpcode(SpvOpBranch); + return_inst->SetOpcode(spv::Op::OpBranch); return_inst->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {target}}}); context()->get_def_use_mgr()->AnalyzeInstDefUse(return_inst); new_edges_[target_block].insert(block->id()); @@ -276,7 +280,7 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, &inst, [&users_to_update, &dom_tree, &inst, inst_bb, this](Instruction* user) { BasicBlock* user_bb = nullptr; - if (user->opcode() != SpvOpPhi) { + if (user->opcode() != spv::Op::OpPhi) { user_bb = context()->get_instr_block(user); } else { // For OpPhi, the use should be considered to be in the predecessor. @@ -325,15 +329,16 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, // instruction. If not, the Spir-V will be invalid. Instruction* inst_type = get_def_use_mgr()->GetDef(inst.type_id()); bool regenerateInstruction = false; - if (inst_type->opcode() == SpvOpTypePointer) { + if (inst_type->opcode() == spv::Op::OpTypePointer) { if (!context()->get_feature_mgr()->HasCapability( - SpvCapabilityVariablePointers)) { + spv::Capability::VariablePointers)) { regenerateInstruction = true; } - uint32_t storage_class = inst_type->GetSingleWordInOperand(0); - if (storage_class != SpvStorageClassWorkgroup && - storage_class != SpvStorageClassStorageBuffer) { + auto storage_class = + spv::StorageClass(inst_type->GetSingleWordInOperand(0)); + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer) { regenerateInstruction = true; } } @@ -343,7 +348,7 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, uint32_t new_id = TakeNextId(); regen_inst->SetResultId(new_id); Instruction* insert_pos = &*merge_block->begin(); - while (insert_pos->opcode() == SpvOpPhi) { + while (insert_pos->opcode() == spv::Op::OpPhi) { insert_pos = insert_pos->NextNode(); } new_phi = insert_pos->InsertBefore(std::move(regen_inst)); @@ -459,7 +464,7 @@ bool MergeReturnPass::BreakFromConstruct( // Leave the phi instructions behind. auto iter = block->begin(); - while (iter->opcode() == SpvOpPhi) { + while (iter->opcode() == spv::Op::OpPhi) { ++iter; } @@ -478,7 +483,7 @@ bool MergeReturnPass::BreakFromConstruct( // If |block| was a continue target for a loop |old_body| is now the correct // continue target. - if (break_merge_inst->opcode() == SpvOpLoopMerge && + if (break_merge_inst->opcode() == spv::Op::OpLoopMerge && break_merge_inst->GetSingleWordInOperand(1) == block->id()) { break_merge_inst->SetInOperand(1, {old_body->id()}); context()->UpdateDefUse(break_merge_inst); @@ -531,8 +536,8 @@ bool MergeReturnPass::BreakFromConstruct( } void MergeReturnPass::RecordReturned(BasicBlock* block) { - if (block->tail()->opcode() != SpvOpReturn && - block->tail()->opcode() != SpvOpReturnValue) + if (block->tail()->opcode() != spv::Op::OpReturn && + block->tail()->opcode() != spv::Op::OpReturnValue) return; assert(return_flag_ && "Did not generate the return flag variable."); @@ -550,7 +555,7 @@ void MergeReturnPass::RecordReturned(BasicBlock* block) { } std::unique_ptr return_store(new Instruction( - context(), SpvOpStore, 0, 0, + context(), spv::Op::OpStore, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {return_flag_->result_id()}}, {SPV_OPERAND_TYPE_ID, {constant_true_->result_id()}}})); @@ -563,7 +568,7 @@ void MergeReturnPass::RecordReturned(BasicBlock* block) { void MergeReturnPass::RecordReturnValue(BasicBlock* block) { auto terminator = *block->tail(); - if (terminator.opcode() != SpvOpReturnValue) { + if (terminator.opcode() != spv::Op::OpReturnValue) { return; } @@ -571,7 +576,7 @@ void MergeReturnPass::RecordReturnValue(BasicBlock* block) { "Did not generate the variable to hold the return value."); std::unique_ptr value_store(new Instruction( - context(), SpvOpStore, 0, 0, + context(), spv::Op::OpStore, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}, {SPV_OPERAND_TYPE_ID, {terminator.GetSingleWordInOperand(0u)}}})); @@ -586,17 +591,19 @@ void MergeReturnPass::AddReturnValue() { if (return_value_) return; uint32_t return_type_id = function_->type_id(); - if (get_def_use_mgr()->GetDef(return_type_id)->opcode() == SpvOpTypeVoid) + if (get_def_use_mgr()->GetDef(return_type_id)->opcode() == + spv::Op::OpTypeVoid) return; uint32_t return_ptr_type = context()->get_type_mgr()->FindPointerToType( - return_type_id, SpvStorageClassFunction); + return_type_id, spv::StorageClass::Function); uint32_t var_id = TakeNextId(); - std::unique_ptr returnValue(new Instruction( - context(), SpvOpVariable, return_ptr_type, var_id, - std::initializer_list{ - {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); + std::unique_ptr returnValue( + new Instruction(context(), spv::Op::OpVariable, return_ptr_type, var_id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}})); auto insert_iter = function_->begin()->begin(); insert_iter.InsertBefore(std::move(returnValue)); @@ -606,7 +613,7 @@ void MergeReturnPass::AddReturnValue() { context()->set_instr_block(return_value_, entry_block); context()->get_decoration_mgr()->CloneDecorations( - function_->result_id(), var_id, {SpvDecorationRelaxedPrecision}); + function_->result_id(), var_id, {spv::Decoration::RelaxedPrecision}); } void MergeReturnPass::AddReturnFlag() { @@ -625,14 +632,14 @@ void MergeReturnPass::AddReturnFlag() { const_mgr->GetDefiningInstruction(false_const)->result_id(); uint32_t bool_ptr_id = - type_mgr->FindPointerToType(bool_id, SpvStorageClassFunction); + type_mgr->FindPointerToType(bool_id, spv::StorageClass::Function); uint32_t var_id = TakeNextId(); std::unique_ptr returnFlag(new Instruction( - context(), SpvOpVariable, bool_ptr_id, var_id, - std::initializer_list{ - {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, - {SPV_OPERAND_TYPE_ID, {const_false_id}}})); + context(), spv::Op::OpVariable, bool_ptr_id, var_id, + std::initializer_list{{SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}, + {SPV_OPERAND_TYPE_ID, {const_false_id}}})); auto insert_iter = function_->begin()->begin(); @@ -648,8 +655,8 @@ std::vector MergeReturnPass::CollectReturnBlocks( std::vector return_blocks; for (auto& block : *function) { Instruction& terminator = *block.tail(); - if (terminator.opcode() == SpvOpReturn || - terminator.opcode() == SpvOpReturnValue) { + if (terminator.opcode() == spv::Op::OpReturn || + terminator.opcode() == spv::Op::OpReturnValue) { return_blocks.push_back(&block); } } @@ -670,7 +677,7 @@ void MergeReturnPass::MergeReturnBlocks( // Create new return. std::vector phi_ops; for (auto block : return_blocks) { - if (block->tail()->opcode() == SpvOpReturnValue) { + if (block->tail()->opcode() == spv::Op::OpReturnValue) { phi_ops.push_back( {SPV_OPERAND_TYPE_ID, {block->tail()->GetSingleWordInOperand(0u)}}); phi_ops.push_back({SPV_OPERAND_TYPE_ID, {block->id()}}); @@ -682,12 +689,12 @@ void MergeReturnPass::MergeReturnBlocks( uint32_t phi_result_id = TakeNextId(); uint32_t phi_type_id = function->type_id(); std::unique_ptr phi_inst(new Instruction( - context(), SpvOpPhi, phi_type_id, phi_result_id, phi_ops)); + context(), spv::Op::OpPhi, phi_type_id, phi_result_id, phi_ops)); ret_block_iter->AddInstruction(std::move(phi_inst)); BasicBlock::iterator phiIter = ret_block_iter->tail(); std::unique_ptr return_inst( - new Instruction(context(), SpvOpReturnValue, 0u, 0u, + new Instruction(context(), spv::Op::OpReturnValue, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {phi_result_id}}})); ret_block_iter->AddInstruction(std::move(return_inst)); BasicBlock::iterator ret = ret_block_iter->tail(); @@ -697,14 +704,14 @@ void MergeReturnPass::MergeReturnBlocks( get_def_use_mgr()->AnalyzeInstDef(&*ret); } else { std::unique_ptr return_inst( - new Instruction(context(), SpvOpReturn)); + new Instruction(context(), spv::Op::OpReturn)); ret_block_iter->AddInstruction(std::move(return_inst)); } // Replace returns with branches for (auto block : return_blocks) { context()->ForgetUses(block->terminator()); - block->tail()->SetOpcode(SpvOpBranch); + block->tail()->SetOpcode(spv::Op::OpBranch); block->tail()->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {return_id}}}); get_def_use_mgr()->AnalyzeInstUse(block->terminator()); get_def_use_mgr()->AnalyzeInstUse(block->GetLabelInst()); @@ -789,7 +796,7 @@ bool MergeReturnPass::AddSingleCaseSwitchAroundFunction() { BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) { std::unique_ptr label( - new Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {})); + new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {})); // Create the new basic block std::unique_ptr block(new BasicBlock(std::move(label))); @@ -824,7 +831,7 @@ bool MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) { // block to make sure the OpVariable instructions remain in the entry block. BasicBlock* start_block = &*function_->begin(); auto split_pos = start_block->begin(); - while (split_pos->opcode() == SpvOpVariable) { + while (split_pos->opcode() == spv::Op::OpVariable) { ++split_pos; } @@ -865,7 +872,7 @@ bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) { if (struct_cfg_analysis->IsContinueBlock(bb.id())) { // |bb| must be an empty block ending with a branch to the header. Instruction* inst = &*bb.begin(); - if (inst->opcode() != SpvOpBranch) { + if (inst->opcode() != spv::Op::OpBranch) { return true; } @@ -875,7 +882,7 @@ bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) { } } else if (struct_cfg_analysis->IsMergeBlock(bb.id())) { // |bb| must be an empty block ending with OpUnreachable. - if (bb.begin()->opcode() != SpvOpUnreachable) { + if (bb.begin()->opcode() != spv::Op::OpUnreachable) { return true; } } else { diff --git a/3rdparty/spirv-tools/source/opt/module.cpp b/3rdparty/spirv-tools/source/opt/module.cpp index c98af8f51..a9710c6a3 100644 --- a/3rdparty/spirv-tools/source/opt/module.cpp +++ b/3rdparty/spirv-tools/source/opt/module.cpp @@ -69,14 +69,14 @@ std::vector Module::GetConstants() const { return const_insts; } -uint32_t Module::GetGlobalValue(SpvOp opcode) const { +uint32_t Module::GetGlobalValue(spv::Op opcode) const { for (auto& inst : types_values_) { if (inst.opcode() == opcode) return inst.result_id(); } return 0; } -void Module::AddGlobalValue(SpvOp opcode, uint32_t result_id, +void Module::AddGlobalValue(spv::Op opcode, uint32_t result_id, uint32_t type_id) { std::unique_ptr newGlobal( new Instruction(context(), opcode, type_id, result_id, {})); @@ -159,7 +159,6 @@ void Module::ToBinary(std::vector* binary, bool skip_nop) const { if (between_merge_and_branch && i->IsLineInst()) { return; } - between_merge_and_branch = false; if (last_line_inst != nullptr) { // If the current instruction is OpLine or DebugLine and it is the same // as the last line instruction that is still effective (can be applied @@ -181,28 +180,30 @@ void Module::ToBinary(std::vector* binary, bool skip_nop) const { ->get_feature_mgr() ->GetExtInstImportId_Shader100DebugInfo(); if (shader_set_id != 0) { - binary->push_back((5 << 16) | static_cast(SpvOpExtInst)); + binary->push_back((5 << 16) | + static_cast(spv::Op::OpExtInst)); binary->push_back(context()->get_type_mgr()->GetVoidTypeId()); binary->push_back(context()->TakeNextId()); binary->push_back(shader_set_id); binary->push_back(NonSemanticShaderDebugInfo100DebugNoLine); } else { - binary->push_back((1 << 16) | static_cast(SpvOpNoLine)); + binary->push_back((1 << 16) | + static_cast(spv::Op::OpNoLine)); } last_line_inst = nullptr; } } - if (opcode == SpvOpLabel) { + if (opcode == spv::Op::OpLabel) { between_label_and_phi_var = true; - } else if (opcode != SpvOpVariable && opcode != SpvOpPhi && + } else if (opcode != spv::Op::OpVariable && opcode != spv::Op::OpPhi && !spvtools::opt::IsOpLineInst(opcode)) { between_label_and_phi_var = false; } if (!(skip_nop && i->IsNop())) { const auto& scope = i->GetDebugScope(); - if (scope != last_scope) { + if (scope != last_scope && !between_merge_and_branch) { // Can only emit nonsemantic instructions after all phi instructions // in a block so don't emit scope instructions before phi instructions // for NonSemantic.Shader.DebugInfo.100. @@ -221,9 +222,11 @@ void Module::ToBinary(std::vector* binary, bool skip_nop) const { i->ToBinaryWithoutAttachedDebugInsts(binary); } // Update the last line instruction. + between_merge_and_branch = false; if (spvOpcodeIsBlockTerminator(opcode) || i->IsNoLine()) { last_line_inst = nullptr; - } else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) { + } else if (opcode == spv::Op::OpLoopMerge || + opcode == spv::Op::OpSelectionMerge) { between_merge_and_branch = true; last_line_inst = nullptr; } else if (i->IsLine()) { @@ -272,7 +275,7 @@ uint32_t Module::GetExtInstImportId(const char* extstr) { std::ostream& operator<<(std::ostream& str, const Module& module) { module.ForEachInst([&str](const Instruction* inst) { str << *inst; - if (inst->opcode() != SpvOpFunctionEnd) { + if (inst->opcode() != spv::Op::OpFunctionEnd) { str << std::endl; } }); diff --git a/3rdparty/spirv-tools/source/opt/module.h b/3rdparty/spirv-tools/source/opt/module.h index 7a6be460e..ed2f3454e 100644 --- a/3rdparty/spirv-tools/source/opt/module.h +++ b/3rdparty/spirv-tools/source/opt/module.h @@ -136,10 +136,10 @@ class Module { std::vector GetConstants() const; // Return result id of global value with |opcode|, 0 if not present. - uint32_t GetGlobalValue(SpvOp opcode) const; + uint32_t GetGlobalValue(spv::Op opcode) const; // Add global value with |opcode|, |result_id| and |type_id| - void AddGlobalValue(SpvOp opcode, uint32_t result_id, uint32_t type_id); + void AddGlobalValue(spv::Op opcode, uint32_t result_id, uint32_t type_id); inline uint32_t id_bound() const { return header_.bound; } diff --git a/3rdparty/spirv-tools/source/opt/optimizer.cpp b/3rdparty/spirv-tools/source/opt/optimizer.cpp index 381589b53..be0daebda 100644 --- a/3rdparty/spirv-tools/source/opt/optimizer.cpp +++ b/3rdparty/spirv-tools/source/opt/optimizer.cpp @@ -60,6 +60,7 @@ struct Optimizer::Impl { spv_target_env target_env; // Target environment. opt::PassManager pass_manager; // Internal implementation pass manager. + std::unordered_set live_locs; // Arg to debug dead output passes }; Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) { @@ -524,7 +525,7 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { } else if (pass_name == "remove-dont-inline") { RegisterPass(CreateRemoveDontInlinePass()); } else if (pass_name == "eliminate-dead-input-components") { - RegisterPass(CreateEliminateDeadInputComponentsPass()); + RegisterPass(CreateEliminateDeadInputComponentsSafePass()); } else if (pass_name == "fix-func-call-param") { RegisterPass(CreateFixFuncCallArgumentsPass()); } else if (pass_name == "convert-to-sampled-image") { @@ -784,14 +785,10 @@ Optimizer::PassToken CreateLocalMultiStoreElimPass() { MakeUnique()); } -Optimizer::PassToken CreateAggressiveDCEPass() { +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface, + bool remove_outputs) { return MakeUnique( - MakeUnique(false)); -} - -Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface) { - return MakeUnique( - MakeUnique(preserve_interface)); + MakeUnique(preserve_interface, remove_outputs)); } Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass() { @@ -1016,7 +1013,34 @@ Optimizer::PassToken CreateInterpolateFixupPass() { Optimizer::PassToken CreateEliminateDeadInputComponentsPass() { return MakeUnique( - MakeUnique()); + MakeUnique(spv::StorageClass::Input, + /* safe_mode */ false)); +} + +Optimizer::PassToken CreateEliminateDeadOutputComponentsPass() { + return MakeUnique( + MakeUnique(spv::StorageClass::Output, + /* safe_mode */ false)); +} + +Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass() { + return MakeUnique( + MakeUnique(spv::StorageClass::Input, + /* safe_mode */ true)); +} + +Optimizer::PassToken CreateAnalyzeLiveInputPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins) { + return MakeUnique( + MakeUnique(live_locs, live_builtins)); +} + +Optimizer::PassToken CreateEliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins) { + return MakeUnique( + MakeUnique(live_locs, live_builtins)); } Optimizer::PassToken CreateConvertToSampledImagePass( diff --git a/3rdparty/spirv-tools/source/opt/pass.cpp b/3rdparty/spirv-tools/source/opt/pass.cpp index 017aad10f..75c37407f 100644 --- a/3rdparty/spirv-tools/source/opt/pass.cpp +++ b/3rdparty/spirv-tools/source/opt/pass.cpp @@ -21,11 +21,8 @@ namespace spvtools { namespace opt { - namespace { - -const uint32_t kTypePointerTypeIdInIdx = 1; - +constexpr uint32_t kTypePointerTypeIdInIdx = 1; } // namespace Pass::Pass() : consumer_(nullptr), context_(nullptr), already_run_(false) {} @@ -56,11 +53,11 @@ uint32_t Pass::GetPointeeTypeId(const Instruction* ptrInst) const { Instruction* Pass::GetBaseType(uint32_t ty_id) { Instruction* ty_inst = get_def_use_mgr()->GetDef(ty_id); - if (ty_inst->opcode() == SpvOpTypeMatrix) { + if (ty_inst->opcode() == spv::Op::OpTypeMatrix) { uint32_t vty_id = ty_inst->GetSingleWordInOperand(0); ty_inst = get_def_use_mgr()->GetDef(vty_id); } - if (ty_inst->opcode() == SpvOpTypeVector) { + if (ty_inst->opcode() == spv::Op::OpTypeVector) { uint32_t cty_id = ty_inst->GetSingleWordInOperand(0); ty_inst = get_def_use_mgr()->GetDef(cty_id); } @@ -69,12 +66,12 @@ Instruction* Pass::GetBaseType(uint32_t ty_id) { bool Pass::IsFloat(uint32_t ty_id, uint32_t width) { Instruction* ty_inst = GetBaseType(ty_id); - if (ty_inst->opcode() != SpvOpTypeFloat) return false; + if (ty_inst->opcode() != spv::Op::OpTypeFloat) return false; return ty_inst->GetSingleWordInOperand(0) == width; } uint32_t Pass::GetNullId(uint32_t type_id) { - if (IsFloat(type_id, 16)) context()->AddCapability(SpvCapabilityFloat16); + if (IsFloat(type_id, 16)) context()->AddCapability(spv::Capability::Float16); analysis::TypeManager* type_mgr = context()->get_type_mgr(); analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); const analysis::Type* type = type_mgr->GetType(type_id); diff --git a/3rdparty/spirv-tools/source/opt/passes.h b/3rdparty/spirv-tools/source/opt/passes.h index 21354c77b..eb3b1e5d3 100644 --- a/3rdparty/spirv-tools/source/opt/passes.h +++ b/3rdparty/spirv-tools/source/opt/passes.h @@ -19,6 +19,7 @@ #include "source/opt/aggressive_dead_code_elim_pass.h" #include "source/opt/amd_ext_to_khr.h" +#include "source/opt/analyze_live_input_pass.h" #include "source/opt/block_merge_pass.h" #include "source/opt/ccp_pass.h" #include "source/opt/cfg_cleanup_pass.h" @@ -34,8 +35,9 @@ #include "source/opt/desc_sroa.h" #include "source/opt/eliminate_dead_constant_pass.h" #include "source/opt/eliminate_dead_functions_pass.h" -#include "source/opt/eliminate_dead_input_components_pass.h" +#include "source/opt/eliminate_dead_io_components_pass.h" #include "source/opt/eliminate_dead_members_pass.h" +#include "source/opt/eliminate_dead_output_stores_pass.h" #include "source/opt/empty_pass.h" #include "source/opt/fix_func_call_arguments.h" #include "source/opt/fix_storage_class.h" diff --git a/3rdparty/spirv-tools/source/opt/private_to_local_pass.cpp b/3rdparty/spirv-tools/source/opt/private_to_local_pass.cpp index 80fb4c535..4904e058b 100644 --- a/3rdparty/spirv-tools/source/opt/private_to_local_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/private_to_local_pass.cpp @@ -24,10 +24,8 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kVariableStorageClassInIdx = 0; -const uint32_t kSpvTypePointerTypeIdInIdx = 1; - +constexpr uint32_t kVariableStorageClassInIdx = 0; +constexpr uint32_t kSpvTypePointerTypeIdInIdx = 1; } // namespace Pass::Status PrivateToLocalPass::Process() { @@ -35,18 +33,18 @@ Pass::Status PrivateToLocalPass::Process() { // Private variables require the shader capability. If this is not a shader, // there is no work to do. - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) return Status::SuccessWithoutChange; std::vector> variables_to_move; std::unordered_set localized_variables; for (auto& inst : context()->types_values()) { - if (inst.opcode() != SpvOpVariable) { + if (inst.opcode() != spv::Op::OpVariable) { continue; } - if (inst.GetSingleWordInOperand(kVariableStorageClassInIdx) != - SpvStorageClassPrivate) { + if (spv::StorageClass(inst.GetSingleWordInOperand( + kVariableStorageClassInIdx)) != spv::StorageClass::Private) { continue; } @@ -123,7 +121,8 @@ bool PrivateToLocalPass::MoveVariable(Instruction* variable, context()->ForgetUses(variable); // Update the storage class of the variable. - variable->SetInOperand(kVariableStorageClassInIdx, {SpvStorageClassFunction}); + variable->SetInOperand(kVariableStorageClassInIdx, + {uint32_t(spv::StorageClass::Function)}); // Update the type as well. uint32_t new_type_id = GetNewType(variable->type_id()); @@ -147,7 +146,7 @@ uint32_t PrivateToLocalPass::GetNewType(uint32_t old_type_id) { uint32_t pointee_type_id = old_type_inst->GetSingleWordInOperand(kSpvTypePointerTypeIdInIdx); uint32_t new_type_id = - type_mgr->FindPointerToType(pointee_type_id, SpvStorageClassFunction); + type_mgr->FindPointerToType(pointee_type_id, spv::StorageClass::Function); if (new_type_id != 0) { context()->UpdateDefUse(context()->get_def_use_mgr()->GetDef(new_type_id)); } @@ -161,17 +160,17 @@ bool PrivateToLocalPass::IsValidUse(const Instruction* inst) const { return true; } switch (inst->opcode()) { - case SpvOpLoad: - case SpvOpStore: - case SpvOpImageTexelPointer: // Treat like a load + case spv::Op::OpLoad: + case spv::Op::OpStore: + case spv::Op::OpImageTexelPointer: // Treat like a load return true; - case SpvOpAccessChain: + case spv::Op::OpAccessChain: return context()->get_def_use_mgr()->WhileEachUser( inst, [this](const Instruction* user) { if (!IsValidUse(user)) return false; return true; }); - case SpvOpName: + case spv::Op::OpName: return true; default: return spvOpcodeIsDecoration(inst->opcode()); @@ -188,13 +187,13 @@ bool PrivateToLocalPass::UpdateUse(Instruction* inst, Instruction* user) { return true; } switch (inst->opcode()) { - case SpvOpLoad: - case SpvOpStore: - case SpvOpImageTexelPointer: // Treat like a load + case spv::Op::OpLoad: + case spv::Op::OpStore: + case spv::Op::OpImageTexelPointer: // Treat like a load // The type is fine because it is the type pointed to, and that does not // change. break; - case SpvOpAccessChain: { + case spv::Op::OpAccessChain: { context()->ForgetUses(inst); uint32_t new_type_id = GetNewType(inst->type_id()); if (new_type_id == 0) { @@ -208,8 +207,8 @@ bool PrivateToLocalPass::UpdateUse(Instruction* inst, Instruction* user) { return false; } } break; - case SpvOpName: - case SpvOpEntryPoint: // entry points will be updated separately. + case spv::Op::OpName: + case spv::Op::OpEntryPoint: // entry points will be updated separately. break; default: assert(spvOpcodeIsDecoration(inst->opcode()) && diff --git a/3rdparty/spirv-tools/source/opt/propagator.cpp b/3rdparty/spirv-tools/source/opt/propagator.cpp index 6a1f1aafb..9cd6174cf 100644 --- a/3rdparty/spirv-tools/source/opt/propagator.cpp +++ b/3rdparty/spirv-tools/source/opt/propagator.cpp @@ -134,7 +134,7 @@ bool SSAPropagator::Simulate(Instruction* instr) { // defined at an instruction D that should be simulated again, then the output // of D might affect |instr|, so we should simulate |instr| again. bool has_operands_to_simulate = false; - if (instr->opcode() == SpvOpPhi) { + if (instr->opcode() == spv::Op::OpPhi) { // For Phi instructions, an operand causes the Phi to be simulated again if // the operand comes from an edge that has not yet been traversed or if its // definition should be simulated again. @@ -189,7 +189,7 @@ bool SSAPropagator::Simulate(BasicBlock* block) { // statement in it. if (!BlockHasBeenSimulated(block)) { block->ForEachInst([this, &changed](Instruction* instr) { - if (instr->opcode() != SpvOpPhi) { + if (instr->opcode() != spv::Op::OpPhi) { changed |= Simulate(instr); } }); diff --git a/3rdparty/spirv-tools/source/opt/propagator.h b/3rdparty/spirv-tools/source/opt/propagator.h index ac7c0e7ea..71212c969 100644 --- a/3rdparty/spirv-tools/source/opt/propagator.h +++ b/3rdparty/spirv-tools/source/opt/propagator.h @@ -153,10 +153,10 @@ struct Edge { // std::map values; // const auto visit_fn = [&ctx, &values](Instruction* instr, // BasicBlock** dest_bb) { -// if (instr->opcode() == SpvOpStore) { +// if (instr->opcode() == spv::Op::OpStore) { // uint32_t rhs_id = instr->GetSingleWordOperand(1); // Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id); -// if (rhs_def->opcode() == SpvOpConstant) { +// if (rhs_def->opcode() == spv::Op::OpConstant) { // uint32_t val = rhs_def->GetSingleWordOperand(2); // values[rhs_id] = val; // return SSAPropagator::kInteresting; diff --git a/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp b/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp index 56491b2f2..73a90f066 100644 --- a/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp +++ b/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp @@ -22,23 +22,20 @@ #include "source/opt/ir_context.h" #include "source/util/bit_vector.h" -namespace { - -const uint32_t kExtractCompositeIdInIdx = 0; -const uint32_t kVariableStorageClassInIdx = 0; -const uint32_t kLoadPointerInIdx = 0; - -} // namespace - namespace spvtools { namespace opt { +namespace { +constexpr uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kVariableStorageClassInIdx = 0; +constexpr uint32_t kLoadPointerInIdx = 0; +} // namespace Pass::Status ReduceLoadSize::Process() { bool modified = false; for (auto& func : *get_module()) { func.ForEachInst([&modified, this](Instruction* inst) { - if (inst->opcode() == SpvOpCompositeExtract) { + if (inst->opcode() == spv::Op::OpCompositeExtract) { if (ShouldReplaceExtract(inst)) { modified |= ReplaceExtract(inst); } @@ -50,7 +47,7 @@ Pass::Status ReduceLoadSize::Process() { } bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { - assert(inst->opcode() == SpvOpCompositeExtract && + assert(inst->opcode() == spv::Op::OpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); analysis::TypeManager* type_mgr = context()->get_type_mgr(); @@ -60,7 +57,7 @@ bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* composite_inst = def_use_mgr->GetDef(composite_id); - if (composite_inst->opcode() != SpvOpLoad) { + if (composite_inst->opcode() != spv::Op::OpLoad) { return false; } @@ -71,16 +68,16 @@ bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { } Instruction* var = composite_inst->GetBaseAddress(); - if (var == nullptr || var->opcode() != SpvOpVariable) { + if (var == nullptr || var->opcode() != spv::Op::OpVariable) { return false; } - SpvStorageClass storage_class = static_cast( + spv::StorageClass storage_class = static_cast( var->GetSingleWordInOperand(kVariableStorageClassInIdx)); switch (storage_class) { - case SpvStorageClassUniform: - case SpvStorageClassUniformConstant: - case SpvStorageClassInput: + case spv::StorageClass::Uniform: + case spv::StorageClass::UniformConstant: + case spv::StorageClass::Input: break; default: return false; @@ -124,7 +121,7 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) { Instruction* op_inst = def_use_mgr->GetDef( inst->GetSingleWordInOperand(kExtractCompositeIdInIdx)); - if (op_inst->opcode() != SpvOpLoad) { + if (op_inst->opcode() != spv::Op::OpLoad) { return false; } @@ -139,7 +136,7 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) { all_elements_used = !def_use_mgr->WhileEachUser(op_inst, [&elements_used](Instruction* use) { if (use->IsCommonDebugInstr()) return true; - if (use->opcode() != SpvOpCompositeExtract || + if (use->opcode() != spv::Op::OpCompositeExtract || use->NumInOperands() == 1) { return false; } diff --git a/3rdparty/spirv-tools/source/opt/reflect.h b/3rdparty/spirv-tools/source/opt/reflect.h index c2ffb0beb..45bb5c57c 100644 --- a/3rdparty/spirv-tools/source/opt/reflect.h +++ b/3rdparty/spirv-tools/source/opt/reflect.h @@ -24,41 +24,49 @@ namespace opt { // following functions tend to be outdated and should be updated when SPIR-V // version bumps. -inline bool IsDebug1Inst(SpvOp opcode) { - return (opcode >= SpvOpSourceContinued && opcode <= SpvOpSourceExtension) || - opcode == SpvOpString; +inline bool IsDebug1Inst(spv::Op opcode) { + return (opcode >= spv::Op::OpSourceContinued && + opcode <= spv::Op::OpSourceExtension) || + opcode == spv::Op::OpString; } -inline bool IsDebug2Inst(SpvOp opcode) { - return opcode == SpvOpName || opcode == SpvOpMemberName; +inline bool IsDebug2Inst(spv::Op opcode) { + return opcode == spv::Op::OpName || opcode == spv::Op::OpMemberName; } -inline bool IsDebug3Inst(SpvOp opcode) { - return opcode == SpvOpModuleProcessed; +inline bool IsDebug3Inst(spv::Op opcode) { + return opcode == spv::Op::OpModuleProcessed; } -inline bool IsOpLineInst(SpvOp opcode) { - return opcode == SpvOpLine || opcode == SpvOpNoLine; +inline bool IsOpLineInst(spv::Op opcode) { + return opcode == spv::Op::OpLine || opcode == spv::Op::OpNoLine; } -inline bool IsAnnotationInst(SpvOp opcode) { - return (opcode >= SpvOpDecorate && opcode <= SpvOpGroupMemberDecorate) || - opcode == SpvOpDecorateId || opcode == SpvOpDecorateStringGOOGLE || - opcode == SpvOpMemberDecorateStringGOOGLE; +inline bool IsAnnotationInst(spv::Op opcode) { + return (opcode >= spv::Op::OpDecorate && + opcode <= spv::Op::OpGroupMemberDecorate) || + opcode == spv::Op::OpDecorateId || + opcode == spv::Op::OpDecorateStringGOOGLE || + opcode == spv::Op::OpMemberDecorateStringGOOGLE; } -inline bool IsTypeInst(SpvOp opcode) { - return (opcode >= SpvOpTypeVoid && opcode <= SpvOpTypeForwardPointer) || - opcode == SpvOpTypePipeStorage || opcode == SpvOpTypeNamedBarrier || - opcode == SpvOpTypeAccelerationStructureNV || - opcode == SpvOpTypeAccelerationStructureKHR || - opcode == SpvOpTypeRayQueryKHR || - opcode == SpvOpTypeCooperativeMatrixNV; +inline bool IsTypeInst(spv::Op opcode) { + return (opcode >= spv::Op::OpTypeVoid && + opcode <= spv::Op::OpTypeForwardPointer) || + opcode == spv::Op::OpTypePipeStorage || + opcode == spv::Op::OpTypeNamedBarrier || + opcode == spv::Op::OpTypeAccelerationStructureNV || + opcode == spv::Op::OpTypeAccelerationStructureKHR || + opcode == spv::Op::OpTypeRayQueryKHR || + opcode == spv::Op::OpTypeCooperativeMatrixNV || + opcode == spv::Op::OpTypeHitObjectNV; } -inline bool IsConstantInst(SpvOp opcode) { - return (opcode >= SpvOpConstantTrue && opcode <= SpvOpSpecConstantOp) || - opcode == SpvOpConstantFunctionPointerINTEL; +inline bool IsConstantInst(spv::Op opcode) { + return (opcode >= spv::Op::OpConstantTrue && + opcode <= spv::Op::OpSpecConstantOp) || + opcode == spv::Op::OpConstantFunctionPointerINTEL; } -inline bool IsCompileTimeConstantInst(SpvOp opcode) { - return opcode >= SpvOpConstantTrue && opcode <= SpvOpConstantNull; +inline bool IsCompileTimeConstantInst(spv::Op opcode) { + return opcode >= spv::Op::OpConstantTrue && opcode <= spv::Op::OpConstantNull; } -inline bool IsSpecConstantInst(SpvOp opcode) { - return opcode >= SpvOpSpecConstantTrue && opcode <= SpvOpSpecConstantOp; +inline bool IsSpecConstantInst(spv::Op opcode) { + return opcode >= spv::Op::OpSpecConstantTrue && + opcode <= spv::Op::OpSpecConstantOp; } } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/register_pressure.cpp b/3rdparty/spirv-tools/source/opt/register_pressure.cpp index 1ad337387..34a8ba3e3 100644 --- a/3rdparty/spirv-tools/source/opt/register_pressure.cpp +++ b/3rdparty/spirv-tools/source/opt/register_pressure.cpp @@ -26,7 +26,6 @@ namespace spvtools { namespace opt { - namespace { // Predicate for the FilterIterator to only consider instructions that are not // phi instructions defined in the basic block |bb|. @@ -36,7 +35,7 @@ class ExcludePhiDefinedInBlock { : context_(context), bb_(bb) {} bool operator()(Instruction* insn) const { - return !(insn->opcode() == SpvOpPhi && + return !(insn->opcode() == spv::Op::OpPhi && context_->get_instr_block(insn) == bb_); } @@ -49,9 +48,9 @@ class ExcludePhiDefinedInBlock { // physical register. bool CreatesRegisterUsage(Instruction* insn) { if (!insn->HasResultId()) return false; - if (insn->opcode() == SpvOpUndef) return false; + if (insn->opcode() == spv::Op::OpUndef) return false; if (IsConstantInst(insn->opcode())) return false; - if (insn->opcode() == SpvOpLabel) return false; + if (insn->opcode() == spv::Op::OpLabel) return false; return true; } @@ -147,7 +146,7 @@ class ComputeRegisterLiveness { live_inout->live_in_ = live_inout->live_out_; for (Instruction& insn : make_range(bb->rbegin(), bb->rend())) { - if (insn.opcode() == SpvOpPhi) { + if (insn.opcode() == spv::Op::OpPhi) { live_inout->live_in_.insert(&insn); break; } @@ -224,7 +223,7 @@ class ComputeRegisterLiveness { for (Instruction& insn : make_range(bb.rbegin(), bb.rend())) { // If it is a phi instruction, the register pressure will not change // anymore. - if (insn.opcode() == SpvOpPhi) { + if (insn.opcode() == spv::Op::OpPhi) { break; } @@ -271,7 +270,7 @@ void RegisterLiveness::RegionRegisterLiveness::AddRegisterClass( RegisterLiveness::RegisterClass reg_class{type, false}; insn->context()->get_decoration_mgr()->WhileEachDecoration( - insn->result_id(), SpvDecorationUniform, + insn->result_id(), uint32_t(spv::Decoration::Uniform), [®_class](const Instruction&) { reg_class.is_uniform_ = true; return false; @@ -325,7 +324,7 @@ void RegisterLiveness::ComputeLoopRegisterPressure( loop_reg_pressure->used_registers_, live_inout->used_registers_); for (Instruction& insn : *bb) { - if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) || + if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || seen_insn.count(insn.result_id())) { continue; } @@ -386,7 +385,7 @@ void RegisterLiveness::SimulateFusion( [&l1, &l2](Instruction* insn) { BasicBlock* bb = insn->context()->get_instr_block(insn); return insn->HasResultId() && - !(insn->opcode() == SpvOpPhi && + !(insn->opcode() == spv::Op::OpPhi && (bb == l1.GetHeaderBlock() || bb == l2.GetHeaderBlock())); }); @@ -403,7 +402,7 @@ void RegisterLiveness::SimulateFusion( live_inout_info->live_out_.size()); for (Instruction& insn : *bb) { - if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) || + if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || seen_insn.count(insn.result_id())) { continue; } @@ -434,7 +433,7 @@ void RegisterLiveness::SimulateFusion( live_inout_info->live_out_.size()); for (Instruction& insn : *bb) { - if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) || + if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || seen_insn.count(insn.result_id())) { continue; } @@ -532,7 +531,7 @@ void RegisterLiveness::SimulateFission( std::unordered_set die_in_block; for (Instruction& insn : make_range(bb->rbegin(), bb->rend())) { - if (insn.opcode() == SpvOpPhi) { + if (insn.opcode() == spv::Op::OpPhi) { break; } diff --git a/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.cpp b/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.cpp index 3fcf87955..df925a251 100644 --- a/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.cpp @@ -25,7 +25,7 @@ bool RelaxFloatOpsPass::IsRelaxable(Instruction* inst) { return target_ops_core_f_rslt_.count(inst->opcode()) != 0 || target_ops_core_f_opnd_.count(inst->opcode()) != 0 || sample_ops_.count(inst->opcode()) != 0 || - (inst->opcode() == SpvOpExtInst && + (inst->opcode() == spv::Op::OpExtInst && inst->GetSingleWordInOperand(0) == context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && target_ops_450_.count(inst->GetSingleWordInOperand(1)) != 0); @@ -46,8 +46,9 @@ bool RelaxFloatOpsPass::IsFloat32(Instruction* inst) { bool RelaxFloatOpsPass::IsRelaxed(uint32_t r_id) { for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false)) - if (r_inst->opcode() == SpvOpDecorate && - r_inst->GetSingleWordInOperand(1) == SpvDecorationRelaxedPrecision) + if (r_inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(r_inst->GetSingleWordInOperand(1)) == + spv::Decoration::RelaxedPrecision) return true; return false; } @@ -58,7 +59,8 @@ bool RelaxFloatOpsPass::ProcessInst(Instruction* r_inst) { if (!IsFloat32(r_inst)) return false; if (IsRelaxed(r_id)) return false; if (!IsRelaxable(r_inst)) return false; - get_decoration_mgr()->AddDecoration(r_id, SpvDecorationRelaxedPrecision); + get_decoration_mgr()->AddDecoration( + r_id, uint32_t(spv::Decoration::RelaxedPrecision)); return true; } @@ -87,48 +89,48 @@ Pass::Status RelaxFloatOpsPass::Process() { void RelaxFloatOpsPass::Initialize() { target_ops_core_f_rslt_ = { - SpvOpLoad, - SpvOpPhi, - SpvOpVectorExtractDynamic, - SpvOpVectorInsertDynamic, - SpvOpVectorShuffle, - SpvOpCompositeExtract, - SpvOpCompositeConstruct, - SpvOpCompositeInsert, - SpvOpCopyObject, - SpvOpTranspose, - SpvOpConvertSToF, - SpvOpConvertUToF, - SpvOpFConvert, - // SpvOpQuantizeToF16, - SpvOpFNegate, - SpvOpFAdd, - SpvOpFSub, - SpvOpFMul, - SpvOpFDiv, - SpvOpFMod, - SpvOpVectorTimesScalar, - SpvOpMatrixTimesScalar, - SpvOpVectorTimesMatrix, - SpvOpMatrixTimesVector, - SpvOpMatrixTimesMatrix, - SpvOpOuterProduct, - SpvOpDot, - SpvOpSelect, + spv::Op::OpLoad, + spv::Op::OpPhi, + spv::Op::OpVectorExtractDynamic, + spv::Op::OpVectorInsertDynamic, + spv::Op::OpVectorShuffle, + spv::Op::OpCompositeExtract, + spv::Op::OpCompositeConstruct, + spv::Op::OpCompositeInsert, + spv::Op::OpCopyObject, + spv::Op::OpTranspose, + spv::Op::OpConvertSToF, + spv::Op::OpConvertUToF, + spv::Op::OpFConvert, + // spv::Op::OpQuantizeToF16, + spv::Op::OpFNegate, + spv::Op::OpFAdd, + spv::Op::OpFSub, + spv::Op::OpFMul, + spv::Op::OpFDiv, + spv::Op::OpFMod, + spv::Op::OpVectorTimesScalar, + spv::Op::OpMatrixTimesScalar, + spv::Op::OpVectorTimesMatrix, + spv::Op::OpMatrixTimesVector, + spv::Op::OpMatrixTimesMatrix, + spv::Op::OpOuterProduct, + spv::Op::OpDot, + spv::Op::OpSelect, }; target_ops_core_f_opnd_ = { - SpvOpFOrdEqual, - SpvOpFUnordEqual, - SpvOpFOrdNotEqual, - SpvOpFUnordNotEqual, - SpvOpFOrdLessThan, - SpvOpFUnordLessThan, - SpvOpFOrdGreaterThan, - SpvOpFUnordGreaterThan, - SpvOpFOrdLessThanEqual, - SpvOpFUnordLessThanEqual, - SpvOpFOrdGreaterThanEqual, - SpvOpFUnordGreaterThanEqual, + spv::Op::OpFOrdEqual, + spv::Op::OpFUnordEqual, + spv::Op::OpFOrdNotEqual, + spv::Op::OpFUnordNotEqual, + spv::Op::OpFOrdLessThan, + spv::Op::OpFUnordLessThan, + spv::Op::OpFOrdGreaterThan, + spv::Op::OpFUnordGreaterThan, + spv::Op::OpFOrdLessThanEqual, + spv::Op::OpFUnordLessThanEqual, + spv::Op::OpFOrdGreaterThanEqual, + spv::Op::OpFUnordGreaterThanEqual, }; target_ops_450_ = { GLSLstd450Round, GLSLstd450RoundEven, GLSLstd450Trunc, GLSLstd450FAbs, @@ -147,31 +149,31 @@ void RelaxFloatOpsPass::Initialize() { GLSLstd450Ldexp, GLSLstd450Length, GLSLstd450Distance, GLSLstd450Cross, GLSLstd450Normalize, GLSLstd450FaceForward, GLSLstd450Reflect, GLSLstd450Refract, GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp}; - sample_ops_ = {SpvOpImageSampleImplicitLod, - SpvOpImageSampleExplicitLod, - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleDrefExplicitLod, - SpvOpImageSampleProjImplicitLod, - SpvOpImageSampleProjExplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSampleProjDrefExplicitLod, - SpvOpImageFetch, - SpvOpImageGather, - SpvOpImageDrefGather, - SpvOpImageRead, - SpvOpImageSparseSampleImplicitLod, - SpvOpImageSparseSampleExplicitLod, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleDrefExplicitLod, - SpvOpImageSparseSampleProjImplicitLod, - SpvOpImageSparseSampleProjExplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, - SpvOpImageSparseSampleProjDrefExplicitLod, - SpvOpImageSparseFetch, - SpvOpImageSparseGather, - SpvOpImageSparseDrefGather, - SpvOpImageSparseTexelsResident, - SpvOpImageSparseRead}; + sample_ops_ = {spv::Op::OpImageSampleImplicitLod, + spv::Op::OpImageSampleExplicitLod, + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleProjImplicitLod, + spv::Op::OpImageSampleProjExplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageFetch, + spv::Op::OpImageGather, + spv::Op::OpImageDrefGather, + spv::Op::OpImageRead, + spv::Op::OpImageSparseSampleImplicitLod, + spv::Op::OpImageSparseSampleExplicitLod, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleDrefExplicitLod, + spv::Op::OpImageSparseSampleProjImplicitLod, + spv::Op::OpImageSparseSampleProjExplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleProjDrefExplicitLod, + spv::Op::OpImageSparseFetch, + spv::Op::OpImageSparseGather, + spv::Op::OpImageSparseDrefGather, + spv::Op::OpImageSparseTexelsResident, + spv::Op::OpImageSparseRead}; } } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.h b/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.h index 5ee3d73c8..9e4606f8d 100644 --- a/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.h +++ b/3rdparty/spirv-tools/source/opt/relax_float_ops_pass.h @@ -61,17 +61,23 @@ class RelaxFloatOpsPass : public Pass { // Initialize state for converting to half void Initialize(); + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + // Set of float result core operations to be processed - std::unordered_set target_ops_core_f_rslt_; + std::unordered_set target_ops_core_f_rslt_; // Set of float operand core operations to be processed - std::unordered_set target_ops_core_f_opnd_; + std::unordered_set target_ops_core_f_opnd_; // Set of 450 extension operations to be processed std::unordered_set target_ops_450_; // Set of sample operations - std::unordered_set sample_ops_; + std::unordered_set sample_ops_; }; } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/remove_dontinline_pass.cpp b/3rdparty/spirv-tools/source/opt/remove_dontinline_pass.cpp index 4dd1cd4f2..3750bc1fe 100644 --- a/3rdparty/spirv-tools/source/opt/remove_dontinline_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/remove_dontinline_pass.cpp @@ -37,10 +37,11 @@ bool RemoveDontInline::ClearDontInlineFunctionControl(Function* function) { uint32_t function_control = function_inst->GetSingleWordInOperand(kFunctionControlInOperandIdx); - if ((function_control & SpvFunctionControlDontInlineMask) == 0) { + if ((function_control & uint32_t(spv::FunctionControlMask::DontInline)) == + 0) { return false; } - function_control &= ~SpvFunctionControlDontInlineMask; + function_control &= ~uint32_t(spv::FunctionControlMask::DontInline); function_inst->SetInOperand(kFunctionControlInOperandIdx, {function_control}); return true; } diff --git a/3rdparty/spirv-tools/source/opt/remove_duplicates_pass.cpp b/3rdparty/spirv-tools/source/opt/remove_duplicates_pass.cpp index 1ed8e2a04..90c3acff2 100644 --- a/3rdparty/spirv-tools/source/opt/remove_duplicates_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/remove_duplicates_pass.cpp @@ -70,7 +70,7 @@ bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports() const { return modified; } - std::unordered_map ext_inst_imports; + std::unordered_map ext_inst_imports; for (auto* i = &*context()->ext_inst_import_begin(); i;) { auto res = ext_inst_imports.emplace(i->GetInOperand(0u).AsString(), i->result_id()); @@ -101,7 +101,8 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { std::vector visited_forward_pointers; std::vector to_delete; for (auto* i = &*context()->types_values_begin(); i; i = i->NextNode()) { - const bool is_i_forward_pointer = i->opcode() == SpvOpTypeForwardPointer; + const bool is_i_forward_pointer = + i->opcode() == spv::Op::OpTypeForwardPointer; // We only care about types. if (!spvOpcodeGeneratesType(i->opcode()) && !is_i_forward_pointer) { @@ -110,7 +111,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { if (!is_i_forward_pointer) { // Is the current type equal to one of the types we have already visited? - SpvId id_to_keep = 0u; + spv::Id id_to_keep = 0u; analysis::Type* i_type = type_manager.GetType(i->result_id()); assert(i_type); // TODO(dneto0): Use a trie to avoid quadratic behaviour? Extract the @@ -137,7 +138,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { } else { analysis::ForwardPointer i_type( i->GetSingleWordInOperand(0u), - (SpvStorageClass)i->GetSingleWordInOperand(1u)); + (spv::StorageClass)i->GetSingleWordInOperand(1u)); i_type.SetTargetPointer( type_manager.GetType(i_type.target_id())->AsPointer()); diff --git a/3rdparty/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp b/3rdparty/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp index 31e87bd4b..d4df1b2ef 100644 --- a/3rdparty/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp @@ -31,13 +31,14 @@ class RemoveUnusedInterfaceVariablesContext { instruction.ForEachInId([&](const uint32_t* id) { if (used_variables_.count(*id)) return; auto* var = parent_.get_def_use_mgr()->GetDef(*id); - if (!var || var->opcode() != SpvOpVariable) return; - auto storage_class = var->GetSingleWordInOperand(0); - if (storage_class != SpvStorageClassFunction && + if (!var || var->opcode() != spv::Op::OpVariable) return; + auto storage_class = + spv::StorageClass(var->GetSingleWordInOperand(0)); + if (storage_class != spv::StorageClass::Function && (parent_.get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4) || - storage_class == SpvStorageClassInput || - storage_class == SpvStorageClassOutput)) + storage_class == spv::StorageClass::Input || + storage_class == spv::StorageClass::Output)) used_variables_.insert(*id); }); return false; @@ -90,4 +91,4 @@ RemoveUnusedInterfaceVariablesPass::Process() { return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); } } // namespace opt -} // namespace spvtools \ No newline at end of file +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp b/3rdparty/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp index e97593ef3..59745e12d 100644 --- a/3rdparty/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp +++ b/3rdparty/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp @@ -21,11 +21,10 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kOpAccessChainInOperandIndexes = 1; -const uint32_t kOpTypePointerInOperandType = 1; -const uint32_t kOpTypeArrayInOperandType = 0; -const uint32_t kOpTypeStructInOperandMember = 0; +constexpr uint32_t kOpAccessChainInOperandIndexes = 1; +constexpr uint32_t kOpTypePointerInOperandType = 1; +constexpr uint32_t kOpTypeArrayInOperandType = 0; +constexpr uint32_t kOpTypeStructInOperandMember = 0; IRContext::Analysis kAnalysisDefUseAndInstrToBlockMapping = IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping; @@ -54,8 +53,8 @@ bool ReplaceDescArrayAccessUsingVarIndex:: std::vector work_list; get_def_use_mgr()->ForEachUser(var, [&work_list](Instruction* use) { switch (use->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: work_list.push_back(use); break; default: @@ -132,8 +131,8 @@ ReplaceDescArrayAccessUsingVarIndex::CollectRequiredImageAndAccessInsts( Instruction* operand = get_def_use_mgr()->GetDef(*idp); if (context()->get_instr_block(operand) != nullptr && (HasImageOrImagePtrType(operand) || - operand->opcode() == SpvOpAccessChain || - operand->opcode() == SpvOpInBoundsAccessChain)) { + operand->opcode() == spv::Op::OpAccessChain || + operand->opcode() == spv::Op::OpInBoundsAccessChain)) { work_list.push(operand); } }; @@ -158,22 +157,22 @@ bool ReplaceDescArrayAccessUsingVarIndex::HasImageOrImagePtrType( bool ReplaceDescArrayAccessUsingVarIndex::IsImageOrImagePtrType( const Instruction* type_inst) const { - if (type_inst->opcode() == SpvOpTypeImage || - type_inst->opcode() == SpvOpTypeSampler || - type_inst->opcode() == SpvOpTypeSampledImage) { + if (type_inst->opcode() == spv::Op::OpTypeImage || + type_inst->opcode() == spv::Op::OpTypeSampler || + type_inst->opcode() == spv::Op::OpTypeSampledImage) { return true; } - if (type_inst->opcode() == SpvOpTypePointer) { + if (type_inst->opcode() == spv::Op::OpTypePointer) { Instruction* pointee_type_inst = get_def_use_mgr()->GetDef( type_inst->GetSingleWordInOperand(kOpTypePointerInOperandType)); return IsImageOrImagePtrType(pointee_type_inst); } - if (type_inst->opcode() == SpvOpTypeArray) { + if (type_inst->opcode() == spv::Op::OpTypeArray) { Instruction* element_type_inst = get_def_use_mgr()->GetDef( type_inst->GetSingleWordInOperand(kOpTypeArrayInOperandType)); return IsImageOrImagePtrType(element_type_inst); } - if (type_inst->opcode() != SpvOpTypeStruct) return false; + if (type_inst->opcode() != spv::Op::OpTypeStruct) return false; for (uint32_t in_operand_idx = kOpTypeStructInOperandMember; in_operand_idx < type_inst->NumInOperands(); ++in_operand_idx) { Instruction* member_type_inst = get_def_use_mgr()->GetDef( @@ -186,16 +185,16 @@ bool ReplaceDescArrayAccessUsingVarIndex::IsImageOrImagePtrType( bool ReplaceDescArrayAccessUsingVarIndex::IsConcreteType( uint32_t type_id) const { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); - if (type_inst->opcode() == SpvOpTypeInt || - type_inst->opcode() == SpvOpTypeFloat) { + if (type_inst->opcode() == spv::Op::OpTypeInt || + type_inst->opcode() == spv::Op::OpTypeFloat) { return true; } - if (type_inst->opcode() == SpvOpTypeVector || - type_inst->opcode() == SpvOpTypeMatrix || - type_inst->opcode() == SpvOpTypeArray) { + if (type_inst->opcode() == spv::Op::OpTypeVector || + type_inst->opcode() == spv::Op::OpTypeMatrix || + type_inst->opcode() == spv::Op::OpTypeArray) { return IsConcreteType(type_inst->GetSingleWordInOperand(0)); } - if (type_inst->opcode() == SpvOpTypeStruct) { + if (type_inst->opcode() == spv::Op::OpTypeStruct) { for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { if (!IsConcreteType(type_inst->GetSingleWordInOperand(i))) return false; } @@ -322,8 +321,8 @@ ReplaceDescArrayAccessUsingVarIndex::SeparateInstructionsIntoNewBlock( } BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateNewBlock() const { - auto* new_block = new BasicBlock(std::unique_ptr( - new Instruction(context(), SpvOpLabel, 0, context()->TakeNextId(), {}))); + auto* new_block = new BasicBlock(std::unique_ptr(new Instruction( + context(), spv::Op::OpLabel, 0, context()->TakeNextId(), {}))); get_def_use_mgr()->AnalyzeInstDefUse(new_block->GetLabelInst()); context()->set_instr_block(new_block->GetLabelInst(), new_block); return new_block; @@ -332,7 +331,7 @@ BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateNewBlock() const { void ReplaceDescArrayAccessUsingVarIndex::UseConstIndexForAccessChain( Instruction* access_chain, uint32_t const_element_idx) const { uint32_t const_element_idx_id = - context()->get_constant_mgr()->GetUIntConst(const_element_idx); + context()->get_constant_mgr()->GetUIntConstId(const_element_idx); access_chain->SetInOperand(kOpAccessChainInOperandIndexes, {const_element_idx_id}); } @@ -422,7 +421,7 @@ void ReplaceDescArrayAccessUsingVarIndex::ReplacePhiIncomingBlock( uint32_t old_incoming_block_id, uint32_t new_incoming_block_id) const { context()->ReplaceAllUsesWithPredicate( old_incoming_block_id, new_incoming_block_id, - [](Instruction* use) { return use->opcode() == SpvOpPhi; }); + [](Instruction* use) { return use->opcode() == spv::Op::OpPhi; }); } } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp b/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp index 1dcd06f59..214097398 100644 --- a/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp +++ b/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp @@ -23,16 +23,16 @@ namespace opt { Pass::Status ReplaceInvalidOpcodePass::Process() { bool modified = false; - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage)) { + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Linkage)) { return Status::SuccessWithoutChange; } - SpvExecutionModel execution_model = GetExecutionModel(); - if (execution_model == SpvExecutionModelKernel) { + spv::ExecutionModel execution_model = GetExecutionModel(); + if (execution_model == spv::ExecutionModel::Kernel) { // We do not handle kernels. return Status::SuccessWithoutChange; } - if (execution_model == SpvExecutionModelMax) { + if (execution_model == spv::ExecutionModel::Max) { // Mixed execution models for the entry points. This case is not currently // handled. return Status::SuccessWithoutChange; @@ -44,19 +44,19 @@ Pass::Status ReplaceInvalidOpcodePass::Process() { return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); } -SpvExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { - SpvExecutionModel result = SpvExecutionModelMax; +spv::ExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { + spv::ExecutionModel result = spv::ExecutionModel::Max; bool first = true; for (Instruction& entry_point : get_module()->entry_points()) { if (first) { - result = - static_cast(entry_point.GetSingleWordInOperand(0)); + result = static_cast( + entry_point.GetSingleWordInOperand(0)); first = false; } else { - SpvExecutionModel current_model = - static_cast(entry_point.GetSingleWordInOperand(0)); + spv::ExecutionModel current_model = static_cast( + entry_point.GetSingleWordInOperand(0)); if (current_model != result) { - result = SpvExecutionModelMax; + result = spv::ExecutionModel::Max; break; } } @@ -65,13 +65,13 @@ SpvExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { } bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, - SpvExecutionModel model) { + spv::ExecutionModel model) { bool modified = false; Instruction* last_line_dbg_inst = nullptr; function->ForEachInst( [model, &modified, &last_line_dbg_inst, this](Instruction* inst) { // Track the debug information so we can have a meaningful message. - if (inst->opcode() == SpvOpLabel || inst->IsNoLine()) { + if (inst->opcode() == spv::Op::OpLabel || inst->IsNoLine()) { last_line_dbg_inst = nullptr; return; } else if (inst->IsLine()) { @@ -80,15 +80,15 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, } bool replace = false; - if (model != SpvExecutionModelFragment && + if (model != spv::ExecutionModel::Fragment && IsFragmentShaderOnlyInstruction(inst)) { replace = true; } - if (model != SpvExecutionModelTessellationControl && - model != SpvExecutionModelGLCompute) { - if (inst->opcode() == SpvOpControlBarrier) { - assert(model != SpvExecutionModelKernel && + if (model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::GLCompute) { + if (inst->opcode() == spv::Op::OpControlBarrier) { + assert(model != spv::ExecutionModel::Kernel && "Expecting to be working on a shader module."); replace = true; } @@ -101,7 +101,7 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, } else { // Get the name of the source file. uint32_t file_name_id = 0; - if (last_line_dbg_inst->opcode() == SpvOpLine) { + if (last_line_dbg_inst->opcode() == spv::Op::OpLine) { file_name_id = last_line_dbg_inst->GetSingleWordInOperand(0); } else { // Shader100::DebugLine uint32_t debug_source_id = @@ -131,26 +131,26 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, bool ReplaceInvalidOpcodePass::IsFragmentShaderOnlyInstruction( Instruction* inst) { switch (inst->opcode()) { - case SpvOpDPdx: - case SpvOpDPdy: - case SpvOpFwidth: - case SpvOpDPdxFine: - case SpvOpDPdyFine: - case SpvOpFwidthFine: - case SpvOpDPdxCoarse: - case SpvOpDPdyCoarse: - case SpvOpFwidthCoarse: - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageQueryLod: + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpFwidth: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpFwidthFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidthCoarse: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageQueryLod: // TODO: Teach |ReplaceInstruction| to handle block terminators. Then // uncomment the OpKill case. - // case SpvOpKill: - // case SpvOpTerminateInstruction: + // case spv::Op::OpKill: + // case spv::Op::OpTerminateInstruction: return true; default: return false; @@ -183,7 +183,7 @@ uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { analysis::TypeManager* type_mgr = context()->get_type_mgr(); Instruction* type = context()->get_def_use_mgr()->GetDef(type_id); - if (type->opcode() == SpvOpTypeVector) { + if (type->opcode() == spv::Op::OpTypeVector) { uint32_t component_const = GetSpecialConstant(type->GetSingleWordInOperand(0)); std::vector ids; @@ -192,7 +192,8 @@ uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { } special_const = const_mgr->GetConstant(type_mgr->GetType(type_id), ids); } else { - assert(type->opcode() == SpvOpTypeInt || type->opcode() == SpvOpTypeFloat); + assert(type->opcode() == spv::Op::OpTypeInt || + type->opcode() == spv::Op::OpTypeFloat); std::vector literal_words; for (uint32_t i = 0; i < type->GetSingleWordInOperand(0); i += 32) { literal_words.push_back(0xDEADBEEF); @@ -204,7 +205,7 @@ uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { return const_mgr->GetDefiningInstruction(special_const)->result_id(); } -std::string ReplaceInvalidOpcodePass::BuildWarningMessage(SpvOp opcode) { +std::string ReplaceInvalidOpcodePass::BuildWarningMessage(spv::Op opcode) { spv_opcode_desc opcode_info; context()->grammar().lookupOpcode(opcode, &opcode_info); std::string message = "Removing "; diff --git a/3rdparty/spirv-tools/source/opt/replace_invalid_opc.h b/3rdparty/spirv-tools/source/opt/replace_invalid_opc.h index 426bcac5e..3f0d16bba 100644 --- a/3rdparty/spirv-tools/source/opt/replace_invalid_opc.h +++ b/3rdparty/spirv-tools/source/opt/replace_invalid_opc.h @@ -34,13 +34,13 @@ class ReplaceInvalidOpcodePass : public Pass { private: // Returns the execution model that is used by every entry point in the // module. If more than one execution model is used in the module, then the - // return value is SpvExecutionModelMax. - SpvExecutionModel GetExecutionModel(); + // return value is spv::ExecutionModel::Max. + spv::ExecutionModel GetExecutionModel(); // Replaces all instructions in |function| that are invalid with execution // model |mode|, but valid for another shader model, with a special constant // value. See |GetSpecialConstant|. - bool RewriteFunction(Function* function, SpvExecutionModel mode); + bool RewriteFunction(Function* function, spv::ExecutionModel mode); // Returns true if |inst| is valid for fragment shaders only. bool IsFragmentShaderOnlyInstruction(Instruction* inst); @@ -58,7 +58,7 @@ class ReplaceInvalidOpcodePass : public Pass { // width of the type has been reached. For a vector, each element of the // constant will be constructed the same way. uint32_t GetSpecialConstant(uint32_t type_id); - std::string BuildWarningMessage(SpvOp opcode); + std::string BuildWarningMessage(spv::Op opcode); }; } // namespace opt diff --git a/3rdparty/spirv-tools/source/opt/scalar_analysis.cpp b/3rdparty/spirv-tools/source/opt/scalar_analysis.cpp index 2b0a824cf..0c8babe8a 100644 --- a/3rdparty/spirv-tools/source/opt/scalar_analysis.cpp +++ b/3rdparty/spirv-tools/source/opt/scalar_analysis.cpp @@ -97,7 +97,7 @@ SENode* ScalarEvolutionAnalysis::CreateRecurrentExpression( SENode* ScalarEvolutionAnalysis::AnalyzeMultiplyOp( const Instruction* multiply) { - assert(multiply->opcode() == SpvOp::SpvOpIMul && + assert(multiply->opcode() == spv::Op::OpIMul && "Multiply node did not come from a multiply instruction"); analysis::DefUseManager* def_use = context_->get_def_use_mgr(); @@ -168,21 +168,21 @@ SENode* ScalarEvolutionAnalysis::AnalyzeInstruction(const Instruction* inst) { SENode* output = nullptr; switch (inst->opcode()) { - case SpvOp::SpvOpPhi: { + case spv::Op::OpPhi: { output = AnalyzePhiInstruction(inst); break; } - case SpvOp::SpvOpConstant: - case SpvOp::SpvOpConstantNull: { + case spv::Op::OpConstant: + case spv::Op::OpConstantNull: { output = AnalyzeConstant(inst); break; } - case SpvOp::SpvOpISub: - case SpvOp::SpvOpIAdd: { + case spv::Op::OpISub: + case spv::Op::OpIAdd: { output = AnalyzeAddOp(inst); break; } - case SpvOp::SpvOpIMul: { + case spv::Op::OpIMul: { output = AnalyzeMultiplyOp(inst); break; } @@ -196,9 +196,9 @@ SENode* ScalarEvolutionAnalysis::AnalyzeInstruction(const Instruction* inst) { } SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const Instruction* inst) { - if (inst->opcode() == SpvOp::SpvOpConstantNull) return CreateConstant(0); + if (inst->opcode() == spv::Op::OpConstantNull) return CreateConstant(0); - assert(inst->opcode() == SpvOp::SpvOpConstant); + assert(inst->opcode() == spv::Op::OpConstant); assert(inst->NumInOperands() == 1); int64_t value = 0; @@ -226,8 +226,8 @@ SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const Instruction* inst) { // Handles both addition and subtraction. If the |sub| flag is set then the // addition will be op1+(-op2) otherwise op1+op2. SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const Instruction* inst) { - assert((inst->opcode() == SpvOp::SpvOpIAdd || - inst->opcode() == SpvOp::SpvOpISub) && + assert((inst->opcode() == spv::Op::OpIAdd || + inst->opcode() == spv::Op::OpISub) && "Add node must be created from a OpIAdd or OpISub instruction"); analysis::DefUseManager* def_use = context_->get_def_use_mgr(); @@ -239,7 +239,7 @@ SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const Instruction* inst) { AnalyzeInstruction(def_use->GetDef(inst->GetSingleWordInOperand(1))); // To handle subtraction we wrap the second operand in a unary negation node. - if (inst->opcode() == SpvOp::SpvOpISub) { + if (inst->opcode() == spv::Op::OpISub) { op2 = CreateNegation(op2); } @@ -573,7 +573,7 @@ struct PushToStringImpl { }; template -static void PushToString(T id, std::u32string* str) { +void PushToString(T id, std::u32string* str) { PushToStringImpl{}(id, str); } @@ -928,8 +928,8 @@ namespace { // Remove |node| from the |mul| chain (of the form A * ... * |node| * ... * Z), // if |node| is not in the chain, returns the original chain. -static SENode* RemoveOneNodeFromMultiplyChain(SEMultiplyNode* mul, - const SENode* node) { +SENode* RemoveOneNodeFromMultiplyChain(SEMultiplyNode* mul, + const SENode* node) { SENode* lhs = mul->GetChildren()[0]; SENode* rhs = mul->GetChildren()[1]; if (lhs == node) { diff --git a/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp b/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp index e27c828b0..bfebb01c8 100644 --- a/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp @@ -26,12 +26,13 @@ #include "source/util/make_unique.h" #include "types.h" -static const uint32_t kDebugValueOperandValueIndex = 5; -static const uint32_t kDebugValueOperandExpressionIndex = 6; -static const uint32_t kDebugDeclareOperandVariableIndex = 5; - namespace spvtools { namespace opt { +namespace { +constexpr uint32_t kDebugValueOperandValueIndex = 5; +constexpr uint32_t kDebugValueOperandExpressionIndex = 6; +constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; +} // namespace Pass::Status ScalarReplacementPass::Process() { Status status = Status::SuccessWithoutChange; @@ -56,7 +57,7 @@ Pass::Status ScalarReplacementPass::ProcessFunction(Function* function) { for (auto iter = entry.begin(); iter != entry.end(); ++iter) { // Function storage class OpVariables must appear as the first instructions // of the entry block. - if (iter->opcode() != SpvOpVariable) break; + if (iter->opcode() != spv::Op::OpVariable) break; Instruction* varInst = &*iter; if (CanReplaceVariable(varInst)) { @@ -105,29 +106,29 @@ Pass::Status ScalarReplacementPass::ReplaceVariable( } if (!IsAnnotationInst(user->opcode())) { switch (user->opcode()) { - case SpvOpLoad: + case spv::Op::OpLoad: if (ReplaceWholeLoad(user, replacements)) { dead.push_back(user); } else { return false; } break; - case SpvOpStore: + case spv::Op::OpStore: if (ReplaceWholeStore(user, replacements)) { dead.push_back(user); } else { return false; } break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: if (ReplaceAccessChain(user, replacements)) dead.push_back(user); else return false; break; - case SpvOpName: - case SpvOpMemberName: + case spv::Op::OpName: + case spv::Op::OpMemberName: break; default: assert(false && "Unexpected opcode"); @@ -155,7 +156,7 @@ Pass::Status ScalarReplacementPass::ReplaceVariable( // Attempt to further scalarize. for (auto var : replacements) { - if (var->opcode() == SpvOpVariable) { + if (var->opcode() == spv::Op::OpVariable) { if (get_def_use_mgr()->NumUsers(var) == 0) { context()->KillInst(var); } else if (CanReplaceVariable(var)) { @@ -179,7 +180,7 @@ bool ScalarReplacementPass::ReplaceWholeDebugDeclare( int32_t idx = 0; for (const auto* var : replacements) { Instruction* insert_before = var->NextNode(); - while (insert_before->opcode() == SpvOpVariable) + while (insert_before->opcode() == spv::Op::OpVariable) insert_before = insert_before->NextNode(); assert(insert_before != nullptr && "unexpected end of list"); Instruction* added_dbg_value = @@ -190,7 +191,7 @@ bool ScalarReplacementPass::ReplaceWholeDebugDeclare( if (added_dbg_value == nullptr) return false; added_dbg_value->AddOperand( {SPV_OPERAND_TYPE_ID, - {context()->get_constant_mgr()->GetSIntConst(idx)}}); + {context()->get_constant_mgr()->GetSIntConstId(idx)}}); added_dbg_value->SetOperand(kDebugValueOperandExpressionIndex, {deref_expr->result_id()}); if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) { @@ -216,7 +217,7 @@ bool ScalarReplacementPass::ReplaceWholeDebugValue( // Append 'Indexes' operand. new_dbg_value->AddOperand( {SPV_OPERAND_TYPE_ID, - {context()->get_constant_mgr()->GetSIntConst(idx)}}); + {context()->get_constant_mgr()->GetSIntConstId(idx)}}); // Insert the new DebugValue to the basic block. auto* added_instr = dbg_value->InsertBefore(std::move(new_dbg_value)); get_def_use_mgr()->AnalyzeInstDefUse(added_instr); @@ -236,7 +237,7 @@ bool ScalarReplacementPass::ReplaceWholeLoad( BasicBlock::iterator where(load); for (auto var : replacements) { // Create a load of each replacement variable. - if (var->opcode() != SpvOpVariable) { + if (var->opcode() != spv::Op::OpVariable) { loads.push_back(var); continue; } @@ -247,7 +248,7 @@ bool ScalarReplacementPass::ReplaceWholeLoad( return false; } std::unique_ptr newLoad( - new Instruction(context(), SpvOpLoad, type->result_id(), loadId, + new Instruction(context(), spv::Op::OpLoad, type->result_id(), loadId, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); // Copy memory access attributes which start at index 1. Index 0 is the @@ -269,8 +270,9 @@ bool ScalarReplacementPass::ReplaceWholeLoad( return false; } where = load; - std::unique_ptr compositeConstruct(new Instruction( - context(), SpvOpCompositeConstruct, load->type_id(), compositeId, {})); + std::unique_ptr compositeConstruct( + new Instruction(context(), spv::Op::OpCompositeConstruct, load->type_id(), + compositeId, {})); for (auto l : loads) { Operand op(SPV_OPERAND_TYPE_ID, std::initializer_list{l->result_id()}); @@ -294,7 +296,7 @@ bool ScalarReplacementPass::ReplaceWholeStore( uint32_t elementIndex = 0; for (auto var : replacements) { // Create the extract. - if (var->opcode() != SpvOpVariable) { + if (var->opcode() != spv::Op::OpVariable) { elementIndex++; continue; } @@ -305,7 +307,7 @@ bool ScalarReplacementPass::ReplaceWholeStore( return false; } std::unique_ptr extract(new Instruction( - context(), SpvOpCompositeExtract, type->result_id(), extractId, + context(), spv::Op::OpCompositeExtract, type->result_id(), extractId, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {storeInput}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {elementIndex++}}})); @@ -316,7 +318,7 @@ bool ScalarReplacementPass::ReplaceWholeStore( // Create the store. std::unique_ptr newStore( - new Instruction(context(), SpvOpStore, 0, 0, + new Instruction(context(), spv::Op::OpStore, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {var->result_id()}}, {SPV_OPERAND_TYPE_ID, {extractId}}})); @@ -390,7 +392,7 @@ bool ScalarReplacementPass::CreateReplacementVariables( uint32_t elem = 0; switch (type->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: type->ForEachInOperand( [this, inst, &elem, replacements, &components_used](uint32_t* id) { if (!components_used || components_used->count(elem)) { @@ -401,7 +403,7 @@ bool ScalarReplacementPass::CreateReplacementVariables( elem++; }); break; - case SpvOpTypeArray: + case spv::Op::OpTypeArray: for (uint32_t i = 0; i != GetArrayLength(type); ++i) { if (!components_used || components_used->count(i)) { CreateVariable(type->GetSingleWordInOperand(0u), inst, i, @@ -413,8 +415,8 @@ bool ScalarReplacementPass::CreateReplacementVariables( } break; - case SpvOpTypeMatrix: - case SpvOpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: for (uint32_t i = 0; i != GetNumElements(type); ++i) { CreateVariable(type->GetSingleWordInOperand(0u), inst, i, replacements); } @@ -440,20 +442,20 @@ void ScalarReplacementPass::TransferAnnotations( // no type or member decorations that are necessary to transfer. for (auto inst : get_decoration_mgr()->GetDecorationsFor(source->result_id(), false)) { - assert(inst->opcode() == SpvOpDecorate); - uint32_t decoration = inst->GetSingleWordInOperand(1u); - if (decoration == SpvDecorationInvariant || - decoration == SpvDecorationRestrict) { + assert(inst->opcode() == spv::Op::OpDecorate); + auto decoration = spv::Decoration(inst->GetSingleWordInOperand(1u)); + if (decoration == spv::Decoration::Invariant || + decoration == spv::Decoration::Restrict) { for (auto var : *replacements) { if (var == nullptr) { continue; } - std::unique_ptr annotation( - new Instruction(context(), SpvOpDecorate, 0, 0, - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {var->result_id()}}, - {SPV_OPERAND_TYPE_DECORATION, {decoration}}})); + std::unique_ptr annotation(new Instruction( + context(), spv::Op::OpDecorate, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_DECORATION, {uint32_t(decoration)}}})); for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { Operand copy(inst->GetInOperand(i)); annotation->AddOperand(std::move(copy)); @@ -475,10 +477,11 @@ void ScalarReplacementPass::CreateVariable( replacements->push_back(nullptr); } - std::unique_ptr variable(new Instruction( - context(), SpvOpVariable, ptrId, id, - std::initializer_list{ - {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); + std::unique_ptr variable( + new Instruction(context(), spv::Op::OpVariable, ptrId, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}})); BasicBlock* block = context()->get_instr_block(varInst); block->begin().InsertBefore(std::move(variable)); @@ -494,7 +497,7 @@ void ScalarReplacementPass::CreateVariable( for (auto dec_inst : get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) { uint32_t decoration; - if (dec_inst->opcode() != SpvOpMemberDecorate) { + if (dec_inst->opcode() != spv::Op::OpMemberDecorate) { continue; } @@ -503,10 +506,10 @@ void ScalarReplacementPass::CreateVariable( } decoration = dec_inst->GetSingleWordInOperand(2u); - switch (decoration) { - case SpvDecorationRelaxedPrecision: { + switch (spv::Decoration(decoration)) { + case spv::Decoration::RelaxedPrecision: { std::unique_ptr new_dec_inst( - new Instruction(context(), SpvOpDecorate, 0, 0, {})); + new Instruction(context(), spv::Op::OpDecorate, 0, 0, {})); new_dec_inst->AddOperand(Operand(SPV_OPERAND_TYPE_ID, {id})); for (uint32_t i = 2; i < dec_inst->NumInOperandWords(); ++i) { new_dec_inst->AddOperand(Operand(dec_inst->GetInOperand(i))); @@ -531,8 +534,8 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) { analysis::Type* pointeeTy; std::unique_ptr pointerTy; std::tie(pointeeTy, pointerTy) = - context()->get_type_mgr()->GetTypeAndPointerType(id, - SpvStorageClassFunction); + context()->get_type_mgr()->GetTypeAndPointerType( + id, spv::StorageClass::Function); uint32_t ptrId = 0; if (pointeeTy->IsUniqueType()) { // Non-ambiguous type, just ask the type manager for an id. @@ -544,8 +547,9 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) { // Ambiguous type. We must perform a linear search to try and find the right // type. for (auto global : context()->types_values()) { - if (global.opcode() == SpvOpTypePointer && - global.GetSingleWordInOperand(0u) == SpvStorageClassFunction && + if (global.opcode() == spv::Op::OpTypePointer && + spv::StorageClass(global.GetSingleWordInOperand(0u)) == + spv::StorageClass::Function && global.GetSingleWordInOperand(1u) == id) { if (get_decoration_mgr()->GetDecorationsFor(id, false).empty()) { // Only reuse a decoration-less pointer of the correct type. @@ -562,10 +566,10 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) { ptrId = TakeNextId(); context()->AddType(MakeUnique( - context(), SpvOpTypePointer, 0, ptrId, - std::initializer_list{ - {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, - {SPV_OPERAND_TYPE_ID, {id}}})); + context(), spv::Op::OpTypePointer, 0, ptrId, + std::initializer_list{{SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}, + {SPV_OPERAND_TYPE_ID, {id}}})); Instruction* ptr = &*--context()->types_values_end(); get_def_use_mgr()->AnalyzeInstDefUse(ptr); pointee_to_pointer_[id] = ptrId; @@ -578,7 +582,7 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) { void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, uint32_t index, Instruction* newVar) { - assert(source->opcode() == SpvOpVariable); + assert(source->opcode() == spv::Op::OpVariable); if (source->NumInOperands() < 2) return; uint32_t initId = source->GetSingleWordInOperand(1u); @@ -586,14 +590,14 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, Instruction* init = get_def_use_mgr()->GetDef(initId); uint32_t newInitId = 0; // TODO(dnovillo): Refactor this with constant propagation. - if (init->opcode() == SpvOpConstantNull) { + if (init->opcode() == spv::Op::OpConstantNull) { // Initialize to appropriate NULL. auto iter = type_to_null_.find(storageId); if (iter == type_to_null_.end()) { newInitId = TakeNextId(); type_to_null_[storageId] = newInitId; context()->AddGlobalValue( - MakeUnique(context(), SpvOpConstantNull, storageId, + MakeUnique(context(), spv::Op::OpConstantNull, storageId, newInitId, std::initializer_list{})); Instruction* newNull = &*--context()->types_values_end(); get_def_use_mgr()->AnalyzeInstDefUse(newNull); @@ -604,18 +608,19 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, // Create a new constant extract. newInitId = TakeNextId(); context()->AddGlobalValue(MakeUnique( - context(), SpvOpSpecConstantOp, storageId, newInitId, + context(), spv::Op::OpSpecConstantOp, storageId, newInitId, std::initializer_list{ - {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, {SpvOpCompositeExtract}}, + {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, + {uint32_t(spv::Op::OpCompositeExtract)}}, {SPV_OPERAND_TYPE_ID, {init->result_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}}})); Instruction* newSpecConst = &*--context()->types_values_end(); get_def_use_mgr()->AnalyzeInstDefUse(newSpecConst); - } else if (init->opcode() == SpvOpConstantComposite) { + } else if (init->opcode() == spv::Op::OpConstantComposite) { // Get the appropriate index constant. newInitId = init->GetSingleWordInOperand(index); Instruction* element = get_def_use_mgr()->GetDef(newInitId); - if (element->opcode() == SpvOpUndef) { + if (element->opcode() == spv::Op::OpUndef) { // Undef is not a valid initializer for a variable. newInitId = 0; } @@ -630,7 +635,7 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, uint64_t ScalarReplacementPass::GetArrayLength( const Instruction* arrayType) const { - assert(arrayType->opcode() == SpvOpTypeArray); + assert(arrayType->opcode() == spv::Op::OpTypeArray); const Instruction* length = get_def_use_mgr()->GetDef(arrayType->GetSingleWordInOperand(1u)); return context() @@ -640,8 +645,8 @@ uint64_t ScalarReplacementPass::GetArrayLength( } uint64_t ScalarReplacementPass::GetNumElements(const Instruction* type) const { - assert(type->opcode() == SpvOpTypeVector || - type->opcode() == SpvOpTypeMatrix); + assert(type->opcode() == spv::Op::OpTypeVector || + type->opcode() == spv::Op::OpTypeMatrix); const Operand& op = type->GetInOperand(1u); assert(op.words.size() <= 2); uint64_t len = 0; @@ -659,7 +664,7 @@ bool ScalarReplacementPass::IsSpecConstant(uint32_t id) const { Instruction* ScalarReplacementPass::GetStorageType( const Instruction* inst) const { - assert(inst->opcode() == SpvOpVariable); + assert(inst->opcode() == spv::Op::OpVariable); uint32_t ptrTypeId = inst->type_id(); uint32_t typeId = @@ -669,10 +674,11 @@ Instruction* ScalarReplacementPass::GetStorageType( bool ScalarReplacementPass::CanReplaceVariable( const Instruction* varInst) const { - assert(varInst->opcode() == SpvOpVariable); + assert(varInst->opcode() == spv::Op::OpVariable); // Can only replace function scope variables. - if (varInst->GetSingleWordInOperand(0u) != SpvStorageClassFunction) { + if (spv::StorageClass(varInst->GetSingleWordInOperand(0u)) != + spv::StorageClass::Function) { return false; } @@ -702,14 +708,14 @@ bool ScalarReplacementPass::CheckType(const Instruction* typeInst) const { } switch (typeInst->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: // Don't bother with empty structs or very large structs. if (typeInst->NumInOperands() == 0 || IsLargerThanSizeLimit(typeInst->NumInOperands())) { return false; } return true; - case SpvOpTypeArray: + case spv::Op::OpTypeArray: if (IsSpecConstant(typeInst->GetSingleWordInOperand(1u))) { return false; } @@ -721,12 +727,12 @@ bool ScalarReplacementPass::CheckType(const Instruction* typeInst) const { // re-enabled. //// Specifically including matrix and vector in an attempt to reduce the //// number of vector registers required. - // case SpvOpTypeMatrix: - // case SpvOpTypeVector: + // case spv::Op::OpTypeMatrix: + // case spv::Op::OpTypeVector: // if (IsLargerThanSizeLimit(GetNumElements(typeInst))) return false; // return true; - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeRuntimeArray: default: return false; } @@ -737,26 +743,26 @@ bool ScalarReplacementPass::CheckTypeAnnotations( for (auto inst : get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) { uint32_t decoration; - if (inst->opcode() == SpvOpDecorate) { + if (inst->opcode() == spv::Op::OpDecorate) { decoration = inst->GetSingleWordInOperand(1u); } else { - assert(inst->opcode() == SpvOpMemberDecorate); + assert(inst->opcode() == spv::Op::OpMemberDecorate); decoration = inst->GetSingleWordInOperand(2u); } - switch (decoration) { - case SpvDecorationRowMajor: - case SpvDecorationColMajor: - case SpvDecorationArrayStride: - case SpvDecorationMatrixStride: - case SpvDecorationCPacked: - case SpvDecorationInvariant: - case SpvDecorationRestrict: - case SpvDecorationOffset: - case SpvDecorationAlignment: - case SpvDecorationAlignmentId: - case SpvDecorationMaxByteOffset: - case SpvDecorationRelaxedPrecision: + switch (spv::Decoration(decoration)) { + case spv::Decoration::RowMajor: + case spv::Decoration::ColMajor: + case spv::Decoration::ArrayStride: + case spv::Decoration::MatrixStride: + case spv::Decoration::CPacked: + case spv::Decoration::Invariant: + case spv::Decoration::Restrict: + case spv::Decoration::Offset: + case spv::Decoration::Alignment: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffset: + case spv::Decoration::RelaxedPrecision: break; default: return false; @@ -769,14 +775,14 @@ bool ScalarReplacementPass::CheckTypeAnnotations( bool ScalarReplacementPass::CheckAnnotations(const Instruction* varInst) const { for (auto inst : get_decoration_mgr()->GetDecorationsFor(varInst->result_id(), false)) { - assert(inst->opcode() == SpvOpDecorate); - uint32_t decoration = inst->GetSingleWordInOperand(1u); + assert(inst->opcode() == spv::Op::OpDecorate); + auto decoration = spv::Decoration(inst->GetSingleWordInOperand(1u)); switch (decoration) { - case SpvDecorationInvariant: - case SpvDecorationRestrict: - case SpvDecorationAlignment: - case SpvDecorationAlignmentId: - case SpvDecorationMaxByteOffset: + case spv::Decoration::Invariant: + case spv::Decoration::Restrict: + case spv::Decoration::Alignment: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffset: break; default: return false; @@ -816,8 +822,8 @@ bool ScalarReplacementPass::CheckUses(const Instruction* inst, // Annotations are check as a group separately. if (!IsAnnotationInst(user->opcode())) { switch (user->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: if (index == 2u && user->NumInOperands() > 1) { uint32_t id = user->GetSingleWordInOperand(1u); const Instruction* opInst = get_def_use_mgr()->GetDef(id); @@ -835,16 +841,16 @@ bool ScalarReplacementPass::CheckUses(const Instruction* inst, ok = false; } break; - case SpvOpLoad: + case spv::Op::OpLoad: if (!CheckLoad(user, index)) ok = false; stats->num_full_accesses++; break; - case SpvOpStore: + case spv::Op::OpStore: if (!CheckStore(user, index)) ok = false; stats->num_full_accesses++; break; - case SpvOpName: - case SpvOpMemberName: + case spv::Op::OpName: + case spv::Op::OpMemberName: break; default: ok = false; @@ -861,24 +867,24 @@ bool ScalarReplacementPass::CheckUsesRelaxed(const Instruction* inst) const { get_def_use_mgr()->ForEachUse( inst, [this, &ok](const Instruction* user, uint32_t index) { switch (user->opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: if (index != 2u) { ok = false; } else { if (!CheckUsesRelaxed(user)) ok = false; } break; - case SpvOpLoad: + case spv::Op::OpLoad: if (!CheckLoad(user, index)) ok = false; break; - case SpvOpStore: + case spv::Op::OpStore: if (!CheckStore(user, index)) ok = false; break; - case SpvOpImageTexelPointer: + case spv::Op::OpImageTexelPointer: if (!CheckImageTexelPointer(index)) ok = false; break; - case SpvOpExtInst: + case spv::Op::OpExtInst: if (user->GetCommonDebugOpcode() != CommonDebugInfoDebugDeclare || !CheckDebugDeclare(index)) ok = false; @@ -900,7 +906,8 @@ bool ScalarReplacementPass::CheckLoad(const Instruction* inst, uint32_t index) const { if (index != 2u) return false; if (inst->NumInOperands() >= 2 && - inst->GetSingleWordInOperand(1u) & SpvMemoryAccessVolatileMask) + inst->GetSingleWordInOperand(1u) & + uint32_t(spv::MemoryAccessMask::Volatile)) return false; return true; } @@ -909,7 +916,8 @@ bool ScalarReplacementPass::CheckStore(const Instruction* inst, uint32_t index) const { if (index != 0u) return false; if (inst->NumInOperands() >= 3 && - inst->GetSingleWordInOperand(2u) & SpvMemoryAccessVolatileMask) + inst->GetSingleWordInOperand(2u) & + uint32_t(spv::MemoryAccessMask::Volatile)) return false; return true; } @@ -936,11 +944,11 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) { def_use_mgr->WhileEachUser(inst, [&result, def_use_mgr, this](Instruction* use) { switch (use->opcode()) { - case SpvOpLoad: { + case spv::Op::OpLoad: { // Look for extract from the load. std::vector t; if (def_use_mgr->WhileEachUser(use, [&t](Instruction* use2) { - if (use2->opcode() != SpvOpCompositeExtract || + if (use2->opcode() != spv::Op::OpCompositeExtract || use2->NumInOperands() <= 1) { return false; } @@ -954,13 +962,13 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) { return false; } } - case SpvOpName: - case SpvOpMemberName: - case SpvOpStore: + case spv::Op::OpName: + case spv::Op::OpMemberName: + case spv::Op::OpStore: // No components are used. return true; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: { // Add the first index it if is a constant. // TODO: Could be improved by checking if the address is used in a load. analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); @@ -988,16 +996,16 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) { uint64_t ScalarReplacementPass::GetMaxLegalIndex( const Instruction* var_inst) const { - assert(var_inst->opcode() == SpvOpVariable && + assert(var_inst->opcode() == spv::Op::OpVariable && "|var_inst| must be a variable instruction."); Instruction* type = GetStorageType(var_inst); switch (type->opcode()) { - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: return type->NumInOperands(); - case SpvOpTypeArray: + case spv::Op::OpTypeArray: return GetArrayLength(type); - case SpvOpTypeMatrix: - case SpvOpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: return GetNumElements(type); default: return 0; diff --git a/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h b/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h index 6a66dfb80..0bcd2a4e4 100644 --- a/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h +++ b/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h @@ -33,7 +33,7 @@ namespace opt { // Documented in optimizer.hpp class ScalarReplacementPass : public MemPass { private: - static const uint32_t kDefaultLimit = 100; + static constexpr uint32_t kDefaultLimit = 100; public: ScalarReplacementPass(uint32_t limit = kDefaultLimit) @@ -104,10 +104,10 @@ class ScalarReplacementPass : public MemPass { // Returns true if the uses of |inst| are acceptable for scalarization. // // Recursively checks all the uses of |inst|. For |inst| specifically, only - // allows SpvOpAccessChain, SpvOpInBoundsAccessChain, SpvOpLoad and - // SpvOpStore. Access chains must have the first index be a compile-time - // constant. Subsequent uses of access chains (including other access chains) - // are checked in a more relaxed manner. + // allows spv::Op::OpAccessChain, spv::Op::OpInBoundsAccessChain, + // spv::Op::OpLoad and spv::Op::OpStore. Access chains must have the first + // index be a compile-time constant. Subsequent uses of access chains + // (including other access chains) are checked in a more relaxed manner. bool CheckUses(const Instruction* inst) const; // Helper function for the above |CheckUses|. diff --git a/3rdparty/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp b/3rdparty/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp index 4def2b09a..5125bd153 100644 --- a/3rdparty/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp @@ -30,7 +30,6 @@ namespace spvtools { namespace opt { - namespace { using utils::EncodeNumberStatus; using utils::NumberType; @@ -139,9 +138,9 @@ std::vector ParseDefaultValueBitPattern( // decoration. bool CanHaveSpecIdDecoration(const Instruction& inst) { switch (inst.opcode()) { - case SpvOp::SpvOpSpecConstant: - case SpvOp::SpvOpSpecConstantFalse: - case SpvOp::SpvOpSpecConstantTrue: + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstantTrue: return true; default: return false; @@ -165,7 +164,7 @@ Instruction* GetSpecIdTargetFromDecorationGroup( if (def_use_mgr->WhileEachUser(&decoration_group_defining_inst, [&group_decorate_inst](Instruction* user) { if (user->opcode() == - SpvOp::SpvOpGroupDecorate) { + spv::Op::OpGroupDecorate) { group_decorate_inst = user; return false; } @@ -217,16 +216,16 @@ Instruction* GetSpecIdTargetFromDecorationGroup( Pass::Status SetSpecConstantDefaultValuePass::Process() { // The operand index of decoration target in an OpDecorate instruction. - const uint32_t kTargetIdOperandIndex = 0; + constexpr uint32_t kTargetIdOperandIndex = 0; // The operand index of the decoration literal in an OpDecorate instruction. - const uint32_t kDecorationOperandIndex = 1; + constexpr uint32_t kDecorationOperandIndex = 1; // The operand index of Spec id literal value in an OpDecorate SpecId // instruction. - const uint32_t kSpecIdLiteralOperandIndex = 2; + constexpr uint32_t kSpecIdLiteralOperandIndex = 2; // The number of operands in an OpDecorate SpecId instruction. - const uint32_t kOpDecorateSpecIdNumOperands = 3; + constexpr uint32_t kOpDecorateSpecIdNumOperands = 3; // The in-operand index of the default value in a OpSpecConstant instruction. - const uint32_t kOpSpecConstantLiteralInOperandIndex = 0; + constexpr uint32_t kOpSpecConstantLiteralInOperandIndex = 0; bool modified = false; // Scan through all the annotation instructions to find 'OpDecorate SpecId' @@ -240,10 +239,10 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { // default value of the target spec constant. for (Instruction& inst : context()->annotations()) { // Only process 'OpDecorate SpecId' instructions - if (inst.opcode() != SpvOp::SpvOpDecorate) continue; + if (inst.opcode() != spv::Op::OpDecorate) continue; if (inst.NumOperands() != kOpDecorateSpecIdNumOperands) continue; if (inst.GetSingleWordInOperand(kDecorationOperandIndex) != - uint32_t(SpvDecoration::SpvDecorationSpecId)) { + uint32_t(spv::Decoration::SpecId)) { continue; } @@ -255,7 +254,7 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { // target_id might be a decoration group id. Instruction* spec_inst = nullptr; if (Instruction* target_inst = get_def_use_mgr()->GetDef(target_id)) { - if (target_inst->opcode() == SpvOp::SpvOpDecorationGroup) { + if (target_inst->opcode() == spv::Op::OpDecorationGroup) { spec_inst = GetSpecIdTargetFromDecorationGroup(*target_inst, get_def_use_mgr()); } else { @@ -301,7 +300,7 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { // Update the operand bit patterns of the spec constant defining // instruction. switch (spec_inst->opcode()) { - case SpvOp::SpvOpSpecConstant: + case spv::Op::OpSpecConstant: // If the new value is the same with the original value, no // need to do anything. Otherwise update the operand words. if (spec_inst->GetInOperand(kOpSpecConstantLiteralInOperandIndex) @@ -311,19 +310,19 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { modified = true; } break; - case SpvOp::SpvOpSpecConstantTrue: + case spv::Op::OpSpecConstantTrue: // If the new value is also 'true', no need to change anything. // Otherwise, set the opcode to OpSpecConstantFalse; if (!static_cast(bit_pattern.front())) { - spec_inst->SetOpcode(SpvOp::SpvOpSpecConstantFalse); + spec_inst->SetOpcode(spv::Op::OpSpecConstantFalse); modified = true; } break; - case SpvOp::SpvOpSpecConstantFalse: + case spv::Op::OpSpecConstantFalse: // If the new value is also 'false', no need to change anything. // Otherwise, set the opcode to OpSpecConstantTrue; if (static_cast(bit_pattern.front())) { - spec_inst->SetOpcode(SpvOp::SpvOpSpecConstantTrue); + spec_inst->SetOpcode(spv::Op::OpSpecConstantTrue); modified = true; } break; diff --git a/3rdparty/spirv-tools/source/opt/simplification_pass.cpp b/3rdparty/spirv-tools/source/opt/simplification_pass.cpp index 43ec15f80..dbda39728 100644 --- a/3rdparty/spirv-tools/source/opt/simplification_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/simplification_pass.cpp @@ -69,12 +69,12 @@ bool SimplificationPass::SimplifyFunction(Function* function) { &folder, &inst_seen, this](BasicBlock* bb) { for (Instruction* inst = &*bb->begin(); inst; inst = inst->NextNode()) { inst_seen.insert(inst); - if (inst->opcode() == SpvOpPhi) { + if (inst->opcode() == spv::Op::OpPhi) { process_phis.insert(inst); } bool is_foldable_copy = - inst->opcode() == SpvOpCopyObject && + inst->opcode() == spv::Op::OpCopyObject && context()->get_decoration_mgr()->HaveSubsetOfDecorations( inst->result_id(), inst->GetSingleWordInOperand(0)); @@ -91,7 +91,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { AddNewOperands(inst, &inst_seen, &work_list); - if (inst->opcode() == SpvOpCopyObject) { + if (inst->opcode() == spv::Op::OpCopyObject) { context()->ReplaceAllUsesWithPredicate( inst->result_id(), inst->GetSingleWordInOperand(0), [](Instruction* user) { @@ -104,7 +104,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { }); inst_to_kill.insert(inst); in_work_list.insert(inst); - } else if (inst->opcode() == SpvOpNop) { + } else if (inst->opcode() == spv::Op::OpNop) { inst_to_kill.insert(inst); in_work_list.insert(inst); } @@ -121,7 +121,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { inst_seen.insert(inst); bool is_foldable_copy = - inst->opcode() == SpvOpCopyObject && + inst->opcode() == spv::Op::OpCopyObject && context()->get_decoration_mgr()->HaveSubsetOfDecorations( inst->result_id(), inst->GetSingleWordInOperand(0)); @@ -130,7 +130,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { context()->AnalyzeUses(inst); get_def_use_mgr()->ForEachUser( inst, [&work_list, &in_work_list](Instruction* use) { - if (!use->IsDecoration() && use->opcode() != SpvOpName && + if (!use->IsDecoration() && use->opcode() != spv::Op::OpName && in_work_list.insert(use).second) { work_list.push_back(use); } @@ -138,7 +138,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { AddNewOperands(inst, &inst_seen, &work_list); - if (inst->opcode() == SpvOpCopyObject) { + if (inst->opcode() == spv::Op::OpCopyObject) { context()->ReplaceAllUsesWithPredicate( inst->result_id(), inst->GetSingleWordInOperand(0), [](Instruction* user) { @@ -150,7 +150,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { }); inst_to_kill.insert(inst); in_work_list.insert(inst); - } else if (inst->opcode() == SpvOpNop) { + } else if (inst->opcode() == spv::Op::OpNop) { inst_to_kill.insert(inst); in_work_list.insert(inst); } diff --git a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp index b61fd0f4c..3037274d3 100644 --- a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp +++ b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp @@ -21,32 +21,32 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kOpDecorateInOperandBuiltinDecoration = 2u; -const uint32_t kOpLoadInOperandMemoryOperands = 1u; -const uint32_t kOpEntryPointInOperandEntryPoint = 1u; -const uint32_t kOpEntryPointInOperandInterface = 3u; +constexpr uint32_t kOpDecorateInOperandBuiltinDecoration = 2u; +constexpr uint32_t kOpLoadInOperandMemoryOperands = 1u; +constexpr uint32_t kOpEntryPointInOperandEntryPoint = 1u; +constexpr uint32_t kOpEntryPointInOperandInterface = 3u; bool HasBuiltinDecoration(analysis::DecorationManager* decoration_manager, uint32_t var_id, uint32_t built_in) { return decoration_manager->FindDecoration( - var_id, SpvDecorationBuiltIn, [built_in](const Instruction& inst) { + var_id, uint32_t(spv::Decoration::BuiltIn), + [built_in](const Instruction& inst) { return built_in == inst.GetSingleWordInOperand( kOpDecorateInOperandBuiltinDecoration); }); } -bool IsBuiltInForRayTracingVolatileSemantics(uint32_t built_in) { +bool IsBuiltInForRayTracingVolatileSemantics(spv::BuiltIn built_in) { switch (built_in) { - case SpvBuiltInSMIDNV: - case SpvBuiltInWarpIDNV: - case SpvBuiltInSubgroupSize: - case SpvBuiltInSubgroupLocalInvocationId: - case SpvBuiltInSubgroupEqMask: - case SpvBuiltInSubgroupGeMask: - case SpvBuiltInSubgroupGtMask: - case SpvBuiltInSubgroupLeMask: - case SpvBuiltInSubgroupLtMask: + case spv::BuiltIn::SMIDNV: + case spv::BuiltIn::WarpIDNV: + case spv::BuiltIn::SubgroupSize: + case spv::BuiltIn::SubgroupLocalInvocationId: + case spv::BuiltIn::SubgroupEqMask: + case spv::BuiltIn::SubgroupGeMask: + case spv::BuiltIn::SubgroupGtMask: + case spv::BuiltIn::SubgroupLeMask: + case spv::BuiltIn::SubgroupLtMask: return true; default: return false; @@ -56,16 +56,17 @@ bool IsBuiltInForRayTracingVolatileSemantics(uint32_t built_in) { bool HasBuiltinForRayTracingVolatileSemantics( analysis::DecorationManager* decoration_manager, uint32_t var_id) { return decoration_manager->FindDecoration( - var_id, SpvDecorationBuiltIn, [](const Instruction& inst) { - uint32_t built_in = - inst.GetSingleWordInOperand(kOpDecorateInOperandBuiltinDecoration); + var_id, uint32_t(spv::Decoration::BuiltIn), [](const Instruction& inst) { + spv::BuiltIn built_in = spv::BuiltIn( + inst.GetSingleWordInOperand(kOpDecorateInOperandBuiltinDecoration)); return IsBuiltInForRayTracingVolatileSemantics(built_in); }); } bool HasVolatileDecoration(analysis::DecorationManager* decoration_manager, uint32_t var_id) { - return decoration_manager->HasDecoration(var_id, SpvDecorationVolatile); + return decoration_manager->HasDecoration(var_id, + uint32_t(spv::Decoration::Volatile)); } } // namespace @@ -76,7 +77,7 @@ Pass::Status SpreadVolatileSemantics::Process() { } const bool is_vk_memory_model_enabled = context()->get_feature_mgr()->HasCapability( - SpvCapabilityVulkanMemoryModel); + spv::Capability::VulkanMemoryModel); CollectTargetsForVolatileSemantics(is_vk_memory_model_enabled); // If VulkanMemoryModel capability is not enabled, we have to set Volatile @@ -128,15 +129,16 @@ bool SpreadVolatileSemantics::IsTargetUsedByNonVolatileLoadInEntryPoint( } uint32_t memory_operands = load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); - return (memory_operands & SpvMemoryAccessVolatileMask) != 0; + return (memory_operands & uint32_t(spv::MemoryAccessMask::Volatile)) != + 0; }, funcs); } bool SpreadVolatileSemantics::HasInterfaceInConflictOfVolatileSemantics() { for (Instruction& entry_point : get_module()->entry_points()) { - SpvExecutionModel execution_model = - static_cast(entry_point.GetSingleWordInOperand(0)); + spv::ExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); for (uint32_t operand_index = kOpEntryPointInOperandInterface; operand_index < entry_point.NumInOperands(); ++operand_index) { uint32_t var_id = entry_point.GetSingleWordInOperand(operand_index); @@ -170,8 +172,8 @@ void SpreadVolatileSemantics::MarkVolatileSemanticsForVariable( void SpreadVolatileSemantics::CollectTargetsForVolatileSemantics( const bool is_vk_memory_model_enabled) { for (Instruction& entry_point : get_module()->entry_points()) { - SpvExecutionModel execution_model = - static_cast(entry_point.GetSingleWordInOperand(0)); + spv::ExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); for (uint32_t operand_index = kOpEntryPointInOperandInterface; operand_index < entry_point.NumInOperands(); ++operand_index) { uint32_t var_id = entry_point.GetSingleWordInOperand(operand_index); @@ -194,9 +196,10 @@ void SpreadVolatileSemantics::DecorateVarWithVolatile(Instruction* var) { return; } get_decoration_mgr()->AddDecoration( - SpvOpDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {SpvDecorationVolatile}}}); + spv::Op::OpDecorate, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::Decoration::Volatile)}}}); } bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( @@ -217,17 +220,17 @@ bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( return true; } - if (user->opcode() == SpvOpAccessChain || - user->opcode() == SpvOpInBoundsAccessChain || - user->opcode() == SpvOpPtrAccessChain || - user->opcode() == SpvOpInBoundsPtrAccessChain || - user->opcode() == SpvOpCopyObject) { + if (user->opcode() == spv::Op::OpAccessChain || + user->opcode() == spv::Op::OpInBoundsAccessChain || + user->opcode() == spv::Op::OpPtrAccessChain || + user->opcode() == spv::Op::OpInBoundsPtrAccessChain || + user->opcode() == spv::Op::OpCopyObject) { if (ptr_id == user->GetSingleWordInOperand(0)) worklist.push_back(user->result_id()); return true; } - if (user->opcode() != SpvOpLoad) { + if (user->opcode() != spv::Op::OpLoad) { return true; } @@ -250,12 +253,12 @@ void SpreadVolatileSemantics::SetVolatileForLoadsInEntries( [](Instruction* load) { if (load->NumInOperands() <= kOpLoadInOperandMemoryOperands) { load->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, - {SpvMemoryAccessVolatileMask}}); + {uint32_t(spv::MemoryAccessMask::Volatile)}}); return true; } uint32_t memory_operands = load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); - memory_operands |= SpvMemoryAccessVolatileMask; + memory_operands |= uint32_t(spv::MemoryAccessMask::Volatile); load->SetInOperand(kOpLoadInOperandMemoryOperands, {memory_operands}); return true; }, @@ -264,29 +267,29 @@ void SpreadVolatileSemantics::SetVolatileForLoadsInEntries( } bool SpreadVolatileSemantics::IsTargetForVolatileSemantics( - uint32_t var_id, SpvExecutionModel execution_model) { + uint32_t var_id, spv::ExecutionModel execution_model) { analysis::DecorationManager* decoration_manager = context()->get_decoration_mgr(); - if (execution_model == SpvExecutionModelFragment) { + if (execution_model == spv::ExecutionModel::Fragment) { return get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 6) && HasBuiltinDecoration(decoration_manager, var_id, - SpvBuiltInHelperInvocation); + uint32_t(spv::BuiltIn::HelperInvocation)); } - if (execution_model == SpvExecutionModelIntersectionKHR || - execution_model == SpvExecutionModelIntersectionNV) { + if (execution_model == spv::ExecutionModel::IntersectionKHR || + execution_model == spv::ExecutionModel::IntersectionNV) { if (HasBuiltinDecoration(decoration_manager, var_id, - SpvBuiltInRayTmaxKHR)) { + uint32_t(spv::BuiltIn::RayTmaxKHR))) { return true; } } switch (execution_model) { - case SpvExecutionModelRayGenerationKHR: - case SpvExecutionModelClosestHitKHR: - case SpvExecutionModelMissKHR: - case SpvExecutionModelCallableKHR: - case SpvExecutionModelIntersectionKHR: + case spv::ExecutionModel::RayGenerationKHR: + case spv::ExecutionModel::ClosestHitKHR: + case spv::ExecutionModel::MissKHR: + case spv::ExecutionModel::CallableKHR: + case spv::ExecutionModel::IntersectionKHR: return HasBuiltinForRayTracingVolatileSemantics(decoration_manager, var_id); default: diff --git a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h index 014858d3f..4cbb526fe 100644 --- a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h +++ b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h @@ -39,7 +39,8 @@ class SpreadVolatileSemantics : public Pass { // have an execution model. bool HasNoExecutionModel() { return get_module()->entry_points().empty() && - context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage); + context()->get_feature_mgr()->HasCapability( + spv::Capability::Linkage); } // Iterates interface variables and spreads the Volatile semantics if it has @@ -52,7 +53,7 @@ class SpreadVolatileSemantics : public Pass { // VUID-StandaloneSpirv-VulkanMemoryModel-04678 or // VUID-StandaloneSpirv-VulkanMemoryModel-04679. bool IsTargetForVolatileSemantics(uint32_t var_id, - SpvExecutionModel execution_model); + spv::ExecutionModel execution_model); // Collects interface variables that need the volatile semantics. // |is_vk_memory_model_enabled| is true if VulkanMemoryModel capability is diff --git a/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp b/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp index 22d811044..b8e22908d 100644 --- a/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp @@ -63,10 +63,9 @@ namespace spvtools { namespace opt { - namespace { -const uint32_t kStoreValIdInIdx = 1; -const uint32_t kVariableInitIdInIdx = 1; +constexpr uint32_t kStoreValIdInIdx = 1; +constexpr uint32_t kVariableInitIdInIdx = 1; } // namespace std::string SSARewriter::PhiCandidate::PrettyPrint(const CFG* cfg) const { @@ -300,12 +299,12 @@ void SSARewriter::SealBlock(BasicBlock* bb) { void SSARewriter::ProcessStore(Instruction* inst, BasicBlock* bb) { auto opcode = inst->opcode(); - assert((opcode == SpvOpStore || opcode == SpvOpVariable) && + assert((opcode == spv::Op::OpStore || opcode == spv::Op::OpVariable) && "Expecting a store or a variable definition instruction."); uint32_t var_id = 0; uint32_t val_id = 0; - if (opcode == SpvOpStore) { + if (opcode == spv::Op::OpStore) { (void)pass_->GetPtr(inst, &var_id); val_id = inst->GetSingleWordInOperand(kStoreValIdInIdx); } else if (inst->NumInOperands() >= 2) { @@ -443,9 +442,9 @@ bool SSARewriter::GenerateSSAReplacements(BasicBlock* bb) { for (auto& inst : *bb) { auto opcode = inst.opcode(); - if (opcode == SpvOpStore || opcode == SpvOpVariable) { + if (opcode == spv::Op::OpStore || opcode == spv::Op::OpVariable) { ProcessStore(&inst, bb); - } else if (inst.opcode() == SpvOpLoad) { + } else if (inst.opcode() == spv::Op::OpLoad) { if (!ProcessLoad(&inst, bb)) { return false; } @@ -545,7 +544,7 @@ bool SSARewriter::ApplyReplacements() { // Generate a new OpPhi instruction and insert it in its basic // block. std::unique_ptr phi_inst( - new Instruction(pass_->context(), SpvOpPhi, type_id, + new Instruction(pass_->context(), spv::Op::OpPhi, type_id, phi_candidate->result_id(), phi_operands)); generated_phis.push_back(phi_inst.get()); pass_->get_def_use_mgr()->AnalyzeInstDef(&*phi_inst); @@ -554,7 +553,7 @@ bool SSARewriter::ApplyReplacements() { insert_it = insert_it.InsertBefore(std::move(phi_inst)); pass_->context()->get_decoration_mgr()->CloneDecorations( phi_candidate->var_id(), phi_candidate->result_id(), - {SpvDecorationRelaxedPrecision}); + {spv::Decoration::RelaxedPrecision}); // Add DebugValue for the new OpPhi instruction. insert_it->SetDebugScope(local_var->GetDebugScope()); diff --git a/3rdparty/spirv-tools/source/opt/strength_reduction_pass.cpp b/3rdparty/spirv-tools/source/opt/strength_reduction_pass.cpp index ab7c4eb8d..f2e849871 100644 --- a/3rdparty/spirv-tools/source/opt/strength_reduction_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/strength_reduction_pass.cpp @@ -28,6 +28,8 @@ #include "source/opt/log.h" #include "source/opt/reflect.h" +namespace spvtools { +namespace opt { namespace { // Count the number of trailing zeros in the binary representation of // |constVal|. @@ -53,9 +55,6 @@ bool IsPowerOf2(uint32_t val) { } // namespace -namespace spvtools { -namespace opt { - Pass::Status StrengthReductionPass::Process() { // Initialize the member variables on a per module basis. bool modified = false; @@ -70,7 +69,7 @@ Pass::Status StrengthReductionPass::Process() { bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( BasicBlock::iterator* inst) { - assert((*inst)->opcode() == SpvOp::SpvOpIMul && + assert((*inst)->opcode() == spv::Op::OpIMul && "Only works for multiplication of integers."); bool modified = false; @@ -84,7 +83,7 @@ bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( for (int i = 0; i < 2; i++) { uint32_t opId = (*inst)->GetSingleWordInOperand(i); Instruction* opInst = get_def_use_mgr()->GetDef(opId); - if (opInst->opcode() == SpvOp::SpvOpConstant) { + if (opInst->opcode() == spv::Op::OpConstant) { // We found a constant operand. uint32_t constVal = opInst->GetSingleWordOperand(2); @@ -101,7 +100,7 @@ bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( {shiftConstResultId}); newOperands.push_back(shiftOperand); std::unique_ptr newInstruction( - new Instruction(context(), SpvOp::SpvOpShiftLeftLogical, + new Instruction(context(), spv::Op::OpShiftLeftLogical, (*inst)->type_id(), newResultId, newOperands)); // Insert the new instruction and update the data structures. @@ -133,7 +132,7 @@ void StrengthReductionPass::FindIntTypesAndConstants() { for (auto iter = get_module()->types_values_begin(); iter != get_module()->types_values_end(); ++iter) { switch (iter->opcode()) { - case SpvOp::SpvOpConstant: + case spv::Op::OpConstant: if (iter->type_id() == uint32_type_id_) { uint32_t value = iter->GetSingleWordOperand(2); if (value <= 32) constant_ids_[value] = iter->result_id(); @@ -159,9 +158,8 @@ uint32_t StrengthReductionPass::GetConstantId(uint32_t val) { uint32_t resultId = TakeNextId(); Operand constant(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {val}); - std::unique_ptr newConstant( - new Instruction(context(), SpvOp::SpvOpConstant, uint32_type_id_, - resultId, {constant})); + std::unique_ptr newConstant(new Instruction( + context(), spv::Op::OpConstant, uint32_type_id_, resultId, {constant})); get_module()->AddGlobalValue(std::move(newConstant)); // Notify the DefUseManager about this constant. @@ -184,7 +182,7 @@ bool StrengthReductionPass::ScanFunctions() { for (auto& bb : func) { for (auto inst = bb.begin(); inst != bb.end(); ++inst) { switch (inst->opcode()) { - case SpvOp::SpvOpIMul: + case spv::Op::OpIMul: if (ReplaceMultiplyByPowerOf2(&inst)) modified = true; break; default: diff --git a/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp b/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp index 6a0ebf248..f81bced52 100644 --- a/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp @@ -37,13 +37,13 @@ Pass::Status StripDebugInfoPass::Process() { if (uses_non_semantic_info) { for (auto& inst : context()->module()->debugs1()) { switch (inst.opcode()) { - case SpvOpString: { + case spv::Op::OpString: { analysis::DefUseManager* def_use = context()->get_def_use_mgr(); // see if this string is used anywhere by a non-semantic instruction bool no_nonsemantic_use = def_use->WhileEachUser(&inst, [def_use](Instruction* use) { - if (use->opcode() == SpvOpExtInst) { + if (use->opcode() == spv::Op::OpExtInst) { auto ext_inst_set = def_use->GetDef(use->GetSingleWordInOperand(0u)); const std::string extension_name = @@ -83,7 +83,8 @@ Pass::Status StripDebugInfoPass::Process() { // when that instruction is killed, which will lead to a double kill. std::sort(to_kill.begin(), to_kill.end(), [](Instruction* lhs, Instruction* rhs) -> bool { - if (lhs->opcode() == SpvOpName && rhs->opcode() != SpvOpName) + if (lhs->opcode() == spv::Op::OpName && + rhs->opcode() != spv::Op::OpName) return true; return false; }); diff --git a/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp b/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp index cd1fbb632..889969007 100644 --- a/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp @@ -32,27 +32,31 @@ Pass::Status StripNonSemanticInfoPass::Process() { bool other_uses_for_decorate_string = false; for (auto& inst : context()->module()->annotations()) { switch (inst.opcode()) { - case SpvOpDecorateStringGOOGLE: - if (inst.GetSingleWordInOperand(1) == SpvDecorationHlslSemanticGOOGLE || - inst.GetSingleWordInOperand(1) == SpvDecorationUserTypeGOOGLE) { + case spv::Op::OpDecorateStringGOOGLE: + if (spv::Decoration(inst.GetSingleWordInOperand(1)) == + spv::Decoration::HlslSemanticGOOGLE || + spv::Decoration(inst.GetSingleWordInOperand(1)) == + spv::Decoration::UserTypeGOOGLE) { to_remove.push_back(&inst); } else { other_uses_for_decorate_string = true; } break; - case SpvOpMemberDecorateStringGOOGLE: - if (inst.GetSingleWordInOperand(2) == SpvDecorationHlslSemanticGOOGLE || - inst.GetSingleWordInOperand(2) == SpvDecorationUserTypeGOOGLE) { + case spv::Op::OpMemberDecorateStringGOOGLE: + if (spv::Decoration(inst.GetSingleWordInOperand(2)) == + spv::Decoration::HlslSemanticGOOGLE || + spv::Decoration(inst.GetSingleWordInOperand(2)) == + spv::Decoration::UserTypeGOOGLE) { to_remove.push_back(&inst); } else { other_uses_for_decorate_string = true; } break; - case SpvOpDecorateId: - if (inst.GetSingleWordInOperand(1) == - SpvDecorationHlslCounterBufferGOOGLE) { + case spv::Op::OpDecorateId: + if (spv::Decoration(inst.GetSingleWordInOperand(1)) == + spv::Decoration::HlslCounterBufferGOOGLE) { to_remove.push_back(&inst); } break; @@ -79,7 +83,7 @@ Pass::Status StripNonSemanticInfoPass::Process() { // remove any extended inst imports that are non semantic std::unordered_set non_semantic_sets; for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == SpvOpExtInstImport && + assert(inst.opcode() == spv::Op::OpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.")) { @@ -93,7 +97,7 @@ Pass::Status StripNonSemanticInfoPass::Process() { if (!non_semantic_sets.empty()) { context()->module()->ForEachInst( [&non_semantic_sets, &to_remove](Instruction* inst) { - if (inst->opcode() == SpvOpExtInst) { + if (inst->opcode() == spv::Op::OpExtInst) { if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) != non_semantic_sets.end()) { to_remove.push_back(inst); diff --git a/3rdparty/spirv-tools/source/opt/struct_cfg_analysis.cpp b/3rdparty/spirv-tools/source/opt/struct_cfg_analysis.cpp index 203db87db..290b4bf45 100644 --- a/3rdparty/spirv-tools/source/opt/struct_cfg_analysis.cpp +++ b/3rdparty/spirv-tools/source/opt/struct_cfg_analysis.cpp @@ -16,18 +16,17 @@ #include "source/opt/ir_context.h" -namespace { -const uint32_t kMergeNodeIndex = 0; -const uint32_t kContinueNodeIndex = 1; -} // namespace - namespace spvtools { namespace opt { +namespace { +constexpr uint32_t kMergeNodeIndex = 0; +constexpr uint32_t kContinueNodeIndex = 1; +} // namespace StructuredCFGAnalysis::StructuredCFGAnalysis(IRContext* ctx) : context_(ctx) { // If this is not a shader, there are no merge instructions, and not // structured CFG to analyze. - if (!context_->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { + if (!context_->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { return; } @@ -82,7 +81,7 @@ void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) { merge_inst->GetSingleWordInOperand(kMergeNodeIndex); new_state.cinfo.containing_construct = block->id(); - if (merge_inst->opcode() == SpvOpLoopMerge) { + if (merge_inst->opcode() == spv::Op::OpLoopMerge) { new_state.cinfo.containing_loop = block->id(); new_state.cinfo.containing_switch = 0; new_state.continue_node = @@ -98,7 +97,7 @@ void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) { new_state.cinfo.in_continue = state.back().cinfo.in_continue; new_state.continue_node = state.back().continue_node; - if (merge_inst->NextNode()->opcode() == SpvOpSwitch) { + if (merge_inst->NextNode()->opcode() == spv::Op::OpSwitch) { new_state.cinfo.containing_switch = block->id(); } else { new_state.cinfo.containing_switch = @@ -226,7 +225,7 @@ StructuredCFGAnalysis::FindFuncsCalledFromContinue() { for (auto& bb : func) { if (IsInContainingLoopsContinueConstruct(bb.id())) { for (const Instruction& inst : bb) { - if (inst.opcode() == SpvOpFunctionCall) { + if (inst.opcode() == spv::Op::OpFunctionCall) { funcs_to_process.push(inst.GetSingleWordInOperand(0)); } } diff --git a/3rdparty/spirv-tools/source/opt/type_manager.cpp b/3rdparty/spirv-tools/source/opt/type_manager.cpp index a0006f558..6e4c054ef 100644 --- a/3rdparty/spirv-tools/source/opt/type_manager.cpp +++ b/3rdparty/spirv-tools/source/opt/type_manager.cpp @@ -29,10 +29,8 @@ namespace spvtools { namespace opt { namespace analysis { namespace { - -const int kSpvTypePointerStorageClass = 1; -const int kSpvTypePointerTypeIdInIdx = 2; - +constexpr int kSpvTypePointerStorageClass = 1; +constexpr int kSpvTypePointerTypeIdInIdx = 2; } // namespace TypeManager::TypeManager(const MessageConsumer& consumer, IRContext* c) @@ -49,7 +47,7 @@ Type* TypeManager::GetType(uint32_t id) const { } std::pair> TypeManager::GetTypeAndPointerType( - uint32_t id, SpvStorageClass sc) const { + uint32_t id, spv::StorageClass sc) const { Type* type = GetType(id); if (type) { return std::make_pair(type, MakeUnique(type, sc)); @@ -220,10 +218,10 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { RegisterType(id, *type); switch (type->kind()) { -#define DefineParameterlessCase(kind) \ - case Type::k##kind: \ - typeInst = MakeUnique(context(), SpvOpType##kind, 0, id, \ - std::initializer_list{}); \ +#define DefineParameterlessCase(kind) \ + case Type::k##kind: \ + typeInst = MakeUnique(context(), spv::Op::OpType##kind, 0, \ + id, std::initializer_list{}); \ break DefineParameterlessCase(Void); DefineParameterlessCase(Bool); @@ -236,10 +234,11 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { DefineParameterlessCase(NamedBarrier); DefineParameterlessCase(AccelerationStructureNV); DefineParameterlessCase(RayQueryKHR); + DefineParameterlessCase(HitObjectNV); #undef DefineParameterlessCase case Type::kInteger: typeInst = MakeUnique( - context(), SpvOpTypeInt, 0, id, + context(), spv::Op::OpTypeInt, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsInteger()->width()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -247,7 +246,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { break; case Type::kFloat: typeInst = MakeUnique( - context(), SpvOpTypeFloat, 0, id, + context(), spv::Op::OpTypeFloat, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsFloat()->width()}}}); break; @@ -257,7 +256,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = - MakeUnique(context(), SpvOpTypeVector, 0, id, + MakeUnique(context(), spv::Op::OpTypeVector, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -270,7 +269,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = - MakeUnique(context(), SpvOpTypeMatrix, 0, id, + MakeUnique(context(), spv::Op::OpTypeMatrix, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -284,7 +283,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), SpvOpTypeImage, 0, id, + context(), spv::Op::OpTypeImage, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_DIMENSIONALITY, @@ -308,7 +307,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), SpvOpTypeSampledImage, 0, id, + context(), spv::Op::OpTypeSampledImage, 0, id, std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); break; } @@ -318,7 +317,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), SpvOpTypeArray, 0, id, + context(), spv::Op::OpTypeArray, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_ID, {type->AsArray()->LengthId()}}}); @@ -331,7 +330,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), SpvOpTypeRuntimeArray, 0, id, + context(), spv::Op::OpTypeRuntimeArray, 0, id, std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); break; } @@ -346,7 +345,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {member_type_id})); } typeInst = - MakeUnique(context(), SpvOpTypeStruct, 0, id, ops); + MakeUnique(context(), spv::Op::OpTypeStruct, 0, id, ops); break; } case Type::kOpaque: { @@ -354,7 +353,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { // Convert to null-terminated packed UTF-8 string. std::vector words = spvtools::utils::MakeVector(opaque->name()); typeInst = MakeUnique( - context(), SpvOpTypeOpaque, 0, id, + context(), spv::Op::OpTypeOpaque, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_STRING, words}}); break; @@ -366,7 +365,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), SpvOpTypePointer, 0, id, + context(), spv::Op::OpTypePointer, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(pointer->storage_class())}}, @@ -388,20 +387,20 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { } ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {paramater_type_id})); } - typeInst = - MakeUnique(context(), SpvOpTypeFunction, 0, id, ops); + typeInst = MakeUnique(context(), spv::Op::OpTypeFunction, 0, + id, ops); break; } case Type::kPipe: typeInst = MakeUnique( - context(), SpvOpTypePipe, 0, id, + context(), spv::Op::OpTypePipe, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ACCESS_QUALIFIER, {static_cast(type->AsPipe()->access_qualifier())}}}); break; case Type::kForwardPointer: typeInst = MakeUnique( - context(), SpvOpTypeForwardPointer, 0, 0, + context(), spv::Op::OpTypeForwardPointer, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {type->AsForwardPointer()->target_id()}}, {SPV_OPERAND_TYPE_STORAGE_CLASS, @@ -416,7 +415,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), SpvOpTypeCooperativeMatrixNV, 0, id, + context(), spv::Op::OpTypeCooperativeMatrixNV, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {component_type}}, {SPV_OPERAND_TYPE_SCOPE_ID, {coop_mat->scope_id()}}, @@ -435,7 +434,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { } uint32_t TypeManager::FindPointerToType(uint32_t type_id, - SpvStorageClass storage_class) { + spv::StorageClass storage_class) { Type* pointeeTy = GetType(type_id); Pointer pointerTy(pointeeTy, storage_class); if (pointeeTy->IsUniqueType(true)) { @@ -447,11 +446,11 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id, Module::inst_iterator type_itr = context()->module()->types_values_begin(); for (; type_itr != context()->module()->types_values_end(); ++type_itr) { const Instruction* type_inst = &*type_itr; - if (type_inst->opcode() == SpvOpTypePointer && + if (type_inst->opcode() == spv::Op::OpTypePointer && type_inst->GetSingleWordOperand(kSpvTypePointerTypeIdInIdx) == type_id && - type_inst->GetSingleWordOperand(kSpvTypePointerStorageClass) == - storage_class) + spv::StorageClass(type_inst->GetSingleWordOperand( + kSpvTypePointerStorageClass)) == storage_class) return type_inst->result_id(); } @@ -459,7 +458,7 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id, // TODO(1841): Handle id overflow. uint32_t resultId = context()->TakeNextId(); std::unique_ptr type_inst( - new Instruction(context(), SpvOpTypePointer, 0, resultId, + new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, {uint32_t(storage_class)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_id}}})); @@ -476,7 +475,7 @@ void TypeManager::AttachDecorations(uint32_t id, const Type* type) { for (auto pair : structTy->element_decorations()) { uint32_t element = pair.first; for (auto vec : pair.second) { - CreateDecoration(id, vec, element); + CreateDecoration(id, vec, /* is_member */ true, element); } } } @@ -484,10 +483,10 @@ void TypeManager::AttachDecorations(uint32_t id, const Type* type) { void TypeManager::CreateDecoration(uint32_t target, const std::vector& decoration, - uint32_t element) { + bool is_member, uint32_t element) { std::vector ops; ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {target})); - if (element != 0) { + if (is_member) { ops.push_back(Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {element})); } ops.push_back(Operand(SPV_OPERAND_TYPE_DECORATION, {decoration[0]})); @@ -495,8 +494,8 @@ void TypeManager::CreateDecoration(uint32_t target, ops.push_back(Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration[i]})); } context()->AddAnnotationInst(MakeUnique( - context(), (element == 0 ? SpvOpDecorate : SpvOpMemberDecorate), 0, 0, - ops)); + context(), (is_member ? spv::Op::OpMemberDecorate : spv::Op::OpDecorate), + 0, 0, ops)); Instruction* inst = &*--context()->annotation_end(); context()->get_def_use_mgr()->AnalyzeInstUse(inst); } @@ -529,6 +528,7 @@ Type* TypeManager::RebuildType(const Type& type) { DefineNoSubtypeCase(NamedBarrier); DefineNoSubtypeCase(AccelerationStructureNV); DefineNoSubtypeCase(RayQueryKHR); + DefineNoSubtypeCase(HitObjectNV); #undef DefineNoSubtypeCase case Type::kVector: { const Vector* vec_ty = type.AsVector(); @@ -665,46 +665,47 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { Type* type = nullptr; switch (inst.opcode()) { - case SpvOpTypeVoid: + case spv::Op::OpTypeVoid: type = new Void(); break; - case SpvOpTypeBool: + case spv::Op::OpTypeBool: type = new Bool(); break; - case SpvOpTypeInt: + case spv::Op::OpTypeInt: type = new Integer(inst.GetSingleWordInOperand(0), inst.GetSingleWordInOperand(1)); break; - case SpvOpTypeFloat: + case spv::Op::OpTypeFloat: type = new Float(inst.GetSingleWordInOperand(0)); break; - case SpvOpTypeVector: + case spv::Op::OpTypeVector: type = new Vector(GetType(inst.GetSingleWordInOperand(0)), inst.GetSingleWordInOperand(1)); break; - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: type = new Matrix(GetType(inst.GetSingleWordInOperand(0)), inst.GetSingleWordInOperand(1)); break; - case SpvOpTypeImage: { - const SpvAccessQualifier access = - inst.NumInOperands() < 8 - ? SpvAccessQualifierReadOnly - : static_cast(inst.GetSingleWordInOperand(7)); + case spv::Op::OpTypeImage: { + const spv::AccessQualifier access = + inst.NumInOperands() < 8 ? spv::AccessQualifier::ReadOnly + : static_cast( + inst.GetSingleWordInOperand(7)); type = new Image( GetType(inst.GetSingleWordInOperand(0)), - static_cast(inst.GetSingleWordInOperand(1)), + static_cast(inst.GetSingleWordInOperand(1)), inst.GetSingleWordInOperand(2), inst.GetSingleWordInOperand(3) == 1, inst.GetSingleWordInOperand(4) == 1, inst.GetSingleWordInOperand(5), - static_cast(inst.GetSingleWordInOperand(6)), access); + static_cast(inst.GetSingleWordInOperand(6)), + access); } break; - case SpvOpTypeSampler: + case spv::Op::OpTypeSampler: type = new Sampler(); break; - case SpvOpTypeSampledImage: + case spv::Op::OpTypeSampledImage: type = new SampledImage(GetType(inst.GetSingleWordInOperand(0))); break; - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { const uint32_t length_id = inst.GetSingleWordInOperand(1); const Instruction* length_constant_inst = id_to_constant_inst_[length_id]; assert(length_constant_inst); @@ -717,11 +718,11 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { // Only OpSpecConstant has a SpecId. uint32_t spec_id = 0u; bool has_spec_id = false; - if (length_constant_inst->opcode() == SpvOpSpecConstant) { + if (length_constant_inst->opcode() == spv::Op::OpSpecConstant) { context()->get_decoration_mgr()->ForEachDecoration( - length_id, SpvDecorationSpecId, + length_id, uint32_t(spv::Decoration::SpecId), [&spec_id, &has_spec_id](const Instruction& decoration) { - assert(decoration.opcode() == SpvOpDecorate); + assert(decoration.opcode() == spv::Op::OpDecorate); spec_id = decoration.GetSingleWordOperand(2u); has_spec_id = true; }); @@ -730,7 +731,8 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { if (has_spec_id) { extra_words.push_back(spec_id); } - if ((opcode == SpvOpConstant) || (opcode == SpvOpSpecConstant)) { + if ((opcode == spv::Op::OpConstant) || + (opcode == spv::Op::OpSpecConstant)) { // Always include the literal constant words. In the spec constant // case, the constant might not be overridden, so it's still // significant. @@ -754,7 +756,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } } break; - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeRuntimeArray: type = new RuntimeArray(GetType(inst.GetSingleWordInOperand(0))); if (id_to_incomplete_type_.count(inst.GetSingleWordInOperand(0))) { incomplete_types_.emplace_back(inst.result_id(), type); @@ -762,7 +764,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { std::vector element_types; bool incomplete_type = false; for (uint32_t i = 0; i < inst.NumInOperands(); ++i) { @@ -780,14 +782,14 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } } break; - case SpvOpTypeOpaque: { + case spv::Op::OpTypeOpaque: { type = new Opaque(inst.GetInOperand(0).AsString()); } break; - case SpvOpTypePointer: { + case spv::Op::OpTypePointer: { uint32_t pointee_type_id = inst.GetSingleWordInOperand(1); type = new Pointer( GetType(pointee_type_id), - static_cast(inst.GetSingleWordInOperand(0))); + static_cast(inst.GetSingleWordInOperand(0))); if (id_to_incomplete_type_.count(pointee_type_id)) { incomplete_types_.emplace_back(inst.result_id(), type); @@ -797,7 +799,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { id_to_incomplete_type_.erase(inst.result_id()); } break; - case SpvOpTypeFunction: { + case spv::Op::OpTypeFunction: { bool incomplete_type = false; uint32_t return_type_id = inst.GetSingleWordInOperand(0); if (id_to_incomplete_type_.count(return_type_id)) { @@ -821,49 +823,52 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } } break; - case SpvOpTypeEvent: + case spv::Op::OpTypeEvent: type = new Event(); break; - case SpvOpTypeDeviceEvent: + case spv::Op::OpTypeDeviceEvent: type = new DeviceEvent(); break; - case SpvOpTypeReserveId: + case spv::Op::OpTypeReserveId: type = new ReserveId(); break; - case SpvOpTypeQueue: + case spv::Op::OpTypeQueue: type = new Queue(); break; - case SpvOpTypePipe: + case spv::Op::OpTypePipe: type = new Pipe( - static_cast(inst.GetSingleWordInOperand(0))); + static_cast(inst.GetSingleWordInOperand(0))); break; - case SpvOpTypeForwardPointer: { + case spv::Op::OpTypeForwardPointer: { // Handling of forward pointers is different from the other types. uint32_t target_id = inst.GetSingleWordInOperand(0); - type = new ForwardPointer(target_id, static_cast( + type = new ForwardPointer(target_id, static_cast( inst.GetSingleWordInOperand(1))); incomplete_types_.emplace_back(target_id, type); id_to_incomplete_type_[target_id] = type; return type; } - case SpvOpTypePipeStorage: + case spv::Op::OpTypePipeStorage: type = new PipeStorage(); break; - case SpvOpTypeNamedBarrier: + case spv::Op::OpTypeNamedBarrier: type = new NamedBarrier(); break; - case SpvOpTypeAccelerationStructureNV: + case spv::Op::OpTypeAccelerationStructureNV: type = new AccelerationStructureNV(); break; - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixNV: type = new CooperativeMatrixNV(GetType(inst.GetSingleWordInOperand(0)), inst.GetSingleWordInOperand(1), inst.GetSingleWordInOperand(2), inst.GetSingleWordInOperand(3)); break; - case SpvOpTypeRayQueryKHR: + case spv::Op::OpTypeRayQueryKHR: type = new RayQueryKHR(); break; + case spv::Op::OpTypeHitObjectNV: + type = new HitObjectNV(); + break; default: SPIRV_UNIMPLEMENTED(consumer_, "unhandled type"); break; @@ -886,11 +891,11 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { } void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { - const SpvOp opcode = inst.opcode(); + const spv::Op opcode = inst.opcode(); if (!IsAnnotationInst(opcode)) return; switch (opcode) { - case SpvOpDecorate: { + case spv::Op::OpDecorate: { const auto count = inst.NumOperands(); std::vector data; for (uint32_t i = 1; i < count; ++i) { @@ -898,7 +903,7 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { } type->AddDecoration(std::move(data)); } break; - case SpvOpMemberDecorate: { + case spv::Op::OpMemberDecorate: { const auto count = inst.NumOperands(); const uint32_t index = inst.GetSingleWordOperand(1); std::vector data; diff --git a/3rdparty/spirv-tools/source/opt/type_manager.h b/3rdparty/spirv-tools/source/opt/type_manager.h index 72e37f487..c49e19322 100644 --- a/3rdparty/spirv-tools/source/opt/type_manager.h +++ b/3rdparty/spirv-tools/source/opt/type_manager.h @@ -99,7 +99,7 @@ class TypeManager { // // |id| must be a registered type. std::pair> GetTypeAndPointerType( - uint32_t id, SpvStorageClass sc) const; + uint32_t id, spv::StorageClass sc) const; // Returns an id for a declaration representing |type|. Returns 0 if the type // does not exists, and could not be generated. @@ -112,7 +112,7 @@ class TypeManager { // Find pointer to type and storage in module, return its resultId. If it is // not found, a new type is created, and its id is returned. Returns 0 if the // type could not be created. - uint32_t FindPointerToType(uint32_t type_id, SpvStorageClass storage_class); + uint32_t FindPointerToType(uint32_t type_id, spv::StorageClass storage_class); // Registers |id| to |type|. // @@ -139,6 +139,11 @@ class TypeManager { const Type* GetMemberType(const Type* parent_type, const std::vector& access_chain); + // Attaches the decoration encoded in |inst| to |type|. Does nothing if the + // given instruction is not a decoration instruction. Assumes the target is + // |type| (e.g. should be called in loop of |type|'s decorations). + void AttachDecoration(const Instruction& inst, Type* type); + Type* GetUIntType() { Integer int_type(32, false); return GetRegisteredType(&int_type); @@ -243,19 +248,15 @@ class TypeManager { // Create the annotation instruction. // - // If |element| is zero, an OpDecorate is created, other an OpMemberDecorate - // is created. The annotation is registered with the DefUseManager and the - // DecorationManager. + // If |is_member| is false, an OpDecorate of |decoration| on |id| is created, + // otherwise an OpMemberDecorate is created at |element|. The annotation is + // registered with the DefUseManager and the DecorationManager. void CreateDecoration(uint32_t id, const std::vector& decoration, - uint32_t element = 0); + bool is_member = false, uint32_t element = 0); // Creates and returns a type from the given SPIR-V |inst|. Returns nullptr if // the given instruction is not for defining a type. Type* RecordIfTypeDefinition(const Instruction& inst); - // Attaches the decoration encoded in |inst| to |type|. Does nothing if the - // given instruction is not a decoration instruction. Assumes the target is - // |type| (e.g. should be called in loop of |type|'s decorations). - void AttachDecoration(const Instruction& inst, Type* type); // Returns an equivalent pointer to |type| built in terms of pointers owned by // |type_pool_|. For example, if |type| is a vec3 of bool, it will be rebuilt diff --git a/3rdparty/spirv-tools/source/opt/types.cpp b/3rdparty/spirv-tools/source/opt/types.cpp index 056acebb6..ab95906b6 100644 --- a/3rdparty/spirv-tools/source/opt/types.cpp +++ b/3rdparty/spirv-tools/source/opt/types.cpp @@ -24,7 +24,6 @@ #include "source/util/hash_combine.h" #include "source/util/make_unique.h" -#include "spirv/unified1/spirv.h" namespace spvtools { namespace opt { @@ -65,7 +64,7 @@ bool CompareTwoVectors(const U32VecVec a, const U32VecVec b) { return true; } -} // anonymous namespace +} // namespace std::string Type::GetDecorationStr() const { std::ostringstream oss; @@ -132,6 +131,7 @@ std::unique_ptr Type::Clone() const { DeclareKindCase(AccelerationStructureNV); DeclareKindCase(CooperativeMatrixNV); DeclareKindCase(RayQueryKHR); + DeclareKindCase(HitObjectNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -178,6 +178,7 @@ bool Type::operator==(const Type& other) const { DeclareKindCase(AccelerationStructureNV); DeclareKindCase(CooperativeMatrixNV); DeclareKindCase(RayQueryKHR); + DeclareKindCase(HitObjectNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -232,6 +233,7 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const { DeclareKindCase(AccelerationStructureNV); DeclareKindCase(CooperativeMatrixNV); DeclareKindCase(RayQueryKHR); + DeclareKindCase(HitObjectNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -357,8 +359,9 @@ size_t Matrix::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { return element_type_->ComputeHashValue(hash, seen); } -Image::Image(Type* type, SpvDim dimen, uint32_t d, bool array, bool multisample, - uint32_t sampling, SpvImageFormat f, SpvAccessQualifier qualifier) +Image::Image(Type* type, spv::Dim dimen, uint32_t d, bool array, + bool multisample, uint32_t sampling, spv::ImageFormat f, + spv::AccessQualifier qualifier) : Type(kImage), sampled_type_(type), dim_(dimen), @@ -383,9 +386,9 @@ bool Image::IsSameImpl(const Type* that, IsSameCache* seen) const { std::string Image::str() const { std::ostringstream oss; - oss << "image(" << sampled_type_->str() << ", " << dim_ << ", " << depth_ - << ", " << arrayed_ << ", " << ms_ << ", " << sampled_ << ", " << format_ - << ", " << access_qualifier_ << ")"; + oss << "image(" << sampled_type_->str() << ", " << uint32_t(dim_) << ", " + << depth_ << ", " << arrayed_ << ", " << ms_ << ", " << sampled_ << ", " + << uint32_t(format_) << ", " << uint32_t(access_qualifier_) << ")"; return oss.str(); } @@ -557,7 +560,7 @@ size_t Opaque::ComputeExtraStateHash(size_t hash, SeenTypes*) const { return hash_combine(hash, name_); } -Pointer::Pointer(const Type* type, SpvStorageClass sc) +Pointer::Pointer(const Type* type, spv::StorageClass sc) : Type(kPointer), pointee_type_(type), storage_class_(sc) {} bool Pointer::IsSameImpl(const Type* that, IsSameCache* seen) const { @@ -636,7 +639,7 @@ bool Pipe::IsSameImpl(const Type* that, IsSameCache*) const { std::string Pipe::str() const { std::ostringstream oss; - oss << "pipe(" << access_qualifier_ << ")"; + oss << "pipe(" << uint32_t(access_qualifier_) << ")"; return oss.str(); } diff --git a/3rdparty/spirv-tools/source/opt/types.h b/3rdparty/spirv-tools/source/opt/types.h index a92669e9f..1f329373b 100644 --- a/3rdparty/spirv-tools/source/opt/types.h +++ b/3rdparty/spirv-tools/source/opt/types.h @@ -61,6 +61,7 @@ class NamedBarrier; class AccelerationStructureNV; class CooperativeMatrixNV; class RayQueryKHR; +class HitObjectNV; // Abstract class for a SPIR-V type. It has a bunch of As() methods, // which is used as a way to probe the actual . @@ -100,6 +101,7 @@ class Type { kAccelerationStructureNV, kCooperativeMatrixNV, kRayQueryKHR, + kHitObjectNV, kLast }; @@ -196,6 +198,7 @@ class Type { DeclareCastMethod(AccelerationStructureNV) DeclareCastMethod(CooperativeMatrixNV) DeclareCastMethod(RayQueryKHR) + DeclareCastMethod(HitObjectNV) #undef DeclareCastMethod protected: @@ -302,9 +305,9 @@ class Matrix : public Type { class Image : public Type { public: - Image(Type* type, SpvDim dimen, uint32_t d, bool array, bool multisample, - uint32_t sampling, SpvImageFormat f, - SpvAccessQualifier qualifier = SpvAccessQualifierReadOnly); + Image(Type* type, spv::Dim dimen, uint32_t d, bool array, bool multisample, + uint32_t sampling, spv::ImageFormat f, + spv::AccessQualifier qualifier = spv::AccessQualifier::ReadOnly); Image(const Image&) = default; std::string str() const override; @@ -313,13 +316,13 @@ class Image : public Type { const Image* AsImage() const override { return this; } const Type* sampled_type() const { return sampled_type_; } - SpvDim dim() const { return dim_; } + spv::Dim dim() const { return dim_; } uint32_t depth() const { return depth_; } bool is_arrayed() const { return arrayed_; } bool is_multisampled() const { return ms_; } uint32_t sampled() const { return sampled_; } - SpvImageFormat format() const { return format_; } - SpvAccessQualifier access_qualifier() const { return access_qualifier_; } + spv::ImageFormat format() const { return format_; } + spv::AccessQualifier access_qualifier() const { return access_qualifier_; } size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; @@ -327,13 +330,13 @@ class Image : public Type { bool IsSameImpl(const Type* that, IsSameCache*) const override; Type* sampled_type_; - SpvDim dim_; + spv::Dim dim_; uint32_t depth_; bool arrayed_; bool ms_; uint32_t sampled_; - SpvImageFormat format_; - SpvAccessQualifier access_qualifier_; + spv::ImageFormat format_; + spv::AccessQualifier access_qualifier_; }; class SampledImage : public Type { @@ -491,12 +494,12 @@ class Opaque : public Type { class Pointer : public Type { public: - Pointer(const Type* pointee, SpvStorageClass sc); + Pointer(const Type* pointee, spv::StorageClass sc); Pointer(const Pointer&) = default; std::string str() const override; const Type* pointee_type() const { return pointee_type_; } - SpvStorageClass storage_class() const { return storage_class_; } + spv::StorageClass storage_class() const { return storage_class_; } Pointer* AsPointer() override { return this; } const Pointer* AsPointer() const override { return this; } @@ -509,7 +512,7 @@ class Pointer : public Type { bool IsSameImpl(const Type* that, IsSameCache*) const override; const Type* pointee_type_; - SpvStorageClass storage_class_; + spv::StorageClass storage_class_; }; class Function : public Type { @@ -540,7 +543,7 @@ class Function : public Type { class Pipe : public Type { public: - Pipe(SpvAccessQualifier qualifier) + Pipe(spv::AccessQualifier qualifier) : Type(kPipe), access_qualifier_(qualifier) {} Pipe(const Pipe&) = default; @@ -549,19 +552,19 @@ class Pipe : public Type { Pipe* AsPipe() override { return this; } const Pipe* AsPipe() const override { return this; } - SpvAccessQualifier access_qualifier() const { return access_qualifier_; } + spv::AccessQualifier access_qualifier() const { return access_qualifier_; } size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; private: bool IsSameImpl(const Type* that, IsSameCache*) const override; - SpvAccessQualifier access_qualifier_; + spv::AccessQualifier access_qualifier_; }; class ForwardPointer : public Type { public: - ForwardPointer(uint32_t id, SpvStorageClass sc) + ForwardPointer(uint32_t id, spv::StorageClass sc) : Type(kForwardPointer), target_id_(id), storage_class_(sc), @@ -570,7 +573,7 @@ class ForwardPointer : public Type { uint32_t target_id() const { return target_id_; } void SetTargetPointer(const Pointer* pointer) { pointer_ = pointer; } - SpvStorageClass storage_class() const { return storage_class_; } + spv::StorageClass storage_class() const { return storage_class_; } const Pointer* target_pointer() const { return pointer_; } std::string str() const override; @@ -584,7 +587,7 @@ class ForwardPointer : public Type { bool IsSameImpl(const Type* that, IsSameCache*) const override; uint32_t target_id_; - SpvStorageClass storage_class_; + spv::StorageClass storage_class_; const Pointer* pointer_; }; @@ -648,6 +651,7 @@ DefineParameterlessType(PipeStorage, pipe_storage); DefineParameterlessType(NamedBarrier, named_barrier); DefineParameterlessType(AccelerationStructureNV, accelerationStructureNV); DefineParameterlessType(RayQueryKHR, rayQueryKHR); +DefineParameterlessType(HitObjectNV, hitObjectNV); #undef DefineParameterlessType } // namespace analysis diff --git a/3rdparty/spirv-tools/source/opt/unify_const_pass.cpp b/3rdparty/spirv-tools/source/opt/unify_const_pass.cpp index 6bfa11a5b..f774aa6b6 100644 --- a/3rdparty/spirv-tools/source/opt/unify_const_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/unify_const_pass.cpp @@ -25,7 +25,6 @@ namespace spvtools { namespace opt { - namespace { // The trie that stores a bunch of result ids and, for a given instruction, @@ -103,7 +102,7 @@ class ResultIdTrie { std::unique_ptr root_; // The root node of the trie. }; -} // anonymous namespace +} // namespace Pass::Status UnifyConstantPass::Process() { bool modified = false; @@ -139,12 +138,12 @@ Pass::Status UnifyConstantPass::Process() { // processing is up to a descendant. This makes comparing the key array // always valid for judging duplication. switch (inst->opcode()) { - case SpvOp::SpvOpConstantTrue: - case SpvOp::SpvOpConstantFalse: - case SpvOp::SpvOpConstant: - case SpvOp::SpvOpConstantNull: - case SpvOp::SpvOpConstantSampler: - case SpvOp::SpvOpConstantComposite: + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpConstant: + case spv::Op::OpConstantNull: + case spv::Op::OpConstantSampler: + case spv::Op::OpConstantComposite: // Only spec constants defined with OpSpecConstantOp and // OpSpecConstantComposite should be processed in this pass. Spec // constants defined with OpSpecConstant{|True|False} are decorated with @@ -154,8 +153,8 @@ Pass::Status UnifyConstantPass::Process() { // unique. When all the operands/components are the same between two // OpSpecConstant{Op|Composite} results, their result values must be the // same so are unifiable. - case SpvOp::SpvOpSpecConstantOp: - case SpvOp::SpvOpSpecConstantComposite: { + case spv::Op::OpSpecConstantOp: + case spv::Op::OpSpecConstantComposite: { uint32_t id = defined_constants.LookupEquivalentResultFor(*inst); if (id != inst->result_id()) { // The constant is a duplicated one, use the cached constant to diff --git a/3rdparty/spirv-tools/source/opt/upgrade_memory_model.cpp b/3rdparty/spirv-tools/source/opt/upgrade_memory_model.cpp index 9d6a5bceb..1b439a6ef 100644 --- a/3rdparty/spirv-tools/source/opt/upgrade_memory_model.cpp +++ b/3rdparty/spirv-tools/source/opt/upgrade_memory_model.cpp @@ -28,14 +28,16 @@ namespace opt { Pass::Status UpgradeMemoryModel::Process() { // TODO: This pass needs changes to support cooperative matrices. if (context()->get_feature_mgr()->HasCapability( - SpvCapabilityCooperativeMatrixNV)) { + spv::Capability::CooperativeMatrixNV)) { return Pass::Status::SuccessWithoutChange; } // Only update Logical GLSL450 to Logical VulkanKHR. Instruction* memory_model = get_module()->GetMemoryModel(); - if (memory_model->GetSingleWordInOperand(0u) != SpvAddressingModelLogical || - memory_model->GetSingleWordInOperand(1u) != SpvMemoryModelGLSL450) { + if (memory_model->GetSingleWordInOperand(0u) != + uint32_t(spv::AddressingModel::Logical) || + memory_model->GetSingleWordInOperand(1u) != + uint32_t(spv::MemoryModel::GLSL450)) { return Pass::Status::SuccessWithoutChange; } @@ -55,16 +57,17 @@ void UpgradeMemoryModel::UpgradeMemoryModelInstruction() { // 3. Modify the memory model. Instruction* memory_model = get_module()->GetMemoryModel(); context()->AddCapability(MakeUnique( - context(), SpvOpCapability, 0, 0, + context(), spv::Op::OpCapability, 0, 0, std::initializer_list{ - {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityVulkanMemoryModelKHR}}})); + {SPV_OPERAND_TYPE_CAPABILITY, + {uint32_t(spv::Capability::VulkanMemoryModelKHR)}}})); const std::string extension = "SPV_KHR_vulkan_memory_model"; std::vector words = spvtools::utils::MakeVector(extension); context()->AddExtension( - MakeUnique(context(), SpvOpExtension, 0, 0, + MakeUnique(context(), spv::Op::OpExtension, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_STRING, words}})); - memory_model->SetInOperand(1u, {SpvMemoryModelVulkanKHR}); + memory_model->SetInOperand(1u, {uint32_t(spv::MemoryModel::VulkanKHR)}); } void UpgradeMemoryModel::UpgradeInstructions() { @@ -79,7 +82,7 @@ void UpgradeMemoryModel::UpgradeInstructions() { // In SPIR-V 1.4 or later, normalize OpCopyMemory* access operands. for (auto& func : *get_module()) { func.ForEachInst([this](Instruction* inst) { - if (inst->opcode() == SpvOpExtInst) { + if (inst->opcode() == spv::Op::OpExtInst) { auto ext_inst = inst->GetSingleWordInOperand(1u); if (ext_inst == GLSLstd450Modf || ext_inst == GLSLstd450Frexp) { auto import = @@ -89,9 +92,10 @@ void UpgradeMemoryModel::UpgradeInstructions() { } } } else if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { - if (inst->opcode() == SpvOpCopyMemory || - inst->opcode() == SpvOpCopyMemorySized) { - uint32_t start_operand = inst->opcode() == SpvOpCopyMemory ? 2u : 3u; + if (inst->opcode() == spv::Op::OpCopyMemory || + inst->opcode() == spv::Op::OpCopyMemorySized) { + uint32_t start_operand = + inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; if (inst->NumInOperands() > start_operand) { auto num_access_words = MemoryAccessNumWords( inst->GetSingleWordInOperand(start_operand)); @@ -105,10 +109,10 @@ void UpgradeMemoryModel::UpgradeInstructions() { } } else { // Add two memory access operands. - inst->AddOperand( - {SPV_OPERAND_TYPE_MEMORY_ACCESS, {SpvMemoryAccessMaskNone}}); - inst->AddOperand( - {SPV_OPERAND_TYPE_MEMORY_ACCESS, {SpvMemoryAccessMaskNone}}); + inst->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, + {uint32_t(spv::MemoryAccessMask::MaskNone)}}); + inst->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, + {uint32_t(spv::MemoryAccessMask::MaskNone)}}); } } } @@ -129,23 +133,23 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { bool dst_coherent = false; bool dst_volatile = false; uint32_t start_operand = 0u; - SpvScope scope = SpvScopeQueueFamilyKHR; - SpvScope src_scope = SpvScopeQueueFamilyKHR; - SpvScope dst_scope = SpvScopeQueueFamilyKHR; + spv::Scope scope = spv::Scope::QueueFamilyKHR; + spv::Scope src_scope = spv::Scope::QueueFamilyKHR; + spv::Scope dst_scope = spv::Scope::QueueFamilyKHR; switch (inst->opcode()) { - case SpvOpLoad: - case SpvOpStore: + case spv::Op::OpLoad: + case spv::Op::OpStore: std::tie(is_coherent, is_volatile, scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); break; - case SpvOpImageRead: - case SpvOpImageSparseRead: - case SpvOpImageWrite: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: + case spv::Op::OpImageWrite: std::tie(is_coherent, is_volatile, scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: std::tie(dst_coherent, dst_volatile, dst_scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); std::tie(src_coherent, src_volatile, src_scope) = @@ -156,17 +160,17 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { } switch (inst->opcode()) { - case SpvOpLoad: + case spv::Op::OpLoad: UpgradeFlags(inst, 1u, is_coherent, is_volatile, kVisibility, kMemory); break; - case SpvOpStore: + case spv::Op::OpStore: UpgradeFlags(inst, 2u, is_coherent, is_volatile, kAvailability, kMemory); break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: - start_operand = inst->opcode() == SpvOpCopyMemory ? 2u : 3u; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + start_operand = inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { // There are guaranteed to be two memory access operands at this // point so treat source and target separately. @@ -183,11 +187,11 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { kVisibility, kMemory); } break; - case SpvOpImageRead: - case SpvOpImageSparseRead: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: UpgradeFlags(inst, 2u, is_coherent, is_volatile, kVisibility, kImage); break; - case SpvOpImageWrite: + case spv::Op::OpImageWrite: UpgradeFlags(inst, 3u, is_coherent, is_volatile, kAvailability, kImage); break; @@ -205,7 +209,7 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { // There are two memory access operands. The first is for the target and // the second is for the source. if (dst_coherent || src_coherent) { - start_operand = inst->opcode() == SpvOpCopyMemory ? 2u : 3u; + start_operand = inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; std::vector new_operands; uint32_t num_access_words = MemoryAccessNumWords(inst->GetSingleWordInOperand(start_operand)); @@ -255,13 +259,13 @@ void UpgradeMemoryModel::UpgradeAtomics() { if (spvOpcodeIsAtomicOp(inst->opcode())) { bool unused_coherent = false; bool is_volatile = false; - SpvScope unused_scope = SpvScopeQueueFamilyKHR; + spv::Scope unused_scope = spv::Scope::QueueFamilyKHR; std::tie(unused_coherent, is_volatile, unused_scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0)); UpgradeSemantics(inst, 2u, is_volatile); - if (inst->opcode() == SpvOpAtomicCompareExchange || - inst->opcode() == SpvOpAtomicCompareExchangeWeak) { + if (inst->opcode() == spv::Op::OpAtomicCompareExchange || + inst->opcode() == spv::Op::OpAtomicCompareExchangeWeak) { UpgradeSemantics(inst, 3u, is_volatile); } } @@ -286,14 +290,14 @@ void UpgradeMemoryModel::UpgradeSemantics(Instruction* inst, value = constant->GetU32(); } - value |= SpvMemorySemanticsVolatileMask; + value |= uint32_t(spv::MemorySemanticsMask::Volatile); auto new_constant = context()->get_constant_mgr()->GetConstant(type, {value}); auto new_semantics = context()->get_constant_mgr()->GetDefiningInstruction(new_constant); inst->SetInOperand(in_operand, {new_semantics->result_id()}); } -std::tuple UpgradeMemoryModel::GetInstructionAttributes( +std::tuple UpgradeMemoryModel::GetInstructionAttributes( uint32_t id) { // |id| is a pointer used in a memory/image instruction. Need to determine if // that pointer points to volatile or coherent memory. Workgroup storage @@ -302,8 +306,8 @@ std::tuple UpgradeMemoryModel::GetInstructionAttributes( Instruction* inst = context()->get_def_use_mgr()->GetDef(id); analysis::Type* type = context()->get_type_mgr()->GetType(inst->type_id()); if (type->AsPointer() && - type->AsPointer()->storage_class() == SpvStorageClassWorkgroup) { - return std::make_tuple(true, false, SpvScopeWorkgroup); + type->AsPointer()->storage_class() == spv::StorageClass::Workgroup) { + return std::make_tuple(true, false, spv::Scope::Workgroup); } bool is_coherent = false; @@ -313,7 +317,7 @@ std::tuple UpgradeMemoryModel::GetInstructionAttributes( TraceInstruction(context()->get_def_use_mgr()->GetDef(id), std::vector(), &visited); - return std::make_tuple(is_coherent, is_volatile, SpvScopeQueueFamilyKHR); + return std::make_tuple(is_coherent, is_volatile, spv::Scope::QueueFamilyKHR); } std::pair UpgradeMemoryModel::TraceInstruction( @@ -336,10 +340,10 @@ std::pair UpgradeMemoryModel::TraceInstruction( bool is_coherent = false; bool is_volatile = false; switch (inst->opcode()) { - case SpvOpVariable: - case SpvOpFunctionParameter: - is_coherent |= HasDecoration(inst, 0, SpvDecorationCoherent); - is_volatile |= HasDecoration(inst, 0, SpvDecorationVolatile); + case spv::Op::OpVariable: + case spv::Op::OpFunctionParameter: + is_coherent |= HasDecoration(inst, 0, spv::Decoration::Coherent); + is_volatile |= HasDecoration(inst, 0, spv::Decoration::Volatile); if (!is_coherent || !is_volatile) { bool type_coherent = false; bool type_volatile = false; @@ -349,14 +353,14 @@ std::pair UpgradeMemoryModel::TraceInstruction( is_volatile |= type_volatile; } break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: // Store indices in reverse order. for (uint32_t i = inst->NumInOperands() - 1; i > 0; --i) { indices.push_back(inst->GetSingleWordInOperand(i)); } break; - case SpvOpPtrAccessChain: + case spv::Op::OpPtrAccessChain: // Store indices in reverse order. Skip the |Element| operand. for (uint32_t i = inst->NumInOperands() - 1; i > 1; --i) { indices.push_back(inst->GetSingleWordInOperand(i)); @@ -375,8 +379,8 @@ std::pair UpgradeMemoryModel::TraceInstruction( // Variables and function parameters are sources. Continue searching until we // reach them. - if (inst->opcode() != SpvOpVariable && - inst->opcode() != SpvOpFunctionParameter) { + if (inst->opcode() != spv::Op::OpVariable && + inst->opcode() != spv::Op::OpFunctionParameter) { inst->ForEachInId([this, &is_coherent, &is_volatile, &indices, &visited](const uint32_t* id_ptr) { Instruction* op_inst = context()->get_def_use_mgr()->GetDef(*id_ptr); @@ -404,24 +408,24 @@ std::pair UpgradeMemoryModel::CheckType( bool is_coherent = false; bool is_volatile = false; Instruction* type_inst = context()->get_def_use_mgr()->GetDef(type_id); - assert(type_inst->opcode() == SpvOpTypePointer); + assert(type_inst->opcode() == spv::Op::OpTypePointer); Instruction* element_inst = context()->get_def_use_mgr()->GetDef( type_inst->GetSingleWordInOperand(1u)); for (int i = (int)indices.size() - 1; i >= 0; --i) { if (is_coherent && is_volatile) break; - if (element_inst->opcode() == SpvOpTypePointer) { + if (element_inst->opcode() == spv::Op::OpTypePointer) { element_inst = context()->get_def_use_mgr()->GetDef( element_inst->GetSingleWordInOperand(1u)); - } else if (element_inst->opcode() == SpvOpTypeStruct) { + } else if (element_inst->opcode() == spv::Op::OpTypeStruct) { uint32_t index = indices.at(i); Instruction* index_inst = context()->get_def_use_mgr()->GetDef(index); - assert(index_inst->opcode() == SpvOpConstant); + assert(index_inst->opcode() == spv::Op::OpConstant); uint64_t value = GetIndexValue(index_inst); is_coherent |= HasDecoration(element_inst, static_cast(value), - SpvDecorationCoherent); + spv::Decoration::Coherent); is_volatile |= HasDecoration(element_inst, static_cast(value), - SpvDecorationVolatile); + spv::Decoration::Volatile); element_inst = context()->get_def_use_mgr()->GetDef( element_inst->GetSingleWordInOperand(static_cast(value))); } else { @@ -457,13 +461,13 @@ std::pair UpgradeMemoryModel::CheckAllTypes( if (!visited.insert(def).second) continue; - if (def->opcode() == SpvOpTypeStruct) { + if (def->opcode() == spv::Op::OpTypeStruct) { // Any member decorated with coherent and/or volatile is enough to have // the related operation be flagged as coherent and/or volatile. is_coherent |= HasDecoration(def, std::numeric_limits::max(), - SpvDecorationCoherent); + spv::Decoration::Coherent); is_volatile |= HasDecoration(def, std::numeric_limits::max(), - SpvDecorationVolatile); + spv::Decoration::Volatile); if (is_coherent && is_volatile) return std::make_pair(is_coherent, is_volatile); @@ -475,7 +479,7 @@ std::pair UpgradeMemoryModel::CheckAllTypes( } else if (spvOpcodeIsComposite(def->opcode())) { stack.push_back(context()->get_def_use_mgr()->GetDef( def->GetSingleWordInOperand(0u))); - } else if (def->opcode() == SpvOpTypePointer) { + } else if (def->opcode() == spv::Op::OpTypePointer) { stack.push_back(context()->get_def_use_mgr()->GetDef( def->GetSingleWordInOperand(1u))); } @@ -504,14 +508,15 @@ uint64_t UpgradeMemoryModel::GetIndexValue(Instruction* index_inst) { } bool UpgradeMemoryModel::HasDecoration(const Instruction* inst, uint32_t value, - SpvDecoration decoration) { + spv::Decoration decoration) { // If the iteration was terminated early then an appropriate decoration was // found. return !context()->get_decoration_mgr()->WhileEachDecoration( - inst->result_id(), decoration, [value](const Instruction& i) { - if (i.opcode() == SpvOpDecorate || i.opcode() == SpvOpDecorateId) { + inst->result_id(), (uint32_t)decoration, [value](const Instruction& i) { + if (i.opcode() == spv::Op::OpDecorate || + i.opcode() == spv::Op::OpDecorateId) { return false; - } else if (i.opcode() == SpvOpMemberDecorate) { + } else if (i.opcode() == spv::Op::OpMemberDecorate) { if (value == i.GetSingleWordInOperand(1u) || value == std::numeric_limits::max()) return false; @@ -533,27 +538,27 @@ void UpgradeMemoryModel::UpgradeFlags(Instruction* inst, uint32_t in_operand, } if (is_coherent) { if (inst_type == kMemory) { - flags |= SpvMemoryAccessNonPrivatePointerKHRMask; + flags |= uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR); if (operation_type == kVisibility) { - flags |= SpvMemoryAccessMakePointerVisibleKHRMask; + flags |= uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR); } else { - flags |= SpvMemoryAccessMakePointerAvailableKHRMask; + flags |= uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR); } } else { - flags |= SpvImageOperandsNonPrivateTexelKHRMask; + flags |= uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR); if (operation_type == kVisibility) { - flags |= SpvImageOperandsMakeTexelVisibleKHRMask; + flags |= uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR); } else { - flags |= SpvImageOperandsMakeTexelAvailableKHRMask; + flags |= uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR); } } } if (is_volatile) { if (inst_type == kMemory) { - flags |= SpvMemoryAccessVolatileMask; + flags |= uint32_t(spv::MemoryAccessMask::Volatile); } else { - flags |= SpvImageOperandsVolatileTexelKHRMask; + flags |= uint32_t(spv::ImageOperandsMask::VolatileTexelKHR); } } @@ -566,7 +571,7 @@ void UpgradeMemoryModel::UpgradeFlags(Instruction* inst, uint32_t in_operand, } } -uint32_t UpgradeMemoryModel::GetScopeConstant(SpvScope scope) { +uint32_t UpgradeMemoryModel::GetScopeConstant(spv::Scope scope) { analysis::Integer int_ty(32, false); uint32_t int_id = context()->get_type_mgr()->GetTypeInstruction(&int_ty); const analysis::Constant* constant = @@ -587,15 +592,19 @@ void UpgradeMemoryModel::CleanupDecorations() { context()->get_decoration_mgr()->RemoveDecorationsFrom( inst->result_id(), [](const Instruction& dec) { switch (dec.opcode()) { - case SpvOpDecorate: - case SpvOpDecorateId: - if (dec.GetSingleWordInOperand(1u) == SpvDecorationCoherent || - dec.GetSingleWordInOperand(1u) == SpvDecorationVolatile) + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + if (spv::Decoration(dec.GetSingleWordInOperand(1u)) == + spv::Decoration::Coherent || + spv::Decoration(dec.GetSingleWordInOperand(1u)) == + spv::Decoration::Volatile) return true; break; - case SpvOpMemberDecorate: - if (dec.GetSingleWordInOperand(2u) == SpvDecorationCoherent || - dec.GetSingleWordInOperand(2u) == SpvDecorationVolatile) + case spv::Op::OpMemberDecorate: + if (spv::Decoration(dec.GetSingleWordInOperand(2u)) == + spv::Decoration::Coherent || + spv::Decoration(dec.GetSingleWordInOperand(2u)) == + spv::Decoration::Volatile) return true; break; default: @@ -616,7 +625,7 @@ void UpgradeMemoryModel::UpgradeBarriers() { for (auto& block : *function) { block.ForEachInst([this, &barriers, &operates_on_output](Instruction* inst) { - if (inst->opcode() == SpvOpControlBarrier) { + if (inst->opcode() == spv::Op::OpControlBarrier) { barriers.push_back(inst); } else if (!operates_on_output) { // This instruction operates on output storage class if it is a @@ -625,7 +634,7 @@ void UpgradeMemoryModel::UpgradeBarriers() { analysis::Type* type = context()->get_type_mgr()->GetType(inst->type_id()); if (type && type->AsPointer() && - type->AsPointer()->storage_class() == SpvStorageClassOutput) { + type->AsPointer()->storage_class() == spv::StorageClass::Output) { operates_on_output = true; return; } @@ -635,7 +644,8 @@ void UpgradeMemoryModel::UpgradeBarriers() { analysis::Type* op_type = context()->get_type_mgr()->GetType(op_inst->type_id()); if (op_type && op_type->AsPointer() && - op_type->AsPointer()->storage_class() == SpvStorageClassOutput) + op_type->AsPointer()->storage_class() == + spv::StorageClass::Output) operates_on_output = true; }); } @@ -646,7 +656,8 @@ void UpgradeMemoryModel::UpgradeBarriers() { std::queue roots; for (auto& e : get_module()->entry_points()) - if (e.GetSingleWordInOperand(0u) == SpvExecutionModelTessellationControl) { + if (spv::ExecutionModel(e.GetSingleWordInOperand(0u)) == + spv::ExecutionModel::TessellationControl) { roots.push(e.GetSingleWordInOperand(1u)); if (context()->ProcessCallTreeFromRoots(CollectBarriers, &roots)) { for (auto barrier : barriers) { @@ -659,8 +670,9 @@ void UpgradeMemoryModel::UpgradeBarriers() { uint64_t semantics_value = GetIndexValue(semantics_inst); const analysis::Constant* constant = context()->get_constant_mgr()->GetConstant( - semantics_type, {static_cast(semantics_value) | - SpvMemorySemanticsOutputMemoryKHRMask}); + semantics_type, + {static_cast(semantics_value) | + uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR)}); barrier->SetInOperand(2u, {context() ->get_constant_mgr() ->GetDefiningInstruction(constant) @@ -680,15 +692,15 @@ void UpgradeMemoryModel::UpgradeMemoryScope() { // * Workgroup ops (e.g. async_copy) have at most workgroup scope. if (spvOpcodeIsAtomicOp(inst->opcode())) { if (IsDeviceScope(inst->GetSingleWordInOperand(1))) { - inst->SetInOperand(1, {GetScopeConstant(SpvScopeQueueFamilyKHR)}); + inst->SetInOperand(1, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); } - } else if (inst->opcode() == SpvOpControlBarrier) { + } else if (inst->opcode() == spv::Op::OpControlBarrier) { if (IsDeviceScope(inst->GetSingleWordInOperand(1))) { - inst->SetInOperand(1, {GetScopeConstant(SpvScopeQueueFamilyKHR)}); + inst->SetInOperand(1, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); } - } else if (inst->opcode() == SpvOpMemoryBarrier) { + } else if (inst->opcode() == spv::Op::OpMemoryBarrier) { if (IsDeviceScope(inst->GetSingleWordInOperand(0))) { - inst->SetInOperand(0, {GetScopeConstant(SpvScopeQueueFamilyKHR)}); + inst->SetInOperand(0, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); } } }); @@ -704,14 +716,14 @@ bool UpgradeMemoryModel::IsDeviceScope(uint32_t scope_id) { assert(type->width() == 32 || type->width() == 64); if (type->width() == 32) { if (type->IsSigned()) - return static_cast(constant->GetS32()) == SpvScopeDevice; + return static_cast(constant->GetS32()) == spv::Scope::Device; else - return static_cast(constant->GetU32()) == SpvScopeDevice; + return static_cast(constant->GetU32()) == spv::Scope::Device; } else { if (type->IsSigned()) - return static_cast(constant->GetS64()) == SpvScopeDevice; + return static_cast(constant->GetS64()) == spv::Scope::Device; else - return static_cast(constant->GetU64()) == SpvScopeDevice; + return static_cast(constant->GetU64()) == spv::Scope::Device; } assert(false); @@ -758,9 +770,9 @@ void UpgradeMemoryModel::UpgradeExtInst(Instruction* ext_inst) { uint32_t UpgradeMemoryModel::MemoryAccessNumWords(uint32_t mask) { uint32_t result = 1; - if (mask & SpvMemoryAccessAlignedMask) ++result; - if (mask & SpvMemoryAccessMakePointerAvailableKHRMask) ++result; - if (mask & SpvMemoryAccessMakePointerVisibleKHRMask) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result; return result; } diff --git a/3rdparty/spirv-tools/source/opt/upgrade_memory_model.h b/3rdparty/spirv-tools/source/opt/upgrade_memory_model.h index f75304ed0..489436b6d 100644 --- a/3rdparty/spirv-tools/source/opt/upgrade_memory_model.h +++ b/3rdparty/spirv-tools/source/opt/upgrade_memory_model.h @@ -71,7 +71,7 @@ class UpgradeMemoryModel : public Pass { void UpgradeAtomics(); // Returns whether |id| is coherent and/or volatile. - std::tuple GetInstructionAttributes(uint32_t id); + std::tuple GetInstructionAttributes(uint32_t id); // Traces |inst| to determine if it is coherent and/or volatile. // |indices| tracks the access chain indices seen so far. @@ -84,7 +84,7 @@ class UpgradeMemoryModel : public Pass { // match the index or |value| must be a maximum allowable value. The max // value allows any element to match. bool HasDecoration(const Instruction* inst, uint32_t value, - SpvDecoration decoration); + spv::Decoration decoration); // Returns whether |type_id| indexed via |indices| is coherent and/or // volatile. @@ -108,7 +108,7 @@ class UpgradeMemoryModel : public Pass { bool is_volatile); // Returns the result id for a constant for |scope|. - uint32_t GetScopeConstant(SpvScope scope); + uint32_t GetScopeConstant(spv::Scope scope); // Returns the value of |index_inst|. |index_inst| must be an OpConstant of // integer type.g @@ -127,7 +127,7 @@ class UpgradeMemoryModel : public Pass { // scope. void UpgradeMemoryScope(); - // Returns true if |scope_id| is SpvScopeDevice. + // Returns true if |scope_id| is spv::Scope::Device. bool IsDeviceScope(uint32_t scope_id); // Upgrades GLSL.std.450 modf and frexp. Both instructions are replaced with diff --git a/3rdparty/spirv-tools/source/opt/value_number_table.cpp b/3rdparty/spirv-tools/source/opt/value_number_table.cpp index 5271e3fe9..743dc52bb 100644 --- a/3rdparty/spirv-tools/source/opt/value_number_table.cpp +++ b/3rdparty/spirv-tools/source/opt/value_number_table.cpp @@ -57,9 +57,9 @@ uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { } switch (inst->opcode()) { - case SpvOpSampledImage: - case SpvOpImage: - case SpvOpVariable: + case spv::Op::OpSampledImage: + case spv::Op::OpImage: + case spv::Op::OpVariable: value = TakeNextValueNumber(); id_to_value_[inst->result_id()] = value; return value; @@ -82,7 +82,7 @@ uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { analysis::DecorationManager* dec_mgr = context()->get_decoration_mgr(); // When we copy an object, the value numbers should be the same. - if (inst->opcode() == SpvOpCopyObject && + if (inst->opcode() == spv::Op::OpCopyObject && dec_mgr->HaveTheSameDecorations(inst->result_id(), inst->GetSingleWordInOperand(0))) { value = GetValueNumber(inst->GetSingleWordInOperand(0)); @@ -94,7 +94,7 @@ uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { // Phi nodes are a type of copy. If all of the inputs have the same value // number, then we can assign the result of the phi the same value number. - if (inst->opcode() == SpvOpPhi && inst->NumInOperands() > 0 && + if (inst->opcode() == spv::Op::OpPhi && inst->NumInOperands() > 0 && dec_mgr->HaveTheSameDecorations(inst->result_id(), inst->GetSingleWordInOperand(0))) { value = GetValueNumber(inst->GetSingleWordInOperand(0)); @@ -226,7 +226,7 @@ std::size_t ValueTableHash::operator()(const Instruction& inst) const { // instructions that are the same except for the result to hash to the // same value. std::u32string h; - h.push_back(inst.opcode()); + h.push_back(uint32_t(inst.opcode())); h.push_back(inst.type_id()); for (uint32_t i = 0; i < inst.NumInOperands(); ++i) { const auto& opnd = inst.GetInOperand(i); diff --git a/3rdparty/spirv-tools/source/opt/vector_dce.cpp b/3rdparty/spirv-tools/source/opt/vector_dce.cpp index 28d94a076..1e8d255dd 100644 --- a/3rdparty/spirv-tools/source/opt/vector_dce.cpp +++ b/3rdparty/spirv-tools/source/opt/vector_dce.cpp @@ -19,11 +19,9 @@ namespace spvtools { namespace opt { namespace { - -const uint32_t kExtractCompositeIdInIdx = 0; -const uint32_t kInsertObjectIdInIdx = 0; -const uint32_t kInsertCompositeIdInIdx = 1; - +constexpr uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kInsertObjectIdInIdx = 0; +constexpr uint32_t kInsertCompositeIdInIdx = 1; } // namespace Pass::Status VectorDCE::Process() { @@ -68,17 +66,17 @@ void VectorDCE::FindLiveComponents(Function* function, Instruction* current_inst = current_item.instruction; switch (current_inst->opcode()) { - case SpvOpCompositeExtract: + case spv::Op::OpCompositeExtract: MarkExtractUseAsLive(current_inst, current_item.components, live_components, &work_list); break; - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: MarkInsertUsesAsLive(current_item, live_components, &work_list); break; - case SpvOpVectorShuffle: + case spv::Op::OpVectorShuffle: MarkVectorShuffleUsesAsLive(current_item, live_components, &work_list); break; - case SpvOpCompositeConstruct: + case spv::Op::OpCompositeConstruct: MarkCompositeContructUsesAsLive(current_item, live_components, &work_list); break; @@ -347,11 +345,11 @@ bool VectorDCE::RewriteInstructions( } switch (current_inst->opcode()) { - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: modified |= RewriteInsertInstruction( current_inst, live_component->second, &dead_dbg_value); break; - case SpvOpCompositeConstruct: + case spv::Op::OpCompositeConstruct: // TODO: The members that are not live can be replaced by an undef // or constant. This will remove uses of those values, and possibly // create opportunities for ADCE. diff --git a/3rdparty/spirv-tools/source/opt/workaround1209.cpp b/3rdparty/spirv-tools/source/opt/workaround1209.cpp index d6e9d2cf7..0cf954afd 100644 --- a/3rdparty/spirv-tools/source/opt/workaround1209.cpp +++ b/3rdparty/spirv-tools/source/opt/workaround1209.cpp @@ -43,13 +43,13 @@ bool Workaround1209::RemoveOpUnreachableInLoops() { loop_merges.pop(); } - if (bb->tail()->opcode() == SpvOpUnreachable) { + if (bb->tail()->opcode() == spv::Op::OpUnreachable) { if (!loop_merges.empty()) { // We found an OpUnreachable inside a loop. // Replace it with an unconditional branch to the loop merge. context()->KillInst(&*bb->tail()); std::unique_ptr new_branch( - new Instruction(context(), SpvOpBranch, 0, 0, + new Instruction(context(), spv::Op::OpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {loop_merges.top()}}})); context()->AnalyzeDefUse(&*new_branch); diff --git a/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp b/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp index 51432a73b..c0c6d6221 100644 --- a/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp +++ b/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp @@ -28,7 +28,8 @@ Pass::Status WrapOpKill::Process() { Function* func = context()->GetFunction(func_id); bool successful = func->WhileEachInst([this, &modified](Instruction* inst) { const auto opcode = inst->opcode(); - if ((opcode == SpvOpKill) || (opcode == SpvOpTerminateInvocation)) { + if ((opcode == spv::Op::OpKill) || + (opcode == spv::Op::OpTerminateInvocation)) { modified = true; if (!ReplaceWithFunctionCall(inst)) { return false; @@ -56,8 +57,8 @@ Pass::Status WrapOpKill::Process() { } bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { - assert((inst->opcode() == SpvOpKill || - inst->opcode() == SpvOpTerminateInvocation) && + assert((inst->opcode() == spv::Op::OpKill || + inst->opcode() == spv::Op::OpTerminateInvocation) && "|inst| must be an OpKill or OpTerminateInvocation instruction."); InstructionBuilder ir_builder( context(), inst, @@ -76,14 +77,15 @@ bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { Instruction* return_inst = nullptr; uint32_t return_type_id = GetOwningFunctionsReturnType(inst); if (return_type_id != GetVoidTypeId()) { - Instruction* undef = ir_builder.AddNullaryOp(return_type_id, SpvOpUndef); + Instruction* undef = + ir_builder.AddNullaryOp(return_type_id, spv::Op::OpUndef); if (undef == nullptr) { return false; } return_inst = - ir_builder.AddUnaryOp(0, SpvOpReturnValue, undef->result_id()); + ir_builder.AddUnaryOp(0, spv::Op::OpReturnValue, undef->result_id()); } else { - return_inst = ir_builder.AddNullaryOp(0, SpvOpReturn); + return_inst = ir_builder.AddNullaryOp(0, spv::Op::OpReturn); } if (return_inst == nullptr) { @@ -115,13 +117,13 @@ uint32_t WrapOpKill::GetVoidFunctionTypeId() { return type_mgr->GetTypeInstruction(&func_type); } -uint32_t WrapOpKill::GetKillingFuncId(SpvOp opcode) { +uint32_t WrapOpKill::GetKillingFuncId(spv::Op opcode) { // Parameterize by opcode - assert(opcode == SpvOpKill || opcode == SpvOpTerminateInvocation); + assert(opcode == spv::Op::OpKill || opcode == spv::Op::OpTerminateInvocation); std::unique_ptr* const killing_func = - (opcode == SpvOpKill) ? &opkill_function_ - : &opterminateinvocation_function_; + (opcode == spv::Op::OpKill) ? &opkill_function_ + : &opterminateinvocation_function_; if (*killing_func != nullptr) { return (*killing_func)->result_id(); @@ -139,14 +141,14 @@ uint32_t WrapOpKill::GetKillingFuncId(SpvOp opcode) { // Generate the function start instruction std::unique_ptr func_start(new Instruction( - context(), SpvOpFunction, void_type_id, killing_func_id, {})); + context(), spv::Op::OpFunction, void_type_id, killing_func_id, {})); func_start->AddOperand({SPV_OPERAND_TYPE_FUNCTION_CONTROL, {0}}); func_start->AddOperand({SPV_OPERAND_TYPE_ID, {GetVoidFunctionTypeId()}}); (*killing_func).reset(new Function(std::move(func_start))); // Generate the function end instruction std::unique_ptr func_end( - new Instruction(context(), SpvOpFunctionEnd, 0, 0, {})); + new Instruction(context(), spv::Op::OpFunctionEnd, 0, 0, {})); (*killing_func)->SetFunctionEnd(std::move(func_end)); // Create the one basic block for the function. @@ -155,7 +157,7 @@ uint32_t WrapOpKill::GetKillingFuncId(SpvOp opcode) { return 0; } std::unique_ptr label_inst( - new Instruction(context(), SpvOpLabel, 0, lab_id, {})); + new Instruction(context(), spv::Op::OpLabel, 0, lab_id, {})); std::unique_ptr bb(new BasicBlock(std::move(label_inst))); // Add the OpKill to the basic block diff --git a/3rdparty/spirv-tools/source/opt/wrap_opkill.h b/3rdparty/spirv-tools/source/opt/wrap_opkill.h index 7e43ca6cd..c9eb88877 100644 --- a/3rdparty/spirv-tools/source/opt/wrap_opkill.h +++ b/3rdparty/spirv-tools/source/opt/wrap_opkill.h @@ -53,7 +53,7 @@ class WrapOpKill : public Pass { // Return the id of a function that has return type void, has no parameters, // and contains a single instruction, which is |opcode|, either OpKill or // OpTerminateInvocation. Returns 0 if the function could not be generated. - uint32_t GetKillingFuncId(SpvOp opcode); + uint32_t GetKillingFuncId(spv::Op opcode); // Returns the id of the return type for the function that contains |inst|. // Returns 0 if |inst| is not in a function. diff --git a/3rdparty/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp index 2cd779a26..93b51a11f 100644 --- a/3rdparty/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp @@ -36,9 +36,9 @@ ConditionalBranchToSimpleConditionalBranchOpportunityFinder:: for (auto* function : GetTargetFunctions(context, target_function)) { // Consider every block in the function. for (auto& block : *function) { - // The terminator must be SpvOpBranchConditional. + // The terminator must be spv::Op::OpBranchConditional. opt::Instruction* terminator = block.terminator(); - if (terminator->opcode() != SpvOpBranchConditional) { + if (terminator->opcode() != spv::Op::OpBranchConditional) { continue; } diff --git a/3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp b/3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp index a2c3b40a0..e626d60ba 100644 --- a/3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp +++ b/3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp @@ -23,7 +23,7 @@ namespace reduce { MergeBlocksReductionOpportunity::MergeBlocksReductionOpportunity( opt::IRContext* context, opt::Function* function, opt::BasicBlock* block) { // Precondition: the terminator has to be OpBranch. - assert(block->terminator()->opcode() == SpvOpBranch); + assert(block->terminator()->opcode() == spv::Op::OpBranch); context_ = context; function_ = function; // Get the successor block associated with the OpBranch. diff --git a/3rdparty/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp index eb7498ad1..c6196f367 100644 --- a/3rdparty/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp @@ -50,7 +50,7 @@ OperandToConstReductionOpportunityFinder::GetAvailableOpportunities( // The argument is already a constant. continue; } - if (def->opcode() == SpvOpFunction) { + if (def->opcode() == spv::Op::OpFunction) { // The argument refers to a function, e.g. the function called // by OpFunctionCall; avoid replacing this with a constant of // the function's return type. diff --git a/3rdparty/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp index 06bf9550a..c7bc12135 100644 --- a/3rdparty/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp @@ -32,7 +32,7 @@ OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities( auto type_id = inst.type_id(); if (type_id) { auto type_id_def = context->get_def_use_mgr()->GetDef(type_id); - if (type_id_def->opcode() == SpvOpTypePointer) { + if (type_id_def->opcode() == spv::Op::OpTypePointer) { continue; } } @@ -57,7 +57,7 @@ OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities( } // Don't replace function operands with undef. - if (operand_id_def->opcode() == SpvOpFunction) { + if (operand_id_def->opcode() == spv::Op::OpFunction) { continue; } @@ -68,7 +68,7 @@ OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities( context->get_def_use_mgr()->GetDef(operand_type_id); // Skip pointer operands. - if (operand_type_id_def->opcode() == SpvOpTypePointer) { + if (operand_type_id_def->opcode() == spv::Op::OpTypePointer) { continue; } diff --git a/3rdparty/spirv-tools/source/reduce/reduction_util.cpp b/3rdparty/spirv-tools/source/reduce/reduction_util.cpp index 511f43236..c9882d5e9 100644 --- a/3rdparty/spirv-tools/source/reduce/reduction_util.cpp +++ b/3rdparty/spirv-tools/source/reduce/reduction_util.cpp @@ -26,7 +26,7 @@ const uint32_t kFalseBranchOperandIndex = 2; uint32_t FindOrCreateGlobalVariable(opt::IRContext* context, uint32_t pointer_type_id) { for (auto& inst : context->module()->types_values()) { - if (inst.opcode() != SpvOpVariable) { + if (inst.opcode() != spv::Op::OpVariable) { continue; } if (inst.type_id() == pointer_type_id) { @@ -35,7 +35,7 @@ uint32_t FindOrCreateGlobalVariable(opt::IRContext* context, } const uint32_t variable_id = context->TakeNextId(); auto variable_inst = MakeUnique( - context, SpvOpVariable, pointer_type_id, variable_id, + context, spv::Op::OpVariable, pointer_type_id, variable_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(context->get_type_mgr() @@ -53,7 +53,7 @@ uint32_t FindOrCreateFunctionVariable(opt::IRContext* context, assert(context->get_type_mgr() ->GetType(pointer_type_id) ->AsPointer() - ->storage_class() == SpvStorageClassFunction); + ->storage_class() == spv::StorageClass::Function); // Go through the instructions in the function's first block until we find a // suitable variable, or go past all the variables. @@ -62,7 +62,7 @@ uint32_t FindOrCreateFunctionVariable(opt::IRContext* context, // We will either find a suitable variable, or find a non-variable // instruction; we won't exhaust all instructions. assert(iter != function->begin()->end()); - if (iter->opcode() != SpvOpVariable) { + if (iter->opcode() != spv::Op::OpVariable) { // If we see a non-variable, we have gone through all the variables. break; } @@ -74,16 +74,17 @@ uint32_t FindOrCreateFunctionVariable(opt::IRContext* context, // function's entry block. const uint32_t variable_id = context->TakeNextId(); auto variable_inst = MakeUnique( - context, SpvOpVariable, pointer_type_id, variable_id, + context, spv::Op::OpVariable, pointer_type_id, variable_id, opt::Instruction::OperandList( - {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); + {{SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}})); iter->InsertBefore(std::move(variable_inst)); return variable_id; } uint32_t FindOrCreateGlobalUndef(opt::IRContext* context, uint32_t type_id) { for (auto& inst : context->module()->types_values()) { - if (inst.opcode() != SpvOpUndef) { + if (inst.opcode() != spv::Op::OpUndef) { continue; } if (inst.type_id() == type_id) { @@ -91,8 +92,9 @@ uint32_t FindOrCreateGlobalUndef(opt::IRContext* context, uint32_t type_id) { } } const uint32_t undef_id = context->TakeNextId(); - auto undef_inst = MakeUnique( - context, SpvOpUndef, type_id, undef_id, opt::Instruction::OperandList()); + auto undef_inst = + MakeUnique(context, spv::Op::OpUndef, type_id, undef_id, + opt::Instruction::OperandList()); assert(undef_id == undef_inst->result_id()); context->module()->AddGlobalValue(std::move(undef_inst)); return undef_id; diff --git a/3rdparty/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp index 74df1b8db..6abadf2a8 100644 --- a/3rdparty/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp @@ -36,7 +36,7 @@ RemoveSelectionReductionOpportunityFinder::GetAvailableOpportunities( for (auto* function : GetTargetFunctions(context, target_function)) { for (auto& block : *function) { if (auto merge_instruction = block.GetMergeInst()) { - if (merge_instruction->opcode() == SpvOpLoopMerge) { + if (merge_instruction->opcode() == spv::Op::OpLoopMerge) { uint32_t merge_block_id = merge_instruction->GetSingleWordOperand(kMergeNodeIndex); uint32_t continue_block_id = @@ -54,7 +54,7 @@ RemoveSelectionReductionOpportunityFinder::GetAvailableOpportunities( for (auto& function : *context->module()) { for (auto& block : function) { if (auto merge_instruction = block.GetMergeInst()) { - if (merge_instruction->opcode() == SpvOpSelectionMerge) { + if (merge_instruction->opcode() == spv::Op::OpSelectionMerge) { if (CanOpSelectionMergeBeRemoved( context, block, merge_instruction, merge_and_continue_blocks_from_loops)) { diff --git a/3rdparty/spirv-tools/source/reduce/remove_struct_member_reduction_opportunity.cpp b/3rdparty/spirv-tools/source/reduce/remove_struct_member_reduction_opportunity.cpp index e72ed3514..3309fd099 100644 --- a/3rdparty/spirv-tools/source/reduce/remove_struct_member_reduction_opportunity.cpp +++ b/3rdparty/spirv-tools/source/reduce/remove_struct_member_reduction_opportunity.cpp @@ -36,14 +36,14 @@ void RemoveStructMemberReductionOpportunity::Apply() { struct_type_, [this, &decorations_to_kill](opt::Instruction* user, uint32_t /*operand_index*/) { switch (user->opcode()) { - case SpvOpCompositeConstruct: - case SpvOpConstantComposite: + case spv::Op::OpCompositeConstruct: + case spv::Op::OpConstantComposite: // This use is constructing a composite of the struct type, so we // must remove the id that was provided for the member we are // removing. user->RemoveInOperand(member_index_); break; - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: // This use is decorating a member of the struct. if (user->GetSingleWordInOperand(1) == member_index_) { // The member we are removing is being decorated, so we record @@ -78,8 +78,8 @@ void RemoveStructMemberReductionOpportunity::Apply() { for (auto& block : function) { for (auto& inst : block) { switch (inst.opcode()) { - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: { // These access chain instructions take sequences of ids for // indexing, starting from input operand 1. auto composite_type_id = @@ -90,8 +90,8 @@ void RemoveStructMemberReductionOpportunity::Apply() { ->GetSingleWordInOperand(1); AdjustAccessedIndices(composite_type_id, 1, false, context, &inst); } break; - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: { + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: { // These access chain instructions take sequences of ids for // indexing, starting from input operand 2. auto composite_type_id = @@ -102,7 +102,7 @@ void RemoveStructMemberReductionOpportunity::Apply() { ->GetSingleWordInOperand(1); AdjustAccessedIndices(composite_type_id, 2, false, context, &inst); } break; - case SpvOpCompositeExtract: { + case spv::Op::OpCompositeExtract: { // OpCompositeExtract uses literals for indexing, starting at input // operand 1. auto composite_type_id = @@ -111,7 +111,7 @@ void RemoveStructMemberReductionOpportunity::Apply() { ->type_id(); AdjustAccessedIndices(composite_type_id, 1, true, context, &inst); } break; - case SpvOpCompositeInsert: { + case spv::Op::OpCompositeInsert: { // OpCompositeInsert uses literals for indexing, starting at input // operand 2. auto composite_type_id = @@ -146,13 +146,13 @@ void RemoveStructMemberReductionOpportunity::AdjustAccessedIndices( i < composite_access_instruction->NumInOperands(); i++) { auto type_inst = context->get_def_use_mgr()->GetDef(next_type); switch (type_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeMatrix: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: next_type = type_inst->GetSingleWordInOperand(0); break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { // Struct types are special because (a) we may need to adjust the index // being used, if the struct type is the one from which we are removing // a member, and (b) the type encountered by following the current index diff --git a/3rdparty/spirv-tools/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp index d7bb3a82e..fbbeb3462 100644 --- a/3rdparty/spirv-tools/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp @@ -103,8 +103,8 @@ RemoveUnusedInstructionReductionOpportunityFinder::GetAvailableOpportunities( continue; } if (spvOpcodeIsBlockTerminator(inst.opcode()) || - inst.opcode() == SpvOpSelectionMerge || - inst.opcode() == SpvOpLoopMerge) { + inst.opcode() == spv::Op::OpSelectionMerge || + inst.opcode() == spv::Op::OpLoopMerge) { // In this reduction pass we do not want to affect static // control flow. continue; @@ -133,7 +133,7 @@ bool RemoveUnusedInstructionReductionOpportunityFinder:: &inst, [this](opt::Instruction* user, uint32_t use_index) -> bool { return (user->IsDecoration() && !IsIndependentlyRemovableDecoration(*user)) || - (user->opcode() == SpvOpEntryPoint && use_index > 2); + (user->opcode() == spv::Op::OpEntryPoint && use_index > 2); }); } @@ -141,13 +141,13 @@ bool RemoveUnusedInstructionReductionOpportunityFinder:: IsIndependentlyRemovableDecoration(const opt::Instruction& inst) const { uint32_t decoration; switch (inst.opcode()) { - case SpvOpDecorate: - case SpvOpDecorateId: - case SpvOpDecorateString: + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateString: decoration = inst.GetSingleWordInOperand(1u); break; - case SpvOpMemberDecorate: - case SpvOpMemberDecorateString: + case spv::Op::OpMemberDecorate: + case spv::Op::OpMemberDecorateString: decoration = inst.GetSingleWordInOperand(2u); break; default: @@ -160,12 +160,12 @@ bool RemoveUnusedInstructionReductionOpportunityFinder:: // not change the shader interface, will not make the shader invalid, will // actually be found in practice, etc. - switch (decoration) { - case SpvDecorationRelaxedPrecision: - case SpvDecorationNoSignedWrap: - case SpvDecorationNoContraction: - case SpvDecorationNoUnsignedWrap: - case SpvDecorationUserSemantic: + switch (spv::Decoration(decoration)) { + case spv::Decoration::RelaxedPrecision: + case spv::Decoration::NoSignedWrap: + case spv::Decoration::NoContraction: + case spv::Decoration::NoUnsignedWrap: + case spv::Decoration::UserSemantic: return true; default: return false; diff --git a/3rdparty/spirv-tools/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp index cd0c4e4d7..db381e0f0 100644 --- a/3rdparty/spirv-tools/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp @@ -43,7 +43,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( // Consider every struct type in the module. for (auto& type_or_value : context->types_values()) { - if (type_or_value.opcode() != SpvOpTypeStruct) { + if (type_or_value.opcode() != spv::Op::OpTypeStruct) { continue; } @@ -60,7 +60,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( &type_or_value, [&unused_members](opt::Instruction* user, uint32_t /*operand_index*/) { switch (user->opcode()) { - case SpvOpMemberName: + case spv::Op::OpMemberName: unused_members.erase(user->GetSingleWordInOperand(1)); break; default: @@ -91,8 +91,8 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( // The way the helper is invoked depends on whether the instruction // uses literal or id indices, and the offset into the instruction's // input operands from which index operands are provided. - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(context->get_def_use_mgr() @@ -102,8 +102,8 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( MarkAccessedMembersAsUsed(context, composite_type_id, 1, false, inst, &unused_member_to_structs); } break; - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: { + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(context->get_def_use_mgr() @@ -113,7 +113,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( MarkAccessedMembersAsUsed(context, composite_type_id, 2, false, inst, &unused_member_to_structs); } break; - case SpvOpCompositeExtract: { + case spv::Op::OpCompositeExtract: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(inst.GetSingleWordInOperand(0)) @@ -121,7 +121,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( MarkAccessedMembersAsUsed(context, composite_type_id, 1, true, inst, &unused_member_to_structs); } break; - case SpvOpCompositeInsert: { + case spv::Op::OpCompositeInsert: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(inst.GetSingleWordInOperand(1)) @@ -163,13 +163,13 @@ void RemoveUnusedStructMemberReductionOpportunityFinder:: i < composite_access_instruction.NumInOperands(); i++) { auto type_inst = context->get_def_use_mgr()->GetDef(next_type); switch (type_inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeMatrix: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: next_type = type_inst->GetSingleWordInOperand(0); break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { uint32_t index_operand = composite_access_instruction.GetSingleWordInOperand(i); uint32_t member = literal_indices ? index_operand diff --git a/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp b/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp index d867c3ad9..9637f0f16 100644 --- a/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp +++ b/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp @@ -29,15 +29,15 @@ SimpleConditionalBranchToBranchOpportunityFinder::GetAvailableOpportunities( for (auto* function : GetTargetFunctions(context, target_function)) { // Consider every block in the function. for (auto& block : *function) { - // The terminator must be SpvOpBranchConditional. + // The terminator must be spv::Op::OpBranchConditional. opt::Instruction* terminator = block.terminator(); - if (terminator->opcode() != SpvOpBranchConditional) { + if (terminator->opcode() != spv::Op::OpBranchConditional) { continue; } // It must not be a selection header, as these cannot be followed by // OpBranch. if (block.GetMergeInst() && - block.GetMergeInst()->opcode() == SpvOpSelectionMerge) { + block.GetMergeInst()->opcode() == spv::Op::OpSelectionMerge) { continue; } // The conditional branch must be simplified. diff --git a/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp b/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp index a2be0c4d9..6d772b594 100644 --- a/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp +++ b/3rdparty/spirv-tools/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp @@ -31,7 +31,8 @@ bool SimpleConditionalBranchToBranchReductionOpportunity::PreconditionHolds() { } void SimpleConditionalBranchToBranchReductionOpportunity::Apply() { - assert(conditional_branch_instruction_->opcode() == SpvOpBranchConditional && + assert(conditional_branch_instruction_->opcode() == + spv::Op::OpBranchConditional && "SimpleConditionalBranchToBranchReductionOpportunity: branch was not " "a conditional branch"); @@ -46,7 +47,7 @@ void SimpleConditionalBranchToBranchReductionOpportunity::Apply() { // -> // OpBranch %block_id - conditional_branch_instruction_->SetOpcode(SpvOpBranch); + conditional_branch_instruction_->SetOpcode(spv::Op::OpBranch); conditional_branch_instruction_->ReplaceOperands( {{SPV_OPERAND_TYPE_ID, {conditional_branch_instruction_->GetSingleWordInOperand( diff --git a/3rdparty/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity.cpp b/3rdparty/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity.cpp index ed738411a..cc5ffe3ca 100644 --- a/3rdparty/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity.cpp +++ b/3rdparty/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity.cpp @@ -55,7 +55,7 @@ void StructuredConstructToBlockReductionOpportunity::Apply() { // The terminator for the header block is changed to be an unconditional // branch to the merge block. - header_block->terminator()->SetOpcode(SpvOpBranch); + header_block->terminator()->SetOpcode(spv::Op::OpBranch); header_block->terminator()->SetInOperands( {{SPV_OPERAND_TYPE_ID, {merge_block->id()}}}); diff --git a/3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp b/3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp index 850af4566..45b95285e 100644 --- a/3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp +++ b/3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp @@ -129,12 +129,12 @@ void StructuredLoopToSelectionReductionOpportunity::RedirectEdge( // Figure out which operands of the terminator need to be considered for // redirection. std::vector operand_indices; - if (terminator->opcode() == SpvOpBranch) { + if (terminator->opcode() == spv::Op::OpBranch) { operand_indices = {0}; - } else if (terminator->opcode() == SpvOpBranchConditional) { + } else if (terminator->opcode() == spv::Op::OpBranchConditional) { operand_indices = {1, 2}; } else { - assert(terminator->opcode() == SpvOpSwitch); + assert(terminator->opcode() == spv::Op::OpSwitch); for (uint32_t label_index = 1; label_index < terminator->NumOperands(); label_index += 2) { operand_indices.push_back(label_index); @@ -179,18 +179,19 @@ void StructuredLoopToSelectionReductionOpportunity::ChangeLoopToSelection() { auto loop_merge_inst = loop_construct_header_->GetLoopMergeInst(); auto const loop_merge_block_id = loop_merge_inst->GetSingleWordOperand(kMergeNodeIndex); - loop_merge_inst->SetOpcode(SpvOpSelectionMerge); + loop_merge_inst->SetOpcode(spv::Op::OpSelectionMerge); loop_merge_inst->ReplaceOperands( {{loop_merge_inst->GetOperand(kMergeNodeIndex).type, {loop_merge_block_id}}, - {SPV_OPERAND_TYPE_SELECTION_CONTROL, {SpvSelectionControlMaskNone}}}); + {SPV_OPERAND_TYPE_SELECTION_CONTROL, + {uint32_t(spv::SelectionControlMask::MaskNone)}}}); // The loop header either finishes with OpBranch or OpBranchConditional. // The latter is fine for a selection. In the former case we need to turn // it into OpBranchConditional. We use "true" as the condition, and make // the "else" branch be the merge block. auto terminator = loop_construct_header_->terminator(); - if (terminator->opcode() == SpvOpBranch) { + if (terminator->opcode() == spv::Op::OpBranch) { opt::analysis::Bool temp; const opt::analysis::Bool* bool_type = context_->get_type_mgr()->GetRegisteredType(&temp)->AsBool(); @@ -199,7 +200,7 @@ void StructuredLoopToSelectionReductionOpportunity::ChangeLoopToSelection() { auto true_const_result_id = const_mgr->GetDefiningInstruction(true_const)->result_id(); auto original_branch_id = terminator->GetSingleWordOperand(0); - terminator->SetOpcode(SpvOpBranchConditional); + terminator->SetOpcode(spv::Op::OpBranchConditional); terminator->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {true_const_result_id}}, {SPV_OPERAND_TYPE_ID, {original_branch_id}}, {SPV_OPERAND_TYPE_ID, {loop_merge_block_id}}}); @@ -215,7 +216,7 @@ void StructuredLoopToSelectionReductionOpportunity::FixNonDominatedIdUses() { // Consider each instruction in the function. for (auto& block : *loop_construct_header_->GetParent()) { for (auto& def : block) { - if (def.opcode() == SpvOpVariable) { + if (def.opcode() == spv::Op::OpVariable) { // Variables are defined at the start of the function, and can be // accessed by all blocks, even by unreachable blocks that have no // dominators, so we do not need to worry about them. @@ -233,11 +234,11 @@ void StructuredLoopToSelectionReductionOpportunity::FixNonDominatedIdUses() { // access chain, in which case replace it with some (possibly fresh) // variable (as we cannot load from / store to OpUndef). if (!DefinitionSufficientlyDominatesUse(&def, use, index, block)) { - if (def.opcode() == SpvOpAccessChain) { + if (def.opcode() == spv::Op::OpAccessChain) { auto pointer_type = context_->get_type_mgr()->GetType(def.type_id())->AsPointer(); switch (pointer_type->storage_class()) { - case SpvStorageClassFunction: + case spv::StorageClass::Function: use->SetOperand( index, {FindOrCreateFunctionVariable( context_, loop_construct_header_->GetParent(), @@ -270,7 +271,7 @@ bool StructuredLoopToSelectionReductionOpportunity:: opt::Instruction* use, uint32_t use_index, opt::BasicBlock& def_block) { - if (use->opcode() == SpvOpPhi) { + if (use->opcode() == spv::Op::OpPhi) { // A use in a phi doesn't need to be dominated by its definition, but the // associated parent block does need to be dominated by the definition. return context_->GetDominatorAnalysis(loop_construct_header_->GetParent()) diff --git a/3rdparty/spirv-tools/source/table.h b/3rdparty/spirv-tools/source/table.h index 5adf04a4c..8097f13f7 100644 --- a/3rdparty/spirv-tools/source/table.h +++ b/3rdparty/spirv-tools/source/table.h @@ -21,9 +21,9 @@ typedef struct spv_opcode_desc_t { const char* name; - const SpvOp opcode; + const spv::Op opcode; const uint32_t numCapabilities; - const SpvCapability* capabilities; + const spv::Capability* capabilities; // operandTypes[0..numTypes-1] describe logical operands for the instruction. // The operand types include result id and result-type id, followed by // the types of arguments. @@ -48,7 +48,7 @@ typedef struct spv_operand_desc_t { const char* name; const uint32_t value; const uint32_t numCapabilities; - const SpvCapability* capabilities; + const spv::Capability* capabilities; // A set of extensions that enable this feature. If empty then this operand // value is in core and its availability is subject to minVersion. The // assembler, binary parser, and disassembler ignore this rule, so you can @@ -73,7 +73,7 @@ typedef struct spv_ext_inst_desc_t { const char* name; const uint32_t ext_inst; const uint32_t numCapabilities; - const SpvCapability* capabilities; + const spv::Capability* capabilities; const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger? } spv_ext_inst_desc_t; diff --git a/3rdparty/spirv-tools/source/text.cpp b/3rdparty/spirv-tools/source/text.cpp index 90f69c525..8f77d624a 100644 --- a/3rdparty/spirv-tools/source/text.cpp +++ b/3rdparty/spirv-tools/source/text.cpp @@ -227,7 +227,8 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // Set the extended instruction type. // The import set id is the 3rd operand of OpExtInst. - if (pInst->opcode == SpvOpExtInst && pInst->words.size() == 4) { + if (spv::Op(pInst->opcode) == spv::Op::OpExtInst && + pInst->words.size() == 4) { auto ext_inst_type = context->getExtInstTypeForId(pInst->words[3]); if (ext_inst_type == SPV_EXT_INST_TYPE_NONE) { return context->diagnostic() @@ -279,7 +280,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // The assembler accepts the symbolic name for the opcode, but without // the "Op" prefix. For example, "IAdd" is accepted. The number // of the opcode is emitted. - SpvOp opcode; + spv::Op opcode; if (grammar.lookupSpecConstantOpcode(textValue, &opcode)) { return context->diagnostic() << "Invalid " << spvOperandTypeStr(type) << " '" << textValue << "'."; @@ -327,8 +328,8 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // The encoding for OpConstant, OpSpecConstant and OpSwitch all // depend on either their own result-id or the result-id of // one of their parameters. - if (SpvOpConstant == pInst->opcode || - SpvOpSpecConstant == pInst->opcode) { + if (spv::Op::OpConstant == pInst->opcode || + spv::Op::OpSpecConstant == pInst->opcode) { // The type of the literal is determined by the type Id of the // instruction. expected_type = @@ -344,7 +345,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, << "Type for " << opcode_name << " must be a scalar floating point or integer type"; } - } else if (pInst->opcode == SpvOpSwitch) { + } else if (pInst->opcode == spv::Op::OpSwitch) { // The type of the literal is the same as the type of the selector. expected_type = context->getTypeOfValueInstruction(pInst->words[1]); if (!spvtools::isScalarIntegral(expected_type)) { @@ -375,7 +376,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, } // NOTE: Special case for extended instruction library import - if (SpvOpExtInstImport == pInst->opcode) { + if (spv::Op::OpExtInstImport == pInst->opcode) { const spv_ext_inst_type_t ext_inst_type = spvExtInstImportTypeGet(literal.str.c_str()); if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) { @@ -688,7 +689,7 @@ spv_result_t SetHeader(spv_target_env env, const uint32_t bound, uint32_t* header) { if (!header) return SPV_ERROR_INVALID_BINARY; - header[SPV_INDEX_MAGIC_NUMBER] = SpvMagicNumber; + header[SPV_INDEX_MAGIC_NUMBER] = spv::MagicNumber; header[SPV_INDEX_VERSION_NUMBER] = spvVersionForTargetEnv(env); header[SPV_INDEX_GENERATOR_NUMBER] = SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, kAssemblerVersion); @@ -722,7 +723,7 @@ spv_result_t GetNumericIds(const spvtools::AssemblyGrammar& grammar, // being parsed. A malformed input might feature such an operand *before* // the opcode is known. To guard against accessing an uninitialized opcode, // the instruction's opcode is initialized to a default value. - inst.opcode = SpvOpMax; + inst.opcode = spv::Op::Max; if (spvTextEncodeOpcode(grammar, &context, &inst)) { return SPV_ERROR_INVALID_TEXT; diff --git a/3rdparty/spirv-tools/source/text_handler.cpp b/3rdparty/spirv-tools/source/text_handler.cpp index 15c1741f6..35c4b83c1 100644 --- a/3rdparty/spirv-tools/source/text_handler.cpp +++ b/3rdparty/spirv-tools/source/text_handler.cpp @@ -323,12 +323,12 @@ spv_result_t AssemblyContext::recordTypeDefinition( << " has already been used to generate a type"; } - if (pInst->opcode == SpvOpTypeInt) { + if (pInst->opcode == spv::Op::OpTypeInt) { if (pInst->words.size() != 4) return diagnostic() << "Invalid OpTypeInt instruction"; types_[value] = {pInst->words[2], pInst->words[3] != 0, IdTypeClass::kScalarIntegerType}; - } else if (pInst->opcode == SpvOpTypeFloat) { + } else if (pInst->opcode == spv::Op::OpTypeFloat) { if (pInst->words.size() != 3) return diagnostic() << "Invalid OpTypeFloat instruction"; types_[value] = {pInst->words[2], false, IdTypeClass::kScalarFloatType}; diff --git a/3rdparty/spirv-tools/source/util/hex_float.h b/3rdparty/spirv-tools/source/util/hex_float.h index 06e3c5757..98353a4ad 100644 --- a/3rdparty/spirv-tools/source/util/hex_float.h +++ b/3rdparty/spirv-tools/source/util/hex_float.h @@ -896,6 +896,47 @@ ParseNormalFloat, HexFloatTraits>>( return is; } +namespace detail { + +// Returns a new value formed from 'value' by setting 'bit' that is the +// 'n'th most significant bit (where 0 is the most significant bit). +// If 'bit' is zero or 'n' is more than the number of bits in the integer +// type, then return the original value. +template +UINT_TYPE set_nth_most_significant_bit(UINT_TYPE value, UINT_TYPE bit, + UINT_TYPE n) { + constexpr UINT_TYPE max_position = std::numeric_limits::digits - 1; + if ((bit != 0) && (n <= max_position)) { + return static_cast(value | (bit << (max_position - n))); + } + return value; +} + +// Attempts to increment the argument. +// If it does not overflow, then increments the argument and returns true. +// If it would overflow, returns false. +template +bool saturated_inc(INT_TYPE& value) { + if (value == std::numeric_limits::max()) { + return false; + } + value++; + return true; +} + +// Attempts to decrement the argument. +// If it does not underflow, then decrements the argument and returns true. +// If it would overflow, returns false. +template +bool saturated_dec(INT_TYPE& value) { + if (value == std::numeric_limits::min()) { + return false; + } + value--; + return true; +} +} // namespace detail + // Reads a HexFloat from the given stream. // If the float is not encoded as a hex-float then it will be parsed // as a regular float. @@ -997,13 +1038,16 @@ std::istream& operator>>(std::istream& is, HexFloat& value) { if (bits_written) { // If we are here the bits represented belong in the fractional // part of the float, and we have to adjust the exponent accordingly. - fraction = static_cast( - fraction | - static_cast( - write_bit << (HF::top_bit_left_shift - fraction_index++))); - // TODO(dneto): Avoid overflow. Testing would require - // parameterization. - exponent = static_cast(exponent + 1); + fraction = detail::set_nth_most_significant_bit(fraction, write_bit, + fraction_index); + // Increment the fraction index. If the input has bizarrely many + // significant digits, then silently drop them. + detail::saturated_inc(fraction_index); + if (!detail::saturated_inc(exponent)) { + // Overflow failure + is.setstate(std::ios::failbit); + return is; + } } // Since this updated after setting fraction bits, this effectively // drops the leading 1 bit. @@ -1034,14 +1078,17 @@ std::istream& operator>>(std::istream& is, HexFloat& value) { // Handle modifying the exponent here this way we can handle // an arbitrary number of hex values without overflowing our // integer. - // TODO(dneto): Handle underflow. Testing would require extra - // parameterization. - exponent = static_cast(exponent - 1); + if (!detail::saturated_dec(exponent)) { + // Overflow failure + is.setstate(std::ios::failbit); + return is; + } } else { - fraction = static_cast( - fraction | - static_cast( - write_bit << (HF::top_bit_left_shift - fraction_index++))); + fraction = detail::set_nth_most_significant_bit(fraction, write_bit, + fraction_index); + // Increment the fraction index. If the input has bizarrely many + // significant digits, then silently drop them. + detail::saturated_inc(fraction_index); } } } else { diff --git a/3rdparty/spirv-tools/source/val/construct.cpp b/3rdparty/spirv-tools/source/val/construct.cpp index 52e61d555..1ca81d416 100644 --- a/3rdparty/spirv-tools/source/val/construct.cpp +++ b/3rdparty/spirv-tools/source/val/construct.cpp @@ -164,10 +164,12 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { // ii. The immediate dominator of |block|. auto NextBlock = [](const BasicBlock* block) -> const BasicBlock* { for (auto& use : block->label()->uses()) { - if ((use.first->opcode() == SpvOpLoopMerge || - use.first->opcode() == SpvOpSelectionMerge) && + if ((use.first->opcode() == spv::Op::OpLoopMerge || + use.first->opcode() == spv::Op::OpSelectionMerge) && use.second == 1 && - use.first->block()->structurally_dominates(*block)) { + use.first->block()->structurally_dominates(*block) && + // A header likely declared itself as its merge. + use.first->block() != block) { return use.first->block(); } } @@ -181,10 +183,10 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { auto terminator = block->terminator(); auto index = terminator - &_.ordered_instructions()[0]; auto merge_inst = &_.ordered_instructions()[index - 1]; - if (merge_inst->opcode() == SpvOpLoopMerge || - (header->terminator()->opcode() != SpvOpSwitch && - merge_inst->opcode() == SpvOpSelectionMerge && - terminator->opcode() == SpvOpSwitch)) { + if (merge_inst->opcode() == spv::Op::OpLoopMerge || + (header->terminator()->opcode() != spv::Op::OpSwitch && + merge_inst->opcode() == spv::Op::OpSelectionMerge && + terminator->opcode() == spv::Op::OpSwitch)) { auto merge_target = merge_inst->GetOperandAs(0u); auto merge_block = merge_inst->function()->GetBlock(merge_target).first; if (merge_block->structurally_dominates(*header)) { @@ -192,22 +194,22 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { continue; } - if ((!seen_switch || merge_inst->opcode() == SpvOpLoopMerge) && + if ((!seen_switch || merge_inst->opcode() == spv::Op::OpLoopMerge) && dest->id() == merge_target) { return true; - } else if (merge_inst->opcode() == SpvOpLoopMerge) { + } else if (merge_inst->opcode() == spv::Op::OpLoopMerge) { auto continue_target = merge_inst->GetOperandAs(1u); if (dest->id() == continue_target) { return true; } } - if (terminator->opcode() == SpvOpSwitch) { + if (terminator->opcode() == spv::Op::OpSwitch) { seen_switch = true; } // Hit an enclosing loop and didn't break or continue. - if (merge_inst->opcode() == SpvOpLoopMerge) return false; + if (merge_inst->opcode() == spv::Op::OpLoopMerge) return false; } block = NextBlock(block); diff --git a/3rdparty/spirv-tools/source/val/decoration.h b/3rdparty/spirv-tools/source/val/decoration.h index 4f53f2075..384cc5755 100644 --- a/3rdparty/spirv-tools/source/val/decoration.h +++ b/3rdparty/spirv-tools/source/val/decoration.h @@ -39,33 +39,33 @@ namespace val { // // Example 1: Decoration for an object with no parameters: // OpDecorate %obj Flat -// dec_type_ = SpvDecorationFlat +// dec_type_ = spv::Decoration::Flat // params_ = empty vector // struct_member_index_ = kInvalidMember // // Example 2: Decoration for an object with two parameters: // OpDecorate %obj LinkageAttributes "link" Import -// dec_type_ = SpvDecorationLinkageAttributes +// dec_type_ = spv::Decoration::LinkageAttributes // params_ = vector { link, Import } // struct_member_index_ = kInvalidMember // // Example 3: Decoration for a member of a structure with one parameter: // OpMemberDecorate %struct 2 Offset 2 -// dec_type_ = SpvDecorationOffset +// dec_type_ = spv::Decoration::Offset // params_ = vector { 2 } // struct_member_index_ = 2 // class Decoration { public: enum { kInvalidMember = -1 }; - Decoration(SpvDecoration t, + Decoration(spv::Decoration t, const std::vector& parameters = std::vector(), uint32_t member_index = kInvalidMember) : dec_type_(t), params_(parameters), struct_member_index_(member_index) {} void set_struct_member_index(uint32_t index) { struct_member_index_ = index; } int struct_member_index() const { return struct_member_index_; } - SpvDecoration dec_type() const { return dec_type_; } + spv::Decoration dec_type() const { return dec_type_; } std::vector& params() { return params_; } const std::vector& params() const { return params_; } @@ -84,7 +84,7 @@ class Decoration { } private: - SpvDecoration dec_type_; + spv::Decoration dec_type_; std::vector params_; // If the decoration applies to a member of a structure type, then the index diff --git a/3rdparty/spirv-tools/source/val/function.cpp b/3rdparty/spirv-tools/source/val/function.cpp index fc7ccd062..8b4423a1f 100644 --- a/3rdparty/spirv-tools/source/val/function.cpp +++ b/3rdparty/spirv-tools/source/val/function.cpp @@ -33,7 +33,7 @@ namespace val { static const uint32_t kInvalidId = 0x400000; Function::Function(uint32_t function_id, uint32_t result_type_id, - SpvFunctionControlMask function_control, + spv::FunctionControlMask function_control, uint32_t function_type_id) : id_(function_id), function_type_id_(function_type_id), @@ -371,10 +371,10 @@ int Function::GetBlockDepth(BasicBlock* bb) { return block_depth_[bb]; } -void Function::RegisterExecutionModelLimitation(SpvExecutionModel model, +void Function::RegisterExecutionModelLimitation(spv::ExecutionModel model, const std::string& message) { execution_model_limitations_.push_back( - [model, message](SpvExecutionModel in_model, std::string* out_message) { + [model, message](spv::ExecutionModel in_model, std::string* out_message) { if (model != in_model) { if (out_message) { *out_message = message; @@ -385,7 +385,7 @@ void Function::RegisterExecutionModelLimitation(SpvExecutionModel model, }); } -bool Function::IsCompatibleWithExecutionModel(SpvExecutionModel model, +bool Function::IsCompatibleWithExecutionModel(spv::ExecutionModel model, std::string* reason) const { bool return_value = true; std::stringstream ss_reason; diff --git a/3rdparty/spirv-tools/source/val/function.h b/3rdparty/spirv-tools/source/val/function.h index 126b1dc77..481179442 100644 --- a/3rdparty/spirv-tools/source/val/function.h +++ b/3rdparty/spirv-tools/source/val/function.h @@ -55,7 +55,8 @@ enum class FunctionDecl { class Function { public: Function(uint32_t id, uint32_t result_type_id, - SpvFunctionControlMask function_control, uint32_t function_type_id); + spv::FunctionControlMask function_control, + uint32_t function_type_id); /// Registers a function parameter in the current function /// @return Returns SPV_SUCCESS if the call was successful @@ -80,7 +81,8 @@ class Function { /// /// @return Returns SPV_SUCCESS if the call was successful spv_result_t RegisterBlockVariable(uint32_t type_id, uint32_t id, - SpvStorageClass storage, uint32_t init_id); + spv::StorageClass storage, + uint32_t init_id); /// Registers a loop merge construct in the function /// @@ -205,12 +207,12 @@ class Function { /// Registers execution model limitation such as "Feature X is only available /// with Execution Model Y". - void RegisterExecutionModelLimitation(SpvExecutionModel model, + void RegisterExecutionModelLimitation(spv::ExecutionModel model, const std::string& message); /// Registers execution model limitation with an |is_compatible| functor. void RegisterExecutionModelLimitation( - std::function is_compatible) { + std::function is_compatible) { execution_model_limitations_.push_back(is_compatible); } @@ -227,7 +229,7 @@ class Function { /// Returns true if the given execution model passes the limitations stored in /// execution_model_limitations_. Returns false otherwise and fills optional /// |reason| parameter. - bool IsCompatibleWithExecutionModel(SpvExecutionModel model, + bool IsCompatibleWithExecutionModel(spv::ExecutionModel model, std::string* reason = nullptr) const; // Inserts id to the set of functions called from this function. @@ -286,7 +288,7 @@ class Function { uint32_t result_type_id_; /// The control fo the function - SpvFunctionControlMask function_control_; + spv::FunctionControlMask function_control_; /// The type of declaration of each function FunctionDecl declaration_type_; @@ -381,7 +383,7 @@ class Function { /// function. The functor stored in the list return true if execution model /// is compatible, false otherwise. If the functor returns false, it can also /// optionally fill the string parameter with the reason for incompatibility. - std::list> + std::list> execution_model_limitations_; /// Stores limitations imposed by instructions used within the function. diff --git a/3rdparty/spirv-tools/source/val/instruction.h b/3rdparty/spirv-tools/source/val/instruction.h index 6d1f9f4f1..c524bd375 100644 --- a/3rdparty/spirv-tools/source/val/instruction.h +++ b/3rdparty/spirv-tools/source/val/instruction.h @@ -42,7 +42,7 @@ class Instruction { uint32_t id() const { return inst_.result_id; } uint32_t type_id() const { return inst_.type_id; } - SpvOp opcode() const { return static_cast(inst_.opcode); } + spv::Op opcode() const { return static_cast(inst_.opcode); } /// Returns the Function where the instruction was defined. nullptr if it was /// defined outside of a Function @@ -87,13 +87,13 @@ class Instruction { } bool IsNonSemantic() const { - return opcode() == SpvOp::SpvOpExtInst && + return opcode() == spv::Op::OpExtInst && spvExtInstIsNonSemantic(inst_.ext_inst_type); } /// True if this is an OpExtInst for debug info extension. bool IsDebugInfo() const { - return opcode() == SpvOp::SpvOpExtInst && + return opcode() == spv::Op::OpExtInst && spvExtInstIsDebugInfo(inst_.ext_inst_type); } diff --git a/3rdparty/spirv-tools/source/val/validate.cpp b/3rdparty/spirv-tools/source/val/validate.cpp index efb9225e6..52cb0d8bb 100644 --- a/3rdparty/spirv-tools/source/val/validate.cpp +++ b/3rdparty/spirv-tools/source/val/validate.cpp @@ -66,15 +66,15 @@ void RegisterExtension(ValidationState_t& _, // Parses the beginning of the module searching for OpExtension instructions. // Registers extensions if recognized. Returns SPV_REQUESTED_TERMINATION -// once an instruction which is not SpvOpCapability and SpvOpExtension is -// encountered. According to the SPIR-V spec extensions are declared after -// capabilities and before everything else. +// once an instruction which is not spv::Op::OpCapability and +// spv::Op::OpExtension is encountered. According to the SPIR-V spec extensions +// are declared after capabilities and before everything else. spv_result_t ProcessExtensions(void* user_data, const spv_parsed_instruction_t* inst) { - const SpvOp opcode = static_cast(inst->opcode); - if (opcode == SpvOpCapability) return SPV_SUCCESS; + const spv::Op opcode = static_cast(inst->opcode); + if (opcode == spv::Op::OpCapability) return SPV_SUCCESS; - if (opcode == SpvOpExtension) { + if (opcode == spv::Op::OpExtension) { ValidationState_t& _ = *(reinterpret_cast(user_data)); RegisterExtension(_, inst); return SPV_SUCCESS; @@ -123,7 +123,7 @@ spv_result_t ValidateEntryPoints(ValidationState_t& _) { _.ComputeFunctionToEntryPointMapping(); _.ComputeRecursiveEntryPoints(); - if (_.entry_points().empty() && !_.HasCapability(SpvCapabilityLinkage)) { + if (_.entry_points().empty() && !_.HasCapability(spv::Capability::Linkage)) { return _.diag(SPV_ERROR_INVALID_BINARY, nullptr) << "No OpEntryPoint instruction was found. This is only allowed if " "the Linkage capability is being used."; @@ -218,9 +218,9 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( // able to, briefly, de-const the instruction. Instruction* inst = const_cast(&instruction); - if (inst->opcode() == SpvOpEntryPoint) { + if (inst->opcode() == spv::Op::OpEntryPoint) { const auto entry_point = inst->GetOperandAs(1); - const auto execution_model = inst->GetOperandAs(0); + const auto execution_model = inst->GetOperandAs(0); const std::string desc_name = inst->GetOperandAs(2); ValidationState_t::EntryPointDescription desc; @@ -236,7 +236,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (visited_entry_points.size() > 0) { for (const Instruction* check_inst : visited_entry_points) { const auto check_execution_model = - check_inst->GetOperandAs(0); + check_inst->GetOperandAs(0); const std::string check_name = check_inst->GetOperandAs(2); @@ -250,12 +250,12 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( } visited_entry_points.push_back(inst); - has_mask_task_nv |= (execution_model == SpvExecutionModelTaskNV || - execution_model == SpvExecutionModelMeshNV); - has_mask_task_ext |= (execution_model == SpvExecutionModelTaskEXT || - execution_model == SpvExecutionModelMeshEXT); + has_mask_task_nv |= (execution_model == spv::ExecutionModel::TaskNV || + execution_model == spv::ExecutionModel::MeshNV); + has_mask_task_ext |= (execution_model == spv::ExecutionModel::TaskEXT || + execution_model == spv::ExecutionModel::MeshEXT); } - if (inst->opcode() == SpvOpFunctionCall) { + if (inst->opcode() == spv::Op::OpFunctionCall) { if (!vstate->in_function_body()) { return vstate->diag(SPV_ERROR_INVALID_LAYOUT, &instruction) << "A FunctionCall must happen within a function body."; @@ -286,7 +286,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( { Instruction* inst = const_cast(&instruction); vstate->RegisterInstruction(inst); - if (inst->opcode() == SpvOpTypeForwardPointer) { + if (inst->opcode() == spv::Op::OpTypeForwardPointer) { vstate->RegisterForwardPointer(inst->GetOperandAs(0)); } } @@ -300,7 +300,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) << "Missing OpFunctionEnd at end of module."; - if (vstate->HasCapability(SpvCapabilityBindlessTextureNV) && + if (vstate->HasCapability(spv::Capability::BindlessTextureNV) && !vstate->has_samplerimage_variable_address_mode_specified()) return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) << "Missing required OpSamplerImageAddressingModeNV instruction."; @@ -365,11 +365,13 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (auto error = LiteralsPass(*vstate, &instruction)) return error; if (auto error = RayQueryPass(*vstate, &instruction)) return error; if (auto error = RayTracingPass(*vstate, &instruction)) return error; + if (auto error = RayReorderNVPass(*vstate, &instruction)) return error; if (auto error = MeshShadingPass(*vstate, &instruction)) return error; } - // Validate the preconditions involving adjacent instructions. e.g. SpvOpPhi - // must only be preceded by SpvOpLabel, SpvOpPhi, or SpvOpLine. + // Validate the preconditions involving adjacent instructions. e.g. + // spv::Op::OpPhi must only be preceded by spv::Op::OpLabel, spv::Op::OpPhi, + // or spv::Op::OpLine. if (auto error = ValidateAdjacency(*vstate)) return error; if (auto error = ValidateEntryPoints(*vstate)) return error; diff --git a/3rdparty/spirv-tools/source/val/validate.h b/3rdparty/spirv-tools/source/val/validate.h index 4b953ba31..898743859 100644 --- a/3rdparty/spirv-tools/source/val/validate.h +++ b/3rdparty/spirv-tools/source/val/validate.h @@ -69,8 +69,8 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _); /// instructions. /// /// This function will iterate over all instructions and check for any required -/// predecessor and/or successor instructions. e.g. SpvOpPhi must only be -/// preceded by SpvOpLabel, SpvOpPhi, or SpvOpLine. +/// predecessor and/or successor instructions. e.g. spv::Op::OpPhi must only be +/// preceded by spv::Op::OpLabel, spv::Op::OpPhi, or spv::Op::OpLine. /// /// @param[in] _ the validation state of the module /// @@ -203,6 +203,9 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst); /// Validates correctness of ray tracing instructions. spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst); +/// Validates correctness of shader execution reorder instructions. +spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst); + /// Validates correctness of mesh shading instructions. spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst); diff --git a/3rdparty/spirv-tools/source/val/validate_adjacency.cpp b/3rdparty/spirv-tools/source/val/validate_adjacency.cpp index 8e6c373ea..50c2e92ae 100644 --- a/3rdparty/spirv-tools/source/val/validate_adjacency.cpp +++ b/3rdparty/spirv-tools/source/val/validate_adjacency.cpp @@ -46,15 +46,15 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { for (size_t i = 0; i < instructions.size(); ++i) { const auto& inst = instructions[i]; switch (inst.opcode()) { - case SpvOpFunction: - case SpvOpFunctionParameter: + case spv::Op::OpFunction: + case spv::Op::OpFunctionParameter: adjacency_status = IN_NEW_FUNCTION; break; - case SpvOpLabel: + case spv::Op::OpLabel: adjacency_status = adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID; break; - case SpvOpExtInst: + case spv::Op::OpExtInst: // If it is a debug info instruction, we do not change the status to // allow debug info instructions before OpVariable in a function. // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need @@ -67,7 +67,7 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { adjacency_status = PHI_AND_VAR_INVALID; } break; - case SpvOpPhi: + case spv::Op::OpPhi: if (adjacency_status != PHI_VALID) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "OpPhi must appear within a non-entry block before all " @@ -75,15 +75,15 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { << "(except for OpLine, which can be mixed with OpPhi)."; } break; - case SpvOpLine: - case SpvOpNoLine: + case spv::Op::OpLine: + case spv::Op::OpNoLine: break; - case SpvOpLoopMerge: + case spv::Op::OpLoopMerge: adjacency_status = PHI_AND_VAR_INVALID; if (i != (instructions.size() - 1)) { switch (instructions[i + 1].opcode()) { - case SpvOpBranch: - case SpvOpBranchConditional: + case spv::Op::OpBranch: + case spv::Op::OpBranchConditional: break; default: return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -94,12 +94,12 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { } } break; - case SpvOpSelectionMerge: + case spv::Op::OpSelectionMerge: adjacency_status = PHI_AND_VAR_INVALID; if (i != (instructions.size() - 1)) { switch (instructions[i + 1].opcode()) { - case SpvOpBranchConditional: - case SpvOpSwitch: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: break; default: return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -110,8 +110,9 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { } } break; - case SpvOpVariable: - if (inst.GetOperandAs(2) == SpvStorageClassFunction && + case spv::Op::OpVariable: + if (inst.GetOperandAs(2) == + spv::StorageClass::Function && adjacency_status != IN_ENTRY_BLOCK) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "All OpVariable instructions in a function must be the " diff --git a/3rdparty/spirv-tools/source/val/validate_annotation.cpp b/3rdparty/spirv-tools/source/val/validate_annotation.cpp index 21f999b09..bef753d9c 100644 --- a/3rdparty/spirv-tools/source/val/validate_annotation.cpp +++ b/3rdparty/spirv-tools/source/val/validate_annotation.cpp @@ -24,12 +24,12 @@ namespace { // Returns true if the decoration takes ID parameters. // TODO(dneto): This can be generated from the grammar. -bool DecorationTakesIdParameters(SpvDecoration type) { +bool DecorationTakesIdParameters(spv::Decoration type) { switch (type) { - case SpvDecorationUniformId: - case SpvDecorationAlignmentId: - case SpvDecorationMaxByteOffsetId: - case SpvDecorationHlslCounterBufferGOOGLE: + case spv::Decoration::UniformId: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffsetId: + case spv::Decoration::HlslCounterBufferGOOGLE: return true; default: break; @@ -37,14 +37,14 @@ bool DecorationTakesIdParameters(SpvDecoration type) { return false; } -bool IsMemberDecorationOnly(SpvDecoration dec) { +bool IsMemberDecorationOnly(spv::Decoration dec) { switch (dec) { - case SpvDecorationRowMajor: - case SpvDecorationColMajor: - case SpvDecorationMatrixStride: + case spv::Decoration::RowMajor: + case spv::Decoration::ColMajor: + case spv::Decoration::MatrixStride: // SPIR-V spec bug? Offset is generated on variables when dealing with // transform feedback. - // case SpvDecorationOffset: + // case spv::Decoration::Offset: return true; default: break; @@ -52,42 +52,42 @@ bool IsMemberDecorationOnly(SpvDecoration dec) { return false; } -bool IsNotMemberDecoration(SpvDecoration dec) { +bool IsNotMemberDecoration(spv::Decoration dec) { switch (dec) { - case SpvDecorationSpecId: - case SpvDecorationBlock: - case SpvDecorationBufferBlock: - case SpvDecorationArrayStride: - case SpvDecorationGLSLShared: - case SpvDecorationGLSLPacked: - case SpvDecorationCPacked: + case spv::Decoration::SpecId: + case spv::Decoration::Block: + case spv::Decoration::BufferBlock: + case spv::Decoration::ArrayStride: + case spv::Decoration::GLSLShared: + case spv::Decoration::GLSLPacked: + case spv::Decoration::CPacked: // TODO: https://github.com/KhronosGroup/glslang/issues/703: // glslang applies Restrict to structure members. - // case SpvDecorationRestrict: - case SpvDecorationAliased: - case SpvDecorationConstant: - case SpvDecorationUniform: - case SpvDecorationUniformId: - case SpvDecorationSaturatedConversion: - case SpvDecorationIndex: - case SpvDecorationBinding: - case SpvDecorationDescriptorSet: - case SpvDecorationFuncParamAttr: - case SpvDecorationFPRoundingMode: - case SpvDecorationFPFastMathMode: - case SpvDecorationLinkageAttributes: - case SpvDecorationNoContraction: - case SpvDecorationInputAttachmentIndex: - case SpvDecorationAlignment: - case SpvDecorationMaxByteOffset: - case SpvDecorationAlignmentId: - case SpvDecorationMaxByteOffsetId: - case SpvDecorationNoSignedWrap: - case SpvDecorationNoUnsignedWrap: - case SpvDecorationNonUniform: - case SpvDecorationRestrictPointer: - case SpvDecorationAliasedPointer: - case SpvDecorationCounterBuffer: + // case spv::Decoration::Restrict: + case spv::Decoration::Aliased: + case spv::Decoration::Constant: + case spv::Decoration::Uniform: + case spv::Decoration::UniformId: + case spv::Decoration::SaturatedConversion: + case spv::Decoration::Index: + case spv::Decoration::Binding: + case spv::Decoration::DescriptorSet: + case spv::Decoration::FuncParamAttr: + case spv::Decoration::FPRoundingMode: + case spv::Decoration::FPFastMathMode: + case spv::Decoration::LinkageAttributes: + case spv::Decoration::NoContraction: + case spv::Decoration::InputAttachmentIndex: + case spv::Decoration::Alignment: + case spv::Decoration::MaxByteOffset: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffsetId: + case spv::Decoration::NoSignedWrap: + case spv::Decoration::NoUnsignedWrap: + case spv::Decoration::NonUniform: + case spv::Decoration::RestrictPointer: + case spv::Decoration::AliasedPointer: + case spv::Decoration::CounterBuffer: return true; default: break; @@ -95,7 +95,7 @@ bool IsNotMemberDecoration(SpvDecoration dec) { return false; } -spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec, +spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, const Instruction* inst, const Instruction* target) { auto fail = [&_, dec, inst, target](uint32_t vuid) -> DiagnosticStream { @@ -106,76 +106,76 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec, return ds; }; switch (dec) { - case SpvDecorationSpecId: + case spv::Decoration::SpecId: if (!spvOpcodeIsScalarSpecConstant(target->opcode())) { return fail(0) << "must be a scalar specialization constant"; } break; - case SpvDecorationBlock: - case SpvDecorationBufferBlock: - case SpvDecorationGLSLShared: - case SpvDecorationGLSLPacked: - case SpvDecorationCPacked: - if (target->opcode() != SpvOpTypeStruct) { + case spv::Decoration::Block: + case spv::Decoration::BufferBlock: + case spv::Decoration::GLSLShared: + case spv::Decoration::GLSLPacked: + case spv::Decoration::CPacked: + if (target->opcode() != spv::Op::OpTypeStruct) { return fail(0) << "must be a structure type"; } break; - case SpvDecorationArrayStride: - if (target->opcode() != SpvOpTypeArray && - target->opcode() != SpvOpTypeRuntimeArray && - target->opcode() != SpvOpTypePointer) { + case spv::Decoration::ArrayStride: + if (target->opcode() != spv::Op::OpTypeArray && + target->opcode() != spv::Op::OpTypeRuntimeArray && + target->opcode() != spv::Op::OpTypePointer) { return fail(0) << "must be an array or pointer type"; } break; - case SpvDecorationBuiltIn: - if (target->opcode() != SpvOpVariable && + case spv::Decoration::BuiltIn: + if (target->opcode() != spv::Op::OpVariable && !spvOpcodeIsConstant(target->opcode())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "BuiltIns can only target variables, structure members or " "constants"; } - if (_.HasCapability(SpvCapabilityShader) && - inst->GetOperandAs(2) == SpvBuiltInWorkgroupSize) { + if (_.HasCapability(spv::Capability::Shader) && + inst->GetOperandAs(2) == spv::BuiltIn::WorkgroupSize) { if (!spvOpcodeIsConstant(target->opcode())) { return fail(0) << "must be a constant for WorkgroupSize"; } - } else if (target->opcode() != SpvOpVariable) { + } else if (target->opcode() != spv::Op::OpVariable) { return fail(0) << "must be a variable"; } break; - case SpvDecorationNoPerspective: - case SpvDecorationFlat: - case SpvDecorationPatch: - case SpvDecorationCentroid: - case SpvDecorationSample: - case SpvDecorationRestrict: - case SpvDecorationAliased: - case SpvDecorationVolatile: - case SpvDecorationCoherent: - case SpvDecorationNonWritable: - case SpvDecorationNonReadable: - case SpvDecorationXfbBuffer: - case SpvDecorationXfbStride: - case SpvDecorationComponent: - case SpvDecorationStream: - case SpvDecorationRestrictPointer: - case SpvDecorationAliasedPointer: - if (target->opcode() != SpvOpVariable && - target->opcode() != SpvOpFunctionParameter) { + case spv::Decoration::NoPerspective: + case spv::Decoration::Flat: + case spv::Decoration::Patch: + case spv::Decoration::Centroid: + case spv::Decoration::Sample: + case spv::Decoration::Restrict: + case spv::Decoration::Aliased: + case spv::Decoration::Volatile: + case spv::Decoration::Coherent: + case spv::Decoration::NonWritable: + case spv::Decoration::NonReadable: + case spv::Decoration::XfbBuffer: + case spv::Decoration::XfbStride: + case spv::Decoration::Component: + case spv::Decoration::Stream: + case spv::Decoration::RestrictPointer: + case spv::Decoration::AliasedPointer: + if (target->opcode() != spv::Op::OpVariable && + target->opcode() != spv::Op::OpFunctionParameter) { return fail(0) << "must be a memory object declaration"; } - if (_.GetIdOpcode(target->type_id()) != SpvOpTypePointer) { + if (_.GetIdOpcode(target->type_id()) != spv::Op::OpTypePointer) { return fail(0) << "must be a pointer type"; } break; - case SpvDecorationInvariant: - case SpvDecorationConstant: - case SpvDecorationLocation: - case SpvDecorationIndex: - case SpvDecorationBinding: - case SpvDecorationDescriptorSet: - case SpvDecorationInputAttachmentIndex: - if (target->opcode() != SpvOpVariable) { + case spv::Decoration::Invariant: + case spv::Decoration::Constant: + case spv::Decoration::Location: + case spv::Decoration::Index: + case spv::Decoration::Binding: + case spv::Decoration::DescriptorSet: + case spv::Decoration::InputAttachmentIndex: + if (target->opcode() != spv::Op::OpVariable) { return fail(0) << "must be a variable"; } break; @@ -185,57 +185,58 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec, if (spvIsVulkanEnv(_.context()->target_env)) { // The following were all checked as pointer types above. - SpvStorageClass sc = SpvStorageClassUniform; + spv::StorageClass sc = spv::StorageClass::Uniform; const auto type = _.FindDef(target->type_id()); if (type && type->operands().size() > 2) { - sc = type->GetOperandAs(1); + sc = type->GetOperandAs(1); } switch (dec) { - case SpvDecorationLocation: - case SpvDecorationComponent: + case spv::Decoration::Location: + case spv::Decoration::Component: // Location is used for input, output and ray tracing stages. - if (sc != SpvStorageClassInput && sc != SpvStorageClassOutput && - sc != SpvStorageClassRayPayloadKHR && - sc != SpvStorageClassIncomingRayPayloadKHR && - sc != SpvStorageClassHitAttributeKHR && - sc != SpvStorageClassCallableDataKHR && - sc != SpvStorageClassIncomingCallableDataKHR && - sc != SpvStorageClassShaderRecordBufferKHR) { + if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output && + sc != spv::StorageClass::RayPayloadKHR && + sc != spv::StorageClass::IncomingRayPayloadKHR && + sc != spv::StorageClass::HitAttributeKHR && + sc != spv::StorageClass::CallableDataKHR && + sc != spv::StorageClass::IncomingCallableDataKHR && + sc != spv::StorageClass::ShaderRecordBufferKHR && + sc != spv::StorageClass::HitObjectAttributeNV) { return _.diag(SPV_ERROR_INVALID_ID, target) << _.VkErrorID(6672) << _.SpvDecorationString(dec) << " decoration must not be applied to this storage class"; } break; - case SpvDecorationIndex: + case spv::Decoration::Index: // Langauge from SPIR-V definition of Index - if (sc != SpvStorageClassOutput) { + if (sc != spv::StorageClass::Output) { return fail(0) << "must be in the Output storage class"; } break; - case SpvDecorationBinding: - case SpvDecorationDescriptorSet: - if (sc != SpvStorageClassStorageBuffer && - sc != SpvStorageClassUniform && - sc != SpvStorageClassUniformConstant) { + case spv::Decoration::Binding: + case spv::Decoration::DescriptorSet: + if (sc != spv::StorageClass::StorageBuffer && + sc != spv::StorageClass::Uniform && + sc != spv::StorageClass::UniformConstant) { return fail(6491) << "must be in the StorageBuffer, Uniform, or " "UniformConstant storage class"; } break; - case SpvDecorationInputAttachmentIndex: - if (sc != SpvStorageClassUniformConstant) { + case spv::Decoration::InputAttachmentIndex: + if (sc != spv::StorageClass::UniformConstant) { return fail(6678) << "must be in the UniformConstant storage class"; } break; - case SpvDecorationFlat: - case SpvDecorationNoPerspective: - case SpvDecorationCentroid: - case SpvDecorationSample: - if (sc != SpvStorageClassInput && sc != SpvStorageClassOutput) { + case spv::Decoration::Flat: + case spv::Decoration::NoPerspective: + case spv::Decoration::Centroid: + case spv::Decoration::Sample: + if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output) { return fail(4670) << "storage class must be Input or Output"; } break; - case SpvDecorationPerVertexKHR: - if (sc != SpvStorageClassInput) { + case spv::Decoration::PerVertexKHR: + if (sc != spv::StorageClass::Input) { return fail(6777) << "storage class must be Input"; } break; @@ -247,7 +248,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec, } spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { - const auto decoration = inst->GetOperandAs(1); + const auto decoration = inst->GetOperandAs(1); const auto target_id = inst->GetOperandAs(0); const auto target = _.FindDef(target_id); if (!target) { @@ -255,8 +256,8 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env)) { - if ((decoration == SpvDecorationGLSLShared) || - (decoration == SpvDecorationGLSLPacked)) { + if ((decoration == spv::Decoration::GLSLShared) || + (decoration == spv::Decoration::GLSLPacked)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4669) << "OpDecorate decoration '" << _.SpvDecorationString(decoration) @@ -270,7 +271,7 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { "OpDecorateId"; } - if (target->opcode() != SpvOpDecorationGroup) { + if (target->opcode() != spv::Op::OpDecorationGroup) { if (IsMemberDecorationOnly(decoration)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.SpvDecorationString(decoration) @@ -287,7 +288,7 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { } spv_result_t ValidateDecorateId(ValidationState_t& _, const Instruction* inst) { - const auto decoration = inst->GetOperandAs(1); + const auto decoration = inst->GetOperandAs(1); if (!DecorationTakesIdParameters(decoration)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Decorations that don't take ID parameters may not be used with " @@ -306,7 +307,7 @@ spv_result_t ValidateMemberDecorate(ValidationState_t& _, const Instruction* inst) { const auto struct_type_id = inst->GetOperandAs(0); const auto struct_type = _.FindDef(struct_type_id); - if (!struct_type || SpvOpTypeStruct != struct_type->opcode()) { + if (!struct_type || spv::Op::OpTypeStruct != struct_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpMemberDecorate Structure type " << _.getIdName(struct_type_id) << " is not a struct type."; @@ -323,7 +324,7 @@ spv_result_t ValidateMemberDecorate(ValidationState_t& _, << " members. Largest valid index is " << member_count - 1 << "."; } - const auto decoration = inst->GetOperandAs(2); + const auto decoration = inst->GetOperandAs(2); if (IsNotMemberDecoration(decoration)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.SpvDecorationString(decoration) @@ -339,10 +340,11 @@ spv_result_t ValidateDecorationGroup(ValidationState_t& _, const auto decoration_group = _.FindDef(decoration_group_id); for (auto pair : decoration_group->uses()) { auto use = pair.first; - if (use->opcode() != SpvOpDecorate && use->opcode() != SpvOpGroupDecorate && - use->opcode() != SpvOpGroupMemberDecorate && - use->opcode() != SpvOpName && use->opcode() != SpvOpDecorateId && - !use->IsNonSemantic()) { + if (use->opcode() != spv::Op::OpDecorate && + use->opcode() != spv::Op::OpGroupDecorate && + use->opcode() != spv::Op::OpGroupMemberDecorate && + use->opcode() != spv::Op::OpName && + use->opcode() != spv::Op::OpDecorateId && !use->IsNonSemantic()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result id of OpDecorationGroup can only " << "be targeted by OpName, OpGroupDecorate, " @@ -356,7 +358,8 @@ spv_result_t ValidateGroupDecorate(ValidationState_t& _, const Instruction* inst) { const auto decoration_group_id = inst->GetOperandAs(0); auto decoration_group = _.FindDef(decoration_group_id); - if (!decoration_group || SpvOpDecorationGroup != decoration_group->opcode()) { + if (!decoration_group || + spv::Op::OpDecorationGroup != decoration_group->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupDecorate Decoration group " << _.getIdName(decoration_group_id) << " is not a decoration group."; @@ -364,7 +367,7 @@ spv_result_t ValidateGroupDecorate(ValidationState_t& _, for (unsigned i = 1; i < inst->operands().size(); ++i) { auto target_id = inst->GetOperandAs(i); auto target = _.FindDef(target_id); - if (!target || target->opcode() == SpvOpDecorationGroup) { + if (!target || target->opcode() == spv::Op::OpDecorationGroup) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupDecorate may not target OpDecorationGroup " << _.getIdName(target_id); @@ -377,7 +380,8 @@ spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, const Instruction* inst) { const auto decoration_group_id = inst->GetOperandAs(0); const auto decoration_group = _.FindDef(decoration_group_id); - if (!decoration_group || SpvOpDecorationGroup != decoration_group->opcode()) { + if (!decoration_group || + spv::Op::OpDecorationGroup != decoration_group->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupMemberDecorate Decoration group " << _.getIdName(decoration_group_id) << " is not a decoration group."; @@ -388,7 +392,7 @@ spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, const uint32_t struct_id = inst->GetOperandAs(i); const uint32_t index = inst->GetOperandAs(i + 1); auto struct_instr = _.FindDef(struct_id); - if (!struct_instr || SpvOpTypeStruct != struct_instr->opcode()) { + if (!struct_instr || spv::Op::OpTypeStruct != struct_instr->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupMemberDecorate Structure type " << _.getIdName(struct_id) << " is not a struct type."; @@ -413,10 +417,11 @@ spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, spv_result_t RegisterDecorations(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpDecorate: - case SpvOpDecorateId: { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: { const uint32_t target_id = inst->word(1); - const SpvDecoration dec_type = static_cast(inst->word(2)); + const spv::Decoration dec_type = + static_cast(inst->word(2)); std::vector dec_params; if (inst->words().size() > 3) { dec_params.insert(dec_params.end(), inst->words().begin() + 3, @@ -425,10 +430,11 @@ spv_result_t RegisterDecorations(ValidationState_t& _, _.RegisterDecorationForId(target_id, Decoration(dec_type, dec_params)); break; } - case SpvOpMemberDecorate: { + case spv::Op::OpMemberDecorate: { const uint32_t struct_id = inst->word(1); const uint32_t index = inst->word(2); - const SpvDecoration dec_type = static_cast(inst->word(3)); + const spv::Decoration dec_type = + static_cast(inst->word(3)); std::vector dec_params; if (inst->words().size() > 4) { dec_params.insert(dec_params.end(), inst->words().begin() + 4, @@ -438,12 +444,12 @@ spv_result_t RegisterDecorations(ValidationState_t& _, Decoration(dec_type, dec_params, index)); break; } - case SpvOpDecorationGroup: { + case spv::Op::OpDecorationGroup: { // We don't need to do anything right now. Assigning decorations to groups // will be taken care of via OpGroupDecorate. break; } - case SpvOpGroupDecorate: { + case spv::Op::OpGroupDecorate: { // Word 1 is the group . All subsequent words are target s that // are going to be decorated with the decorations. const uint32_t decoration_group_id = inst->word(1); @@ -456,7 +462,7 @@ spv_result_t RegisterDecorations(ValidationState_t& _, } break; } - case SpvOpGroupMemberDecorate: { + case spv::Op::OpGroupMemberDecorate: { // Word 1 is the Decoration Group followed by (struct,literal) // pairs. All decorations of the group should be applied to all the struct // members that are specified in the instructions. @@ -486,24 +492,24 @@ spv_result_t RegisterDecorations(ValidationState_t& _, spv_result_t AnnotationPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpDecorate: + case spv::Op::OpDecorate: if (auto error = ValidateDecorate(_, inst)) return error; break; - case SpvOpDecorateId: + case spv::Op::OpDecorateId: if (auto error = ValidateDecorateId(_, inst)) return error; break; - // TODO(dneto): SpvOpDecorateStringGOOGLE + // TODO(dneto): spv::Op::OpDecorateStringGOOGLE // See https://github.com/KhronosGroup/SPIRV-Tools/issues/2253 - case SpvOpMemberDecorate: + case spv::Op::OpMemberDecorate: if (auto error = ValidateMemberDecorate(_, inst)) return error; break; - case SpvOpDecorationGroup: + case spv::Op::OpDecorationGroup: if (auto error = ValidateDecorationGroup(_, inst)) return error; break; - case SpvOpGroupDecorate: + case spv::Op::OpGroupDecorate: if (auto error = ValidateGroupDecorate(_, inst)) return error; break; - case SpvOpGroupMemberDecorate: + case spv::Op::OpGroupMemberDecorate: if (auto error = ValidateGroupMemberDecorate(_, inst)) return error; break; default: diff --git a/3rdparty/spirv-tools/source/val/validate_arithmetics.cpp b/3rdparty/spirv-tools/source/val/validate_arithmetics.cpp index bae9b5dca..a082eebc9 100644 --- a/3rdparty/spirv-tools/source/val/validate_arithmetics.cpp +++ b/3rdparty/spirv-tools/source/val/validate_arithmetics.cpp @@ -28,19 +28,20 @@ namespace val { // Validates correctness of arithmetic instructions. spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpFAdd: - case SpvOpFSub: - case SpvOpFMul: - case SpvOpFDiv: - case SpvOpFRem: - case SpvOpFMod: - case SpvOpFNegate: { + case spv::Op::OpFAdd: + case spv::Op::OpFSub: + case spv::Op::OpFMul: + case spv::Op::OpFDiv: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpFNegate: { bool supportsCoopMat = - (opcode != SpvOpFMul && opcode != SpvOpFRem && opcode != SpvOpFMod); + (opcode != spv::Op::OpFMul && opcode != spv::Op::OpFRem && + opcode != spv::Op::OpFMod); if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type) && !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type))) @@ -59,9 +60,9 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpUDiv: - case SpvOpUMod: { - bool supportsCoopMat = (opcode == SpvOpUDiv); + case spv::Op::OpUDiv: + case spv::Op::OpUMod: { + bool supportsCoopMat = (opcode == spv::Op::OpUDiv); if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type) && !(supportsCoopMat && @@ -81,15 +82,16 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpISub: - case SpvOpIAdd: - case SpvOpIMul: - case SpvOpSDiv: - case SpvOpSMod: - case SpvOpSRem: - case SpvOpSNegate: { + case spv::Op::OpISub: + case spv::Op::OpIAdd: + case spv::Op::OpIMul: + case spv::Op::OpSDiv: + case spv::Op::OpSMod: + case spv::Op::OpSRem: + case spv::Op::OpSNegate: { bool supportsCoopMat = - (opcode != SpvOpIMul && opcode != SpvOpSRem && opcode != SpvOpSMod); + (opcode != spv::Op::OpIMul && opcode != spv::Op::OpSRem && + opcode != spv::Op::OpSMod); if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type))) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -125,7 +127,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpDot: { + case spv::Op::OpDot: { if (!_.IsFloatScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected float scalar type as Result Type: " @@ -162,7 +164,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpVectorTimesScalar: { + case spv::Op::OpVectorTimesScalar: { if (!_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected float vector type as Result Type: " @@ -185,7 +187,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpMatrixTimesScalar: { + case spv::Op::OpMatrixTimesScalar: { if (!_.IsFloatMatrixType(result_type) && !_.IsCooperativeMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -209,7 +211,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpVectorTimesMatrix: { + case spv::Op::OpVectorTimesMatrix: { const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2); const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 3); @@ -259,7 +261,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpMatrixTimesVector: { + case spv::Op::OpMatrixTimesVector: { const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2); const uint32_t vector_type_id = _.GetOperandTypeId(inst, 3); @@ -303,7 +305,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpMatrixTimesMatrix: { + case spv::Op::OpMatrixTimesMatrix: { const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); @@ -369,7 +371,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpOuterProduct: { + case spv::Op::OpOuterProduct: { const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); @@ -407,10 +409,10 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpIAddCarry: - case SpvOpISubBorrow: - case SpvOpUMulExtended: - case SpvOpSMulExtended: { + case spv::Op::OpIAddCarry: + case spv::Op::OpISubBorrow: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: { std::vector result_types; if (!_.GetStructMemberTypes(result_type, &result_types)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -422,7 +424,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type struct to have two members: " << spvOpcodeString(opcode); - if (opcode == SpvOpSMulExtended) { + if (opcode == spv::Op::OpSMulExtended) { if (!_.IsIntScalarType(result_types[0]) && !_.IsIntVectorType(result_types[0])) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -453,7 +455,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpCooperativeMatrixMulAddNV: { + case spv::Op::OpCooperativeMatrixMulAddNV: { const uint32_t D_type_id = _.GetOperandTypeId(inst, 1); const uint32_t A_type_id = _.GetOperandTypeId(inst, 2); const uint32_t B_type_id = _.GetOperandTypeId(inst, 3); diff --git a/3rdparty/spirv-tools/source/val/validate_atomics.cpp b/3rdparty/spirv-tools/source/val/validate_atomics.cpp index bf565c310..d6b094c4a 100644 --- a/3rdparty/spirv-tools/source/val/validate_atomics.cpp +++ b/3rdparty/spirv-tools/source/val/validate_atomics.cpp @@ -29,18 +29,18 @@ namespace { -bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) { +bool IsStorageClassAllowedByUniversalRules(spv::StorageClass storage_class) { switch (storage_class) { - case SpvStorageClassUniform: - case SpvStorageClassStorageBuffer: - case SpvStorageClassWorkgroup: - case SpvStorageClassCrossWorkgroup: - case SpvStorageClassGeneric: - case SpvStorageClassAtomicCounter: - case SpvStorageClassImage: - case SpvStorageClassFunction: - case SpvStorageClassPhysicalStorageBuffer: - case SpvStorageClassTaskPayloadWorkgroupEXT: + case spv::StorageClass::Uniform: + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::Workgroup: + case spv::StorageClass::CrossWorkgroup: + case spv::StorageClass::Generic: + case spv::StorageClass::AtomicCounter: + case spv::StorageClass::Image: + case spv::StorageClass::Function: + case spv::StorageClass::PhysicalStorageBuffer: + case spv::StorageClass::TaskPayloadWorkgroupEXT: return true; break; default: @@ -48,10 +48,10 @@ bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) { } } -bool HasReturnType(uint32_t opcode) { +bool HasReturnType(spv::Op opcode) { switch (opcode) { - case SpvOpAtomicStore: - case SpvOpAtomicFlagClear: + case spv::Op::OpAtomicStore: + case spv::Op::OpAtomicFlagClear: return false; break; default: @@ -59,11 +59,11 @@ bool HasReturnType(uint32_t opcode) { } } -bool HasOnlyFloatReturnType(uint32_t opcode) { +bool HasOnlyFloatReturnType(spv::Op opcode) { switch (opcode) { - case SpvOpAtomicFAddEXT: - case SpvOpAtomicFMinEXT: - case SpvOpAtomicFMaxEXT: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicFMaxEXT: return true; break; default: @@ -71,21 +71,21 @@ bool HasOnlyFloatReturnType(uint32_t opcode) { } } -bool HasOnlyIntReturnType(uint32_t opcode) { +bool HasOnlyIntReturnType(spv::Op opcode) { switch (opcode) { - case SpvOpAtomicCompareExchange: - case SpvOpAtomicCompareExchangeWeak: - case SpvOpAtomicIIncrement: - case SpvOpAtomicIDecrement: - case SpvOpAtomicIAdd: - case SpvOpAtomicISub: - case SpvOpAtomicSMin: - case SpvOpAtomicUMin: - case SpvOpAtomicSMax: - case SpvOpAtomicUMax: - case SpvOpAtomicAnd: - case SpvOpAtomicOr: - case SpvOpAtomicXor: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: return true; break; default: @@ -93,10 +93,10 @@ bool HasOnlyIntReturnType(uint32_t opcode) { } } -bool HasIntOrFloatReturnType(uint32_t opcode) { +bool HasIntOrFloatReturnType(spv::Op opcode) { switch (opcode) { - case SpvOpAtomicLoad: - case SpvOpAtomicExchange: + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicExchange: return true; break; default: @@ -104,9 +104,9 @@ bool HasIntOrFloatReturnType(uint32_t opcode) { } } -bool HasOnlyBoolReturnType(uint32_t opcode) { +bool HasOnlyBoolReturnType(spv::Op opcode) { switch (opcode) { - case SpvOpAtomicFlagTestAndSet: + case spv::Op::OpAtomicFlagTestAndSet: return true; break; default: @@ -121,29 +121,29 @@ namespace val { // Validates correctness of atomic instructions. spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); switch (opcode) { - case SpvOpAtomicLoad: - case SpvOpAtomicStore: - case SpvOpAtomicExchange: - case SpvOpAtomicFAddEXT: - case SpvOpAtomicCompareExchange: - case SpvOpAtomicCompareExchangeWeak: - case SpvOpAtomicIIncrement: - case SpvOpAtomicIDecrement: - case SpvOpAtomicIAdd: - case SpvOpAtomicISub: - case SpvOpAtomicSMin: - case SpvOpAtomicUMin: - case SpvOpAtomicFMinEXT: - case SpvOpAtomicSMax: - case SpvOpAtomicUMax: - case SpvOpAtomicFMaxEXT: - case SpvOpAtomicAnd: - case SpvOpAtomicOr: - case SpvOpAtomicXor: - case SpvOpAtomicFlagTestAndSet: - case SpvOpAtomicFlagClear: { + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicStore: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicFMaxEXT: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: + case spv::Op::OpAtomicFlagClear: { const uint32_t result_type = inst->type_id(); // All current atomics only are scalar result @@ -177,7 +177,7 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { uint32_t operand_index = HasReturnType(opcode) ? 2 : 0; const uint32_t pointer_type = _.GetOperandTypeId(inst, operand_index++); uint32_t data_type = 0; - uint32_t storage_class = 0; + spv::StorageClass storage_class; if (!_.GetPointerTypeInfo(pointer_type, &data_type, &storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) @@ -185,8 +185,8 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } // Can't use result_type because OpAtomicStore doesn't have a result - if ( _.IsIntScalarType(data_type) &&_.GetBitWidth(data_type) == 64 && - !_.HasCapability(SpvCapabilityInt64Atomics)) { + if (_.IsIntScalarType(data_type) && _.GetBitWidth(data_type) == 64 && + !_.HasCapability(spv::Capability::Int64Atomics)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": 64-bit atomics require the Int64Atomics capability"; @@ -200,69 +200,69 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } // Then Shader rules - if (_.HasCapability(SpvCapabilityShader)) { + if (_.HasCapability(spv::Capability::Shader)) { // Vulkan environment rule if (spvIsVulkanEnv(_.context()->target_env)) { - if ((storage_class != SpvStorageClassUniform) && - (storage_class != SpvStorageClassStorageBuffer) && - (storage_class != SpvStorageClassWorkgroup) && - (storage_class != SpvStorageClassImage) && - (storage_class != SpvStorageClassPhysicalStorageBuffer) && - (storage_class != SpvStorageClassTaskPayloadWorkgroupEXT)) { + if ((storage_class != spv::StorageClass::Uniform) && + (storage_class != spv::StorageClass::StorageBuffer) && + (storage_class != spv::StorageClass::Workgroup) && + (storage_class != spv::StorageClass::Image) && + (storage_class != spv::StorageClass::PhysicalStorageBuffer) && + (storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4686) << spvOpcodeString(opcode) << ": Vulkan spec only allows storage classes for atomic to " "be: Uniform, Workgroup, Image, StorageBuffer, " "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT."; } - } else if (storage_class == SpvStorageClassFunction) { + } else if (storage_class == spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Function storage class forbidden when the Shader " "capability is declared."; } - if (opcode == SpvOpAtomicFAddEXT) { + if (opcode == spv::Op::OpAtomicFAddEXT) { // result type being float checked already if ((_.GetBitWidth(result_type) == 16) && - (!_.HasCapability(SpvCapabilityAtomicFloat16AddEXT))) { + (!_.HasCapability(spv::Capability::AtomicFloat16AddEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float add atomics require the AtomicFloat32AddEXT " "capability"; } if ((_.GetBitWidth(result_type) == 32) && - (!_.HasCapability(SpvCapabilityAtomicFloat32AddEXT))) { + (!_.HasCapability(spv::Capability::AtomicFloat32AddEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float add atomics require the AtomicFloat32AddEXT " "capability"; } if ((_.GetBitWidth(result_type) == 64) && - (!_.HasCapability(SpvCapabilityAtomicFloat64AddEXT))) { + (!_.HasCapability(spv::Capability::AtomicFloat64AddEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float add atomics require the AtomicFloat64AddEXT " "capability"; } - } else if (opcode == SpvOpAtomicFMinEXT || - opcode == SpvOpAtomicFMaxEXT) { + } else if (opcode == spv::Op::OpAtomicFMinEXT || + opcode == spv::Op::OpAtomicFMaxEXT) { if ((_.GetBitWidth(result_type) == 16) && - (!_.HasCapability(SpvCapabilityAtomicFloat16MinMaxEXT))) { + (!_.HasCapability(spv::Capability::AtomicFloat16MinMaxEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float min/max atomics require the " "AtomicFloat16MinMaxEXT capability"; } if ((_.GetBitWidth(result_type) == 32) && - (!_.HasCapability(SpvCapabilityAtomicFloat32MinMaxEXT))) { + (!_.HasCapability(spv::Capability::AtomicFloat32MinMaxEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float min/max atomics require the " "AtomicFloat32MinMaxEXT capability"; } if ((_.GetBitWidth(result_type) == 64) && - (!_.HasCapability(SpvCapabilityAtomicFloat64MinMaxEXT))) { + (!_.HasCapability(spv::Capability::AtomicFloat64MinMaxEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float min/max atomics require the " @@ -273,10 +273,10 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { // And finally OpenCL environment rules if (spvIsOpenCLEnv(_.context()->target_env)) { - if ((storage_class != SpvStorageClassFunction) && - (storage_class != SpvStorageClassWorkgroup) && - (storage_class != SpvStorageClassCrossWorkgroup) && - (storage_class != SpvStorageClassGeneric)) { + if ((storage_class != spv::StorageClass::Function) && + (storage_class != spv::StorageClass::Workgroup) && + (storage_class != spv::StorageClass::CrossWorkgroup) && + (storage_class != spv::StorageClass::Generic)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": storage class must be Function, Workgroup, " @@ -284,7 +284,7 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } if (_.context()->target_env == SPV_ENV_OPENCL_1_2) { - if (storage_class == SpvStorageClassGeneric) { + if (storage_class == spv::StorageClass::Generic) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Storage class cannot be Generic in OpenCL 1.2 " "environment"; @@ -293,15 +293,15 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } // If result and pointer type are different, need to do special check here - if (opcode == SpvOpAtomicFlagTestAndSet || - opcode == SpvOpAtomicFlagClear) { + if (opcode == spv::Op::OpAtomicFlagTestAndSet || + opcode == spv::Op::OpAtomicFlagClear) { if (!_.IsIntScalarType(data_type) || _.GetBitWidth(data_type) != 32) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Pointer to point to a value of 32-bit integer " "type"; } - } else if (opcode == SpvOpAtomicStore) { + } else if (opcode == spv::Op::OpAtomicStore) { if (!_.IsFloatScalarType(data_type) && !_.IsIntScalarType(data_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) @@ -325,8 +325,8 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { memory_scope)) return error; - if (opcode == SpvOpAtomicCompareExchange || - opcode == SpvOpAtomicCompareExchangeWeak) { + if (opcode == spv::Op::OpAtomicCompareExchange || + opcode == spv::Op::OpAtomicCompareExchangeWeak) { const auto unequal_semantics_index = operand_index++; if (auto error = ValidateMemorySemantics( _, inst, unequal_semantics_index, memory_scope)) @@ -346,15 +346,15 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { _.EvalInt32IfConst( inst->GetOperandAs(unequal_semantics_index)); if (is_equal_const && is_unequal_const && - ((equal_value & SpvMemorySemanticsVolatileMask) ^ - (unequal_value & SpvMemorySemanticsVolatileMask))) { + ((equal_value & uint32_t(spv::MemorySemanticsMask::Volatile)) ^ + (unequal_value & uint32_t(spv::MemorySemanticsMask::Volatile)))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Volatile mask setting must match for Equal and Unequal " "memory semantics"; } } - if (opcode == SpvOpAtomicStore) { + if (opcode == spv::Op::OpAtomicStore) { const uint32_t value_type = _.GetOperandTypeId(inst, 3); if (value_type != data_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -362,10 +362,11 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { << ": expected Value type and the type pointed to by " "Pointer to be the same"; } - } else if (opcode != SpvOpAtomicLoad && opcode != SpvOpAtomicIIncrement && - opcode != SpvOpAtomicIDecrement && - opcode != SpvOpAtomicFlagTestAndSet && - opcode != SpvOpAtomicFlagClear) { + } else if (opcode != spv::Op::OpAtomicLoad && + opcode != spv::Op::OpAtomicIIncrement && + opcode != spv::Op::OpAtomicIDecrement && + opcode != spv::Op::OpAtomicFlagTestAndSet && + opcode != spv::Op::OpAtomicFlagClear) { const uint32_t value_type = _.GetOperandTypeId(inst, operand_index++); if (value_type != result_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -374,8 +375,8 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } } - if (opcode == SpvOpAtomicCompareExchange || - opcode == SpvOpAtomicCompareExchangeWeak) { + if (opcode == spv::Op::OpAtomicCompareExchange || + opcode == spv::Op::OpAtomicCompareExchangeWeak) { const uint32_t comparator_type = _.GetOperandTypeId(inst, operand_index++); if (comparator_type != result_type) { diff --git a/3rdparty/spirv-tools/source/val/validate_barriers.cpp b/3rdparty/spirv-tools/source/val/validate_barriers.cpp index 03225d86a..59d886a11 100644 --- a/3rdparty/spirv-tools/source/val/validate_barriers.cpp +++ b/3rdparty/spirv-tools/source/val/validate_barriers.cpp @@ -32,20 +32,20 @@ namespace val { // Validates correctness of barrier instructions. spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpControlBarrier: { + case spv::Op::OpControlBarrier: { if (_.version() < SPV_SPIRV_VERSION_WORD(1, 3)) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelTessellationControl && - model != SpvExecutionModelGLCompute && - model != SpvExecutionModelKernel && - model != SpvExecutionModelTaskNV && - model != SpvExecutionModelMeshNV) { + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::GLCompute && + model != spv::ExecutionModel::Kernel && + model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV) { if (message) { *message = "OpControlBarrier requires one of the following " @@ -76,7 +76,7 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpMemoryBarrier: { + case spv::Op::OpMemoryBarrier: { const uint32_t memory_scope = inst->word(1); if (auto error = ValidateMemoryScope(_, inst, memory_scope)) { @@ -89,8 +89,8 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpNamedBarrierInitialize: { - if (_.GetIdOpcode(result_type) != SpvOpTypeNamedBarrier) { + case spv::Op::OpNamedBarrierInitialize: { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeNamedBarrier) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Result Type to be OpTypeNamedBarrier"; @@ -106,9 +106,9 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpMemoryNamedBarrier: { + case spv::Op::OpMemoryNamedBarrier: { const uint32_t named_barrier_type = _.GetOperandTypeId(inst, 0); - if (_.GetIdOpcode(named_barrier_type) != SpvOpTypeNamedBarrier) { + if (_.GetIdOpcode(named_barrier_type) != spv::Op::OpTypeNamedBarrier) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Named Barrier to be of type OpTypeNamedBarrier"; diff --git a/3rdparty/spirv-tools/source/val/validate_bitwise.cpp b/3rdparty/spirv-tools/source/val/validate_bitwise.cpp index e6e97c4a5..87c955630 100644 --- a/3rdparty/spirv-tools/source/val/validate_bitwise.cpp +++ b/3rdparty/spirv-tools/source/val/validate_bitwise.cpp @@ -27,7 +27,7 @@ namespace val { // Validates when base and result need to be the same type spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, const uint32_t base_type) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); if (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -47,7 +47,7 @@ spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, } // OpBitCount just needs same number of components - if (base_type != inst->type_id() && opcode != SpvOpBitCount) { + if (base_type != inst->type_id() && opcode != spv::Op::OpBitCount) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Base Type to be equal to Result Type: " << spvOpcodeString(opcode); @@ -58,13 +58,13 @@ spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, // Validates correctness of bitwise instructions. spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpShiftRightLogical: - case SpvOpShiftRightArithmetic: - case SpvOpShiftLeftLogical: { + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " @@ -103,10 +103,10 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpBitwiseOr: - case SpvOpBitwiseXor: - case SpvOpBitwiseAnd: - case SpvOpNot: { + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " @@ -140,7 +140,7 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpBitFieldInsert: { + case spv::Op::OpBitFieldInsert: { const uint32_t base_type = _.GetOperandTypeId(inst, 2); const uint32_t insert_type = _.GetOperandTypeId(inst, 3); const uint32_t offset_type = _.GetOperandTypeId(inst, 4); @@ -167,8 +167,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpBitFieldSExtract: - case SpvOpBitFieldUExtract: { + case spv::Op::OpBitFieldSExtract: + case spv::Op::OpBitFieldUExtract: { const uint32_t base_type = _.GetOperandTypeId(inst, 2); const uint32_t offset_type = _.GetOperandTypeId(inst, 3); const uint32_t count_type = _.GetOperandTypeId(inst, 4); @@ -189,7 +189,7 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpBitReverse: { + case spv::Op::OpBitReverse: { const uint32_t base_type = _.GetOperandTypeId(inst, 2); if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { @@ -199,7 +199,7 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpBitCount: { + case spv::Op::OpBitCount: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " diff --git a/3rdparty/spirv-tools/source/val/validate_builtins.cpp b/3rdparty/spirv-tools/source/val/validate_builtins.cpp index 6f4b0f9c3..c07dcaddd 100644 --- a/3rdparty/spirv-tools/source/val/validate_builtins.cpp +++ b/3rdparty/spirv-tools/source/val/validate_builtins.cpp @@ -62,7 +62,7 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, const Instruction& inst, uint32_t* underlying_type) { if (decoration.struct_member_index() != Decoration::kInvalidMember) { - if (inst.opcode() != SpvOpTypeStruct) { + if (inst.opcode() != spv::Op::OpTypeStruct) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << GetIdDesc(inst) << "Attempted to get underlying data type via member index for " @@ -72,7 +72,7 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, return SPV_SUCCESS; } - if (inst.opcode() == SpvOpTypeStruct) { + if (inst.opcode() == spv::Op::OpTypeStruct) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << GetIdDesc(inst) << " did not find an member index to get underlying data type for " @@ -84,7 +84,7 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, return SPV_SUCCESS; } - uint32_t storage_class = 0; + spv::StorageClass storage_class; if (!_.GetPointerTypeInfo(inst.type_id(), underlying_type, &storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << GetIdDesc(inst) @@ -95,22 +95,22 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, } // Returns Storage Class used by the instruction if applicable. -// Returns SpvStorageClassMax if not. -SpvStorageClass GetStorageClass(const Instruction& inst) { +// Returns spv::StorageClass::Max if not. +spv::StorageClass GetStorageClass(const Instruction& inst) { switch (inst.opcode()) { - case SpvOpTypePointer: - case SpvOpTypeForwardPointer: { - return SpvStorageClass(inst.word(2)); + case spv::Op::OpTypePointer: + case spv::Op::OpTypeForwardPointer: { + return spv::StorageClass(inst.word(2)); } - case SpvOpVariable: { - return SpvStorageClass(inst.word(3)); + case spv::Op::OpVariable: { + return spv::StorageClass(inst.word(3)); } - case SpvOpGenericCastToPtrExplicit: { - return SpvStorageClass(inst.word(4)); + case spv::Op::OpGenericCastToPtrExplicit: { + return spv::StorageClass(inst.word(4)); } default: { break; } } - return SpvStorageClassMax; + return spv::StorageClass::Max; } typedef enum VUIDError_ { @@ -123,52 +123,52 @@ typedef enum VUIDError_ { const static uint32_t NumVUIDBuiltins = 36; typedef struct { - SpvBuiltIn builtIn; + spv::BuiltIn builtIn; uint32_t vuid[VUIDErrorMax]; // execution mode, storage class, type VUIDs } BuiltinVUIDMapping; std::array builtinVUIDInfo = {{ // clang-format off - {SpvBuiltInSubgroupEqMask, {0, 4370, 4371}}, - {SpvBuiltInSubgroupGeMask, {0, 4372, 4373}}, - {SpvBuiltInSubgroupGtMask, {0, 4374, 4375}}, - {SpvBuiltInSubgroupLeMask, {0, 4376, 4377}}, - {SpvBuiltInSubgroupLtMask, {0, 4378, 4379}}, - {SpvBuiltInSubgroupLocalInvocationId, {0, 4380, 4381}}, - {SpvBuiltInSubgroupSize, {0, 4382, 4383}}, - {SpvBuiltInGlobalInvocationId, {4236, 4237, 4238}}, - {SpvBuiltInLocalInvocationId, {4281, 4282, 4283}}, - {SpvBuiltInNumWorkgroups, {4296, 4297, 4298}}, - {SpvBuiltInNumSubgroups, {4293, 4294, 4295}}, - {SpvBuiltInSubgroupId, {4367, 4368, 4369}}, - {SpvBuiltInWorkgroupId, {4422, 4423, 4424}}, - {SpvBuiltInHitKindKHR, {4242, 4243, 4244}}, - {SpvBuiltInHitTNV, {4245, 4246, 4247}}, - {SpvBuiltInInstanceCustomIndexKHR, {4251, 4252, 4253}}, - {SpvBuiltInInstanceId, {4254, 4255, 4256}}, - {SpvBuiltInRayGeometryIndexKHR, {4345, 4346, 4347}}, - {SpvBuiltInObjectRayDirectionKHR, {4299, 4300, 4301}}, - {SpvBuiltInObjectRayOriginKHR, {4302, 4303, 4304}}, - {SpvBuiltInObjectToWorldKHR, {4305, 4306, 4307}}, - {SpvBuiltInWorldToObjectKHR, {4434, 4435, 4436}}, - {SpvBuiltInIncomingRayFlagsKHR, {4248, 4249, 4250}}, - {SpvBuiltInRayTminKHR, {4351, 4352, 4353}}, - {SpvBuiltInRayTmaxKHR, {4348, 4349, 4350}}, - {SpvBuiltInWorldRayDirectionKHR, {4428, 4429, 4430}}, - {SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}}, - {SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}}, - {SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}}, - {SpvBuiltInFragInvocationCountEXT, {4217, 4218, 4219}}, - {SpvBuiltInFragSizeEXT, {4220, 4221, 4222}}, - {SpvBuiltInFragStencilRefEXT, {4223, 4224, 4225}}, - {SpvBuiltInFullyCoveredEXT, {4232, 4233, 4234}}, - {SpvBuiltInCullMaskKHR, {6735, 6736, 6737}}, - {SpvBuiltInBaryCoordKHR, {4154, 4155, 4156}}, - {SpvBuiltInBaryCoordNoPerspKHR, {4160, 4161, 4162}}, + {spv::BuiltIn::SubgroupEqMask, {0, 4370, 4371}}, + {spv::BuiltIn::SubgroupGeMask, {0, 4372, 4373}}, + {spv::BuiltIn::SubgroupGtMask, {0, 4374, 4375}}, + {spv::BuiltIn::SubgroupLeMask, {0, 4376, 4377}}, + {spv::BuiltIn::SubgroupLtMask, {0, 4378, 4379}}, + {spv::BuiltIn::SubgroupLocalInvocationId, {0, 4380, 4381}}, + {spv::BuiltIn::SubgroupSize, {0, 4382, 4383}}, + {spv::BuiltIn::GlobalInvocationId, {4236, 4237, 4238}}, + {spv::BuiltIn::LocalInvocationId, {4281, 4282, 4283}}, + {spv::BuiltIn::NumWorkgroups, {4296, 4297, 4298}}, + {spv::BuiltIn::NumSubgroups, {4293, 4294, 4295}}, + {spv::BuiltIn::SubgroupId, {4367, 4368, 4369}}, + {spv::BuiltIn::WorkgroupId, {4422, 4423, 4424}}, + {spv::BuiltIn::HitKindKHR, {4242, 4243, 4244}}, + {spv::BuiltIn::HitTNV, {4245, 4246, 4247}}, + {spv::BuiltIn::InstanceCustomIndexKHR, {4251, 4252, 4253}}, + {spv::BuiltIn::InstanceId, {4254, 4255, 4256}}, + {spv::BuiltIn::RayGeometryIndexKHR, {4345, 4346, 4347}}, + {spv::BuiltIn::ObjectRayDirectionKHR, {4299, 4300, 4301}}, + {spv::BuiltIn::ObjectRayOriginKHR, {4302, 4303, 4304}}, + {spv::BuiltIn::ObjectToWorldKHR, {4305, 4306, 4307}}, + {spv::BuiltIn::WorldToObjectKHR, {4434, 4435, 4436}}, + {spv::BuiltIn::IncomingRayFlagsKHR, {4248, 4249, 4250}}, + {spv::BuiltIn::RayTminKHR, {4351, 4352, 4353}}, + {spv::BuiltIn::RayTmaxKHR, {4348, 4349, 4350}}, + {spv::BuiltIn::WorldRayDirectionKHR, {4428, 4429, 4430}}, + {spv::BuiltIn::WorldRayOriginKHR, {4431, 4432, 4433}}, + {spv::BuiltIn::LaunchIdKHR, {4266, 4267, 4268}}, + {spv::BuiltIn::LaunchSizeKHR, {4269, 4270, 4271}}, + {spv::BuiltIn::FragInvocationCountEXT, {4217, 4218, 4219}}, + {spv::BuiltIn::FragSizeEXT, {4220, 4221, 4222}}, + {spv::BuiltIn::FragStencilRefEXT, {4223, 4224, 4225}}, + {spv::BuiltIn::FullyCoveredEXT, {4232, 4233, 4234}}, + {spv::BuiltIn::CullMaskKHR, {6735, 6736, 6737}}, + {spv::BuiltIn::BaryCoordKHR, {4154, 4155, 4156}}, + {spv::BuiltIn::BaryCoordNoPerspKHR, {4160, 4161, 4162}}, // clang-format off } }; -uint32_t GetVUIDForBuiltin(SpvBuiltIn builtIn, VUIDError type) { +uint32_t GetVUIDForBuiltin(spv::BuiltIn builtIn, VUIDError type) { uint32_t vuid = 0; for (const auto& iter: builtinVUIDInfo) { if (iter.builtIn == builtIn) { @@ -180,57 +180,57 @@ uint32_t GetVUIDForBuiltin(SpvBuiltIn builtIn, VUIDError type) { return vuid; } -bool IsExecutionModelValidForRtBuiltIn(SpvBuiltIn builtin, - SpvExecutionModel stage) { +bool IsExecutionModelValidForRtBuiltIn(spv::BuiltIn builtin, + spv::ExecutionModel stage) { switch (builtin) { - case SpvBuiltInHitKindKHR: - case SpvBuiltInHitTNV: - if (stage == SpvExecutionModelAnyHitKHR || - stage == SpvExecutionModelClosestHitKHR) { + case spv::BuiltIn::HitKindKHR: + case spv::BuiltIn::HitTNV: + if (stage == spv::ExecutionModel::AnyHitKHR || + stage == spv::ExecutionModel::ClosestHitKHR) { return true; } break; - case SpvBuiltInInstanceCustomIndexKHR: - case SpvBuiltInInstanceId: - case SpvBuiltInRayGeometryIndexKHR: - case SpvBuiltInObjectRayDirectionKHR: - case SpvBuiltInObjectRayOriginKHR: - case SpvBuiltInObjectToWorldKHR: - case SpvBuiltInWorldToObjectKHR: + case spv::BuiltIn::InstanceCustomIndexKHR: + case spv::BuiltIn::InstanceId: + case spv::BuiltIn::RayGeometryIndexKHR: + case spv::BuiltIn::ObjectRayDirectionKHR: + case spv::BuiltIn::ObjectRayOriginKHR: + case spv::BuiltIn::ObjectToWorldKHR: + case spv::BuiltIn::WorldToObjectKHR: switch (stage) { - case SpvExecutionModelIntersectionKHR: - case SpvExecutionModelAnyHitKHR: - case SpvExecutionModelClosestHitKHR: + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: return true; default: return false; } break; - case SpvBuiltInIncomingRayFlagsKHR: - case SpvBuiltInRayTminKHR: - case SpvBuiltInRayTmaxKHR: - case SpvBuiltInWorldRayDirectionKHR: - case SpvBuiltInWorldRayOriginKHR: - case SpvBuiltInCullMaskKHR: + case spv::BuiltIn::IncomingRayFlagsKHR: + case spv::BuiltIn::RayTminKHR: + case spv::BuiltIn::RayTmaxKHR: + case spv::BuiltIn::WorldRayDirectionKHR: + case spv::BuiltIn::WorldRayOriginKHR: + case spv::BuiltIn::CullMaskKHR: switch (stage) { - case SpvExecutionModelIntersectionKHR: - case SpvExecutionModelAnyHitKHR: - case SpvExecutionModelClosestHitKHR: - case SpvExecutionModelMissKHR: + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: + case spv::ExecutionModel::MissKHR: return true; default: return false; } break; - case SpvBuiltInLaunchIdKHR: - case SpvBuiltInLaunchSizeKHR: + case spv::BuiltIn::LaunchIdKHR: + case spv::BuiltIn::LaunchSizeKHR: switch (stage) { - case SpvExecutionModelRayGenerationKHR: - case SpvExecutionModelIntersectionKHR: - case SpvExecutionModelAnyHitKHR: - case SpvExecutionModelClosestHitKHR: - case SpvExecutionModelMissKHR: - case SpvExecutionModelCallableKHR: + case spv::ExecutionModel::RayGenerationKHR: + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: + case spv::ExecutionModel::MissKHR: + case spv::ExecutionModel::CallableKHR: return true; default: return false; @@ -559,7 +559,7 @@ class BuiltInsValidator { // |referenced_from_inst| - instruction which references id defined by // |referenced_inst| from within a function. spv_result_t ValidateNotCalledWithExecutionModel( - int vuid, const char* comment, SpvExecutionModel execution_model, + int vuid, const char* comment, spv::ExecutionModel execution_model, const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst); @@ -642,7 +642,7 @@ class BuiltInsValidator { const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst, - SpvExecutionModel execution_model = SpvExecutionModelMax) const; + spv::ExecutionModel execution_model = spv::ExecutionModel::Max) const; // Generates strings like "ID <51> (OpTypePointer) uses storage class // UniformConstant". @@ -671,12 +671,12 @@ class BuiltInsValidator { const std::vector* entry_points_ = &no_entry_points; // Execution models with which the current function can be called. - std::set execution_models_; + std::set execution_models_; }; void BuiltInsValidator::Update(const Instruction& inst) { - const SpvOp opcode = inst.opcode(); - if (opcode == SpvOpFunction) { + const spv::Op opcode = inst.opcode(); + if (opcode == spv::Op::OpFunction) { // Entering a function. assert(function_id_ == 0); function_id_ = inst.id(); @@ -691,7 +691,7 @@ void BuiltInsValidator::Update(const Instruction& inst) { } } - if (opcode == SpvOpFunctionEnd) { + if (opcode == spv::Op::OpFunctionEnd) { // Exiting a function. assert(function_id_ != 0); function_id_ = 0; @@ -704,7 +704,7 @@ std::string BuiltInsValidator::GetDefinitionDesc( const Decoration& decoration, const Instruction& inst) const { std::ostringstream ss; if (decoration.struct_member_index() != Decoration::kInvalidMember) { - assert(inst.opcode() == SpvOpTypeStruct); + assert(inst.opcode() == spv::Op::OpTypeStruct); ss << "Member #" << decoration.struct_member_index(); ss << " of struct ID <" << inst.id() << ">"; } else { @@ -716,7 +716,7 @@ std::string BuiltInsValidator::GetDefinitionDesc( std::string BuiltInsValidator::GetReferenceDesc( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst, - SpvExecutionModel execution_model) const { + spv::ExecutionModel execution_model) const { std::ostringstream ss; ss << GetIdDesc(referenced_from_inst) << " is referencing " << GetIdDesc(referenced_inst); @@ -729,10 +729,10 @@ std::string BuiltInsValidator::GetReferenceDesc( decoration.params()[0]); if (function_id_) { ss << " in function <" << function_id_ << ">"; - if (execution_model != SpvExecutionModelMax) { + if (execution_model != spv::ExecutionModel::Max) { ss << " called with execution model "; ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_EXECUTION_MODEL, - execution_model); + uint32_t(execution_model)); } } ss << "."; @@ -744,7 +744,7 @@ std::string BuiltInsValidator::GetStorageClassDesc( std::ostringstream ss; ss << GetIdDesc(inst) << " uses storage class "; ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_STORAGE_CLASS, - GetStorageClass(inst)); + uint32_t(GetStorageClass(inst))); ss << "."; return ss.str(); } @@ -803,7 +803,7 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedI32( } // Strip the array, if present. - if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { underlying_type = _.FindDef(underlying_type)->word(2u); } @@ -839,7 +839,7 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32( } // Strip the array, if present. - if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { underlying_type = _.FindDef(underlying_type)->word(2u); } @@ -922,7 +922,7 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Vec( } // Strip the array, if present. - if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { underlying_type = _.FindDef(underlying_type)->word(2u); } @@ -983,7 +983,7 @@ spv_result_t BuiltInsValidator::ValidateI32Arr( } const Instruction* const type_inst = _.FindDef(underlying_type); - if (type_inst->opcode() != SpvOpTypeArray) { + if (type_inst->opcode() != spv::Op::OpTypeArray) { return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); } @@ -1029,9 +1029,9 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Arr( } // Strip an extra layer of arraying if present. - if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { uint32_t subtype = _.FindDef(underlying_type)->word(2u); - if (_.GetIdOpcode(subtype) == SpvOpTypeArray) { + if (_.GetIdOpcode(subtype) == spv::Op::OpTypeArray) { underlying_type = subtype; } } @@ -1046,7 +1046,7 @@ spv_result_t BuiltInsValidator::ValidateF32ArrHelper( const std::function& diag, uint32_t underlying_type) { const Instruction* const type_inst = _.FindDef(underlying_type); - if (type_inst->opcode() != SpvOpTypeArray) { + if (type_inst->opcode() != spv::Op::OpTypeArray) { return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); } @@ -1107,14 +1107,14 @@ spv_result_t BuiltInsValidator::ValidateF32Mat( } spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel( - int vuid, const char* comment, SpvExecutionModel execution_model, + int vuid, const char* comment, spv::ExecutionModel execution_model, const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (function_id_) { if (execution_models_.count(execution_model)) { const char* execution_model_str = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_EXECUTION_MODEL, execution_model); + SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)); const char* built_in_str = _.grammar().lookupOperandName( SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -1149,11 +1149,11 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { - uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4190 : 4199; + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4190 : 4199; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -1165,54 +1165,54 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == SpvStorageClassInput) { + if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); - uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4188 : 4197; + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4188 : 4197; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " "Vertex.", - SpvExecutionModelVertex, decoration, built_in_inst, + spv::ExecutionModel::Vertex, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " "MeshNV.", - SpvExecutionModelMeshNV, decoration, built_in_inst, + spv::ExecutionModel::MeshNV, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " "MeshEXT.", - SpvExecutionModelMeshEXT, decoration, built_in_inst, + spv::ExecutionModel::MeshEXT, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - if (storage_class == SpvStorageClassOutput) { + if (storage_class == spv::StorageClass::Output) { assert(function_id_ == 0); - uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4189 : 4198; + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4189 : 4198; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Output storage class if execution model is " "Fragment.", - SpvExecutionModelFragment, decoration, built_in_inst, + spv::ExecutionModel::Fragment, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelFragment: - case SpvExecutionModelVertex: { + case spv::ExecutionModel::Fragment: + case spv::ExecutionModel::Vertex: { if (spv_result_t error = ValidateF32Arr( decoration, built_in_inst, /* Any number of components */ 0, [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (decoration.params()[0] == SpvBuiltInClipDistance) + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -1228,11 +1228,11 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( } break; } - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: - case SpvExecutionModelGeometry: - case SpvExecutionModelMeshNV: - case SpvExecutionModelMeshEXT: { + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: { if (decoration.struct_member_index() != Decoration::kInvalidMember) { // The outer level of array is applied on the variable. if (spv_result_t error = ValidateF32Arr( @@ -1240,7 +1240,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (decoration.params()[0] == SpvBuiltInClipDistance) + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, @@ -1261,7 +1261,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (decoration.params()[0] == SpvBuiltInClipDistance) + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, @@ -1282,7 +1282,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( default: { uint32_t vuid = - (decoration.params()[0] == SpvBuiltInClipDistance) ? 4187 : 4196; + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4187 : 4196; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -1335,9 +1335,9 @@ spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4211) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn FragCoord to be only used for " @@ -1347,8 +1347,8 @@ spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4210) << spvLogStringForEnv(_.context()->target_env) @@ -1396,9 +1396,9 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4214) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn FragDepth to be only used for " @@ -1408,8 +1408,8 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4213) << spvLogStringForEnv(_.context()->target_env) @@ -1424,7 +1424,7 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( // Every entry point from which this function is called needs to have // Execution Mode DepthReplacing. const auto* modes = _.GetExecutionModes(entry_point); - if (!modes || !modes->count(SpvExecutionModeDepthReplacing)) { + if (!modes || !modes->count(spv::ExecutionMode::DepthReplacing)) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4216) << spvLogStringForEnv(_.context()->target_env) @@ -1472,9 +1472,9 @@ spv_result_t BuiltInsValidator::ValidateFrontFacingAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4230) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn FrontFacing to be only used for " @@ -1484,8 +1484,8 @@ spv_result_t BuiltInsValidator::ValidateFrontFacingAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4229) << spvLogStringForEnv(_.context()->target_env) @@ -1532,9 +1532,9 @@ spv_result_t BuiltInsValidator::ValidateHelperInvocationAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4240) << "Vulkan spec allows BuiltIn HelperInvocation to be only used " @@ -1544,8 +1544,8 @@ spv_result_t BuiltInsValidator::ValidateHelperInvocationAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4239) << "Vulkan spec allows BuiltIn HelperInvocation to be used only " @@ -1592,9 +1592,9 @@ spv_result_t BuiltInsValidator::ValidateInvocationIdAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4258) << "Vulkan spec allows BuiltIn InvocationId to be only used for " @@ -1604,9 +1604,9 @@ spv_result_t BuiltInsValidator::ValidateInvocationIdAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelTessellationControl && - execution_model != SpvExecutionModelGeometry) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::TessellationControl && + execution_model != spv::ExecutionModel::Geometry) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4257) << "Vulkan spec allows BuiltIn InvocationId to be used only " @@ -1653,9 +1653,9 @@ spv_result_t BuiltInsValidator::ValidateInstanceIndexAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4264) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn InstanceIndex to be only used for " @@ -1665,8 +1665,8 @@ spv_result_t BuiltInsValidator::ValidateInstanceIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelVertex) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4263) << spvLogStringForEnv(_.context()->target_env) @@ -1713,9 +1713,9 @@ spv_result_t BuiltInsValidator::ValidatePatchVerticesAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4309) << "Vulkan spec allows BuiltIn PatchVertices to be only used for " @@ -1725,9 +1725,9 @@ spv_result_t BuiltInsValidator::ValidatePatchVerticesAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelTessellationControl && - execution_model != SpvExecutionModelTessellationEvaluation) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::TessellationControl && + execution_model != spv::ExecutionModel::TessellationEvaluation) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4308) << "Vulkan spec allows BuiltIn PatchVertices to be used only " @@ -1775,9 +1775,9 @@ spv_result_t BuiltInsValidator::ValidatePointCoordAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4312) << "Vulkan spec allows BuiltIn PointCoord to be only used for " @@ -1787,8 +1787,8 @@ spv_result_t BuiltInsValidator::ValidatePointCoordAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4311) << "Vulkan spec allows BuiltIn PointCoord to be used only with " @@ -1820,10 +1820,10 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4316) << "Vulkan spec allows BuiltIn PointSize to be only used for " @@ -1833,20 +1833,20 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == SpvStorageClassInput) { + if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4315, "Vulkan spec doesn't allow BuiltIn PointSize to be used for " "variables with Input storage class if execution model is " "Vertex.", - SpvExecutionModelVertex, decoration, built_in_inst, + spv::ExecutionModel::Vertex, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelVertex: { + case spv::ExecutionModel::Vertex: { if (spv_result_t error = ValidateF32( decoration, built_in_inst, [this, &referenced_from_inst]( @@ -1861,11 +1861,11 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( } break; } - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: - case SpvExecutionModelGeometry: - case SpvExecutionModelMeshNV: - case SpvExecutionModelMeshEXT: { + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: { // PointSize can be a per-vertex variable for tessellation control, // tessellation evaluation and geometry shader stages. In such cases // variables will have an array of 32-bit floats. @@ -1938,10 +1938,10 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4320) << "Vulkan spec allows BuiltIn Position to be only used for " "variables with Input or Output storage class. " @@ -1950,34 +1950,34 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == SpvStorageClassInput) { + if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, "Vulkan spec doesn't allow BuiltIn Position to be used " "for variables " "with Input storage class if execution model is Vertex.", - SpvExecutionModelVertex, decoration, built_in_inst, + spv::ExecutionModel::Vertex, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, "Vulkan spec doesn't allow BuiltIn Position to be used " "for variables " "with Input storage class if execution model is MeshNV.", - SpvExecutionModelMeshNV, decoration, built_in_inst, + spv::ExecutionModel::MeshNV, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, "Vulkan spec doesn't allow BuiltIn Position to be used " "for variables " "with Input storage class if execution model is MeshEXT.", - SpvExecutionModelMeshEXT, decoration, built_in_inst, + spv::ExecutionModel::MeshEXT, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelVertex: { + case spv::ExecutionModel::Vertex: { if (spv_result_t error = ValidateF32Vec( decoration, built_in_inst, 4, [this, &referenced_from_inst]( @@ -1993,11 +1993,11 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( } break; } - case SpvExecutionModelGeometry: - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: - case SpvExecutionModelMeshNV: - case SpvExecutionModelMeshEXT: { + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: { // Position can be a per-vertex variable for tessellation control, // tessellation evaluation, geometry and mesh shader stages. In such // cases variables will have an array of 4-component 32-bit float @@ -2103,10 +2103,10 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << "Vulkan spec allows BuiltIn PrimitiveId to be only used for " "variables with Input or Output storage class. " @@ -2115,63 +2115,63 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == SpvStorageClassOutput) { + if (storage_class == spv::StorageClass::Output) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "TessellationControl.", - SpvExecutionModelTessellationControl, decoration, built_in_inst, + spv::ExecutionModel::TessellationControl, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "TessellationEvaluation.", - SpvExecutionModelTessellationEvaluation, decoration, built_in_inst, + spv::ExecutionModel::TessellationEvaluation, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "Fragment.", - SpvExecutionModelFragment, decoration, built_in_inst, + spv::ExecutionModel::Fragment, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "IntersectionKHR.", - SpvExecutionModelIntersectionKHR, decoration, built_in_inst, + spv::ExecutionModel::IntersectionKHR, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "AnyHitKHR.", - SpvExecutionModelAnyHitKHR, decoration, built_in_inst, + spv::ExecutionModel::AnyHitKHR, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "ClosestHitKHR.", - SpvExecutionModelClosestHitKHR, decoration, built_in_inst, + spv::ExecutionModel::ClosestHitKHR, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelFragment: - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: - case SpvExecutionModelGeometry: - case SpvExecutionModelMeshNV: - case SpvExecutionModelMeshEXT: - case SpvExecutionModelIntersectionKHR: - case SpvExecutionModelAnyHitKHR: - case SpvExecutionModelClosestHitKHR: { + case spv::ExecutionModel::Fragment: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: { // Ok. break; } @@ -2225,9 +2225,9 @@ spv_result_t BuiltInsValidator::ValidateSampleIdAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4355) << "Vulkan spec allows BuiltIn SampleId to be only used for " @@ -2237,8 +2237,8 @@ spv_result_t BuiltInsValidator::ValidateSampleIdAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4354) << "Vulkan spec allows BuiltIn SampleId to be used only with " @@ -2284,10 +2284,10 @@ spv_result_t BuiltInsValidator::ValidateSampleMaskAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4358) << "Vulkan spec allows BuiltIn SampleMask to be only used for " @@ -2297,8 +2297,8 @@ spv_result_t BuiltInsValidator::ValidateSampleMaskAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4357) << "Vulkan spec allows BuiltIn SampleMask to be used only " @@ -2346,9 +2346,9 @@ spv_result_t BuiltInsValidator::ValidateSamplePositionAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4361) << "Vulkan spec allows BuiltIn SamplePosition to be only used " @@ -2359,8 +2359,8 @@ spv_result_t BuiltInsValidator::ValidateSamplePositionAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4360) << "Vulkan spec allows BuiltIn SamplePosition to be used only " @@ -2408,9 +2408,9 @@ spv_result_t BuiltInsValidator::ValidateTessCoordAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4388) << "Vulkan spec allows BuiltIn TessCoord to be only used for " @@ -2420,8 +2420,8 @@ spv_result_t BuiltInsValidator::ValidateTessCoordAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelTessellationEvaluation) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::TessellationEvaluation) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4387) << "Vulkan spec allows BuiltIn TessCoord to be used only with " @@ -2490,10 +2490,10 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2505,42 +2505,42 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == SpvStorageClassInput) { + if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); - uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4391 : 4395; + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " "used " "for variables with Input storage class if execution model is " "TessellationControl.", - SpvExecutionModelTessellationControl, decoration, built_in_inst, + spv::ExecutionModel::TessellationControl, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - if (storage_class == SpvStorageClassOutput) { + if (storage_class == spv::StorageClass::Output) { assert(function_id_ == 0); - uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4392 : 4396; + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " "used " "for variables with Output storage class if execution model is " "TessellationEvaluation.", - SpvExecutionModelTessellationEvaluation, decoration, built_in_inst, + spv::ExecutionModel::TessellationEvaluation, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: { + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: { // Ok. break; } default: { - uint32_t vuid = (operand == SpvBuiltInTessLevelOuter) ? 4390 : 4394; + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::TessLevelOuter) ? 4390 : 4394; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2623,9 +2623,9 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4399) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn VertexIndex to be only used for " @@ -2635,8 +2635,8 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelVertex) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4398) << spvLogStringForEnv(_.context()->target_env) @@ -2670,7 +2670,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( [this, &decoration, &inst](const std::string& message) -> spv_result_t { uint32_t vuid = - (decoration.params()[0] == SpvBuiltInLayer) ? 4276 : 4408; + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " @@ -2687,7 +2687,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( [this, &decoration, &inst](const std::string& message) -> spv_result_t { uint32_t vuid = - (decoration.params()[0] == SpvBuiltInLayer) ? 4276 : 4408; + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " @@ -2711,10 +2711,10 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2726,15 +2726,15 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == SpvStorageClassInput) { + if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); for (const auto em : - {SpvExecutionModelVertex, SpvExecutionModelTessellationEvaluation, - SpvExecutionModelGeometry, SpvExecutionModelMeshNV, - SpvExecutionModelMeshEXT}) { + {spv::ExecutionModel::Vertex, spv::ExecutionModel::TessellationEvaluation, + spv::ExecutionModel::Geometry, spv::ExecutionModel::MeshNV, + spv::ExecutionModel::MeshEXT}) { id_to_at_reference_checks_[referenced_from_inst.id()].push_back( std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, - this, ((operand == SpvBuiltInLayer) ? 4274 : 4406), + this, ((spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4274 : 4406), "Vulkan spec doesn't allow BuiltIn Layer and " "ViewportIndex to be " "used for variables with Input storage class if " @@ -2745,46 +2745,46 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( } } - if (storage_class == SpvStorageClassOutput) { + if (storage_class == spv::StorageClass::Output) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back( std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, - this, ((operand == SpvBuiltInLayer) ? 4275 : 4407), + this, ((spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4275 : 4407), "Vulkan spec doesn't allow BuiltIn Layer and " "ViewportIndex to be " "used for variables with Output storage class if " "execution model is " "Fragment.", - SpvExecutionModelFragment, decoration, built_in_inst, + spv::ExecutionModel::Fragment, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelGeometry: - case SpvExecutionModelFragment: - case SpvExecutionModelMeshNV: - case SpvExecutionModelMeshEXT: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::Fragment: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: // Ok. break; - case SpvExecutionModelVertex: - case SpvExecutionModelTessellationEvaluation: { - if (!_.HasCapability(SpvCapabilityShaderViewportIndexLayerEXT)) { - if (operand == SpvBuiltInViewportIndex && - _.HasCapability(SpvCapabilityShaderViewportIndex)) + case spv::ExecutionModel::Vertex: + case spv::ExecutionModel::TessellationEvaluation: { + if (!_.HasCapability(spv::Capability::ShaderViewportIndexLayerEXT)) { + if (spv::BuiltIn(operand) == spv::BuiltIn::ViewportIndex && + _.HasCapability(spv::Capability::ShaderViewportIndex)) break; // Ok - if (operand == SpvBuiltInLayer && - _.HasCapability(SpvCapabilityShaderLayer)) + if (spv::BuiltIn(operand) == spv::BuiltIn::Layer && + _.HasCapability(spv::Capability::ShaderLayer)) break; // Ok const char* capability = "ShaderViewportIndexLayerEXT"; - if (operand == SpvBuiltInViewportIndex) + if (spv::BuiltIn(operand) == spv::BuiltIn::ViewportIndex) capability = "ShaderViewportIndexLayerEXT or ShaderViewportIndex"; - if (operand == SpvBuiltInLayer) + if (spv::BuiltIn(operand) == spv::BuiltIn::Layer) capability = "ShaderViewportIndexLayerEXT or ShaderLayer"; - uint32_t vuid = (operand == SpvBuiltInLayer) ? 4273 : 4405; + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4273 : 4405; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Using BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2795,7 +2795,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( break; } default: { - uint32_t vuid = (operand == SpvBuiltInLayer) ? 4272 : 4404; + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4272 : 4404; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2823,7 +2823,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateF32Vec( decoration, inst, 3, [this, &inst, builtin](const std::string& message) -> spv_result_t { @@ -2833,7 +2833,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - builtin) + uint32_t(builtin)) << " variable needs to be a 3-component 32-bit float " "vector. " << message; @@ -2853,29 +2853,29 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -2897,7 +2897,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32Vec( decoration, inst, 3, [this, &inst, builtin](const std::string& message) -> spv_result_t { @@ -2907,7 +2907,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - builtin) + uint32_t(builtin)) << " variable needs to be a 3-component 32-bit int " "vector. " << message; @@ -2926,27 +2926,27 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || - execution_model == SpvExecutionModelTaskNV || - execution_model == SpvExecutionModelMeshNV || - execution_model == SpvExecutionModelTaskEXT || - execution_model == SpvExecutionModelMeshEXT; + for (const spv::ExecutionModel execution_model : execution_models_) { + bool has_vulkan_model = execution_model == spv::ExecutionModel::GLCompute || + execution_model == spv::ExecutionModel::TaskNV || + execution_model == spv::ExecutionModel::MeshNV || + execution_model == spv::ExecutionModel::TaskEXT || + execution_model == spv::ExecutionModel::MeshEXT; if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); @@ -2954,7 +2954,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or" << " TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -2977,11 +2977,11 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " cannot be used as a member decoration "; } if (spv_result_t error = ValidateI32( @@ -2993,7 +2993,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 32-bit int " "vector. " << message; @@ -3011,35 +3011,35 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || - execution_model == SpvExecutionModelTaskNV || - execution_model == SpvExecutionModelMeshNV || - execution_model == SpvExecutionModelTaskEXT || - execution_model == SpvExecutionModelMeshEXT; + for (const spv::ExecutionModel execution_model : execution_models_) { + bool has_vulkan_model = execution_model == spv::ExecutionModel::GLCompute || + execution_model == spv::ExecutionModel::TaskNV || + execution_model == spv::ExecutionModel::MeshNV || + execution_model == spv::ExecutionModel::TaskEXT || + execution_model == spv::ExecutionModel::MeshEXT; if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " << "TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -3062,11 +3062,11 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " cannot be used as a member decoration "; } if (spv_result_t error = ValidateI32( @@ -3078,21 +3078,21 @@ spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 32-bit int. " << message; })) { return error; } - const SpvStorageClass storage_class = GetStorageClass(inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, inst, inst, inst) << " " << GetStorageClassDesc(inst); @@ -3105,11 +3105,11 @@ spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " cannot be used as a member decoration "; } if (spv_result_t error = ValidateI32Vec( @@ -3121,7 +3121,7 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 4-component 32-bit int " "vector. " << message; @@ -3129,15 +3129,15 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( return error; } - const SpvStorageClass storage_class = GetStorageClass(inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, inst, inst, inst) << " " << GetStorageClassDesc(inst); @@ -3182,12 +3182,12 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelGLCompute && - execution_model != SpvExecutionModelTaskNV && - execution_model != SpvExecutionModelMeshNV && - execution_model != SpvExecutionModelTaskEXT && - execution_model != SpvExecutionModelMeshEXT) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::GLCompute && + execution_model != spv::ExecutionModel::TaskNV && + execution_model != spv::ExecutionModel::MeshNV && + execution_model != spv::ExecutionModel::TaskEXT && + execution_model != spv::ExecutionModel::MeshEXT) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4425) << spvLogStringForEnv(_.context()->target_env) @@ -3219,7 +3219,7 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtDefinition( decoration, inst, [this, &inst, &decoration](const std::string& message) -> spv_result_t { - uint32_t vuid = (decoration.params()[0] == SpvBuiltInBaseInstance) + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::BaseInstance) ? 4183 : 4186; return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -3243,10 +3243,10 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { - uint32_t vuid = (operand == SpvBuiltInBaseInstance) ? 4182 : 4185; + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::BaseInstance) ? 4182 : 4185; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3257,9 +3257,9 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelVertex) { - uint32_t vuid = (operand == SpvBuiltInBaseInstance) ? 4181 : 4184; + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex) { + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::BaseInstance) ? 4181 : 4184; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3310,9 +3310,9 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4208) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3323,12 +3323,12 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelVertex && - execution_model != SpvExecutionModelMeshNV && - execution_model != SpvExecutionModelTaskNV && - execution_model != SpvExecutionModelMeshEXT && - execution_model != SpvExecutionModelTaskEXT) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex && + execution_model != spv::ExecutionModel::MeshNV && + execution_model != spv::ExecutionModel::TaskNV && + execution_model != spv::ExecutionModel::MeshEXT && + execution_model != spv::ExecutionModel::TaskEXT) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4207) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3380,9 +3380,9 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4402) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3393,8 +3393,8 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model == SpvExecutionModelGLCompute) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model == spv::ExecutionModel::GLCompute) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4401) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3444,9 +3444,9 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4205) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3472,7 +3472,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const De const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3482,7 +3482,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const De << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - builtin) + uint32_t(builtin)) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3499,29 +3499,29 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3542,7 +3542,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32Vec( decoration, inst, 2, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3552,7 +3552,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& d << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - builtin) + uint32_t(builtin)) << " variable needs to be a 2-component 32-bit int vector. " << message; })) { @@ -3569,29 +3569,29 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3612,7 +3612,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3622,7 +3622,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decorat << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - builtin) + uint32_t(builtin)) << " variable needs to be a int scalar. " << message; })) { @@ -3639,29 +3639,29 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassOutput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Output storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3682,7 +3682,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateBool( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3692,7 +3692,7 @@ spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoratio << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - builtin) + uint32_t(builtin)) << " variable needs to be a bool scalar. " << message; })) { @@ -3709,29 +3709,29 @@ spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3778,9 +3778,9 @@ spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " @@ -3832,9 +3832,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassOutput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4485) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3845,12 +3845,12 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { switch (execution_model) { - case SpvExecutionModelVertex: - case SpvExecutionModelGeometry: - case SpvExecutionModelMeshNV: - case SpvExecutionModelMeshEXT: + case spv::ExecutionModel::Vertex: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: break; default: { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -3905,9 +3905,9 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4491) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3918,8 +3918,8 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelFragment) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4490) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3944,11 +3944,11 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); switch (builtin) { - case SpvBuiltInHitTNV: - case SpvBuiltInRayTminKHR: - case SpvBuiltInRayTmaxKHR: + case spv::BuiltIn::HitTNV: + case spv::BuiltIn::RayTminKHR: + case spv::BuiltIn::RayTmaxKHR: // f32 scalar if (spv_result_t error = ValidateF32( decoration, inst, @@ -3959,19 +3959,19 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, builtin) + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 32-bit float scalar. " << message; })) { return error; } break; - case SpvBuiltInHitKindKHR: - case SpvBuiltInInstanceCustomIndexKHR: - case SpvBuiltInInstanceId: - case SpvBuiltInRayGeometryIndexKHR: - case SpvBuiltInIncomingRayFlagsKHR: - case SpvBuiltInCullMaskKHR: + case spv::BuiltIn::HitKindKHR: + case spv::BuiltIn::InstanceCustomIndexKHR: + case spv::BuiltIn::InstanceId: + case spv::BuiltIn::RayGeometryIndexKHR: + case spv::BuiltIn::IncomingRayFlagsKHR: + case spv::BuiltIn::CullMaskKHR: // i32 scalar if (spv_result_t error = ValidateI32( decoration, inst, @@ -3982,17 +3982,17 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, builtin) + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 32-bit int scalar. " << message; })) { return error; } break; - case SpvBuiltInObjectRayDirectionKHR: - case SpvBuiltInObjectRayOriginKHR: - case SpvBuiltInWorldRayDirectionKHR: - case SpvBuiltInWorldRayOriginKHR: + case spv::BuiltIn::ObjectRayDirectionKHR: + case spv::BuiltIn::ObjectRayOriginKHR: + case spv::BuiltIn::WorldRayDirectionKHR: + case spv::BuiltIn::WorldRayOriginKHR: // f32 vec3 if (spv_result_t error = ValidateF32Vec( decoration, inst, 3, @@ -4003,7 +4003,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, builtin) + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 3-component 32-bit float " "vector. " << message; @@ -4011,8 +4011,8 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( return error; } break; - case SpvBuiltInLaunchIdKHR: - case SpvBuiltInLaunchSizeKHR: + case spv::BuiltIn::LaunchIdKHR: + case spv::BuiltIn::LaunchSizeKHR: // i32 vec3 if (spv_result_t error = ValidateI32Vec( decoration, inst, 3, @@ -4023,7 +4023,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, builtin) + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a 3-component 32-bit int " "vector. " << message; @@ -4031,8 +4031,8 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( return error; } break; - case SpvBuiltInObjectToWorldKHR: - case SpvBuiltInWorldToObjectKHR: + case spv::BuiltIn::ObjectToWorldKHR: + case spv::BuiltIn::WorldToObjectKHR: // f32 mat4x3 if (spv_result_t error = ValidateF32Mat( decoration, inst, 3, 4, @@ -4043,7 +4043,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, builtin) + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) << " variable needs to be a matrix with" << " 4 columns of 3-component vectors of 32-bit " "floats. " @@ -4067,10 +4067,10 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassInput) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " @@ -4082,7 +4082,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const SpvExecutionModel execution_model : execution_models_) { + for (const spv::ExecutionModel execution_model : execution_models_) { if (!IsExecutionModelValidForRtBuiltIn(builtin, execution_model)) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -4091,7 +4091,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( decoration.params()[0]) << " to be used with the execution model " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_EXECUTION_MODEL, execution_model) + SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)) << ".\n" << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -4112,7 +4112,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( const Decoration& decoration, const Instruction& inst) { - const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]); + const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]); if (!spvIsVulkanEnv(_.context()->target_env)) { // Early return. All currently implemented rules are based on Vulkan spec. @@ -4129,166 +4129,166 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( // If the newly added enum has validation rules associated with it // consider leaving a TODO and/or creating an issue. switch (label) { - case SpvBuiltInClipDistance: - case SpvBuiltInCullDistance: { + case spv::BuiltIn::ClipDistance: + case spv::BuiltIn::CullDistance: { return ValidateClipOrCullDistanceAtDefinition(decoration, inst); } - case SpvBuiltInFragCoord: { + case spv::BuiltIn::FragCoord: { return ValidateFragCoordAtDefinition(decoration, inst); } - case SpvBuiltInFragDepth: { + case spv::BuiltIn::FragDepth: { return ValidateFragDepthAtDefinition(decoration, inst); } - case SpvBuiltInFrontFacing: { + case spv::BuiltIn::FrontFacing: { return ValidateFrontFacingAtDefinition(decoration, inst); } - case SpvBuiltInGlobalInvocationId: - case SpvBuiltInLocalInvocationId: - case SpvBuiltInNumWorkgroups: - case SpvBuiltInWorkgroupId: { + case spv::BuiltIn::GlobalInvocationId: + case spv::BuiltIn::LocalInvocationId: + case spv::BuiltIn::NumWorkgroups: + case spv::BuiltIn::WorkgroupId: { return ValidateComputeShaderI32Vec3InputAtDefinition(decoration, inst); } - case SpvBuiltInBaryCoordKHR: - case SpvBuiltInBaryCoordNoPerspKHR: { + case spv::BuiltIn::BaryCoordKHR: + case spv::BuiltIn::BaryCoordNoPerspKHR: { return ValidateFragmentShaderF32Vec3InputAtDefinition(decoration, inst); } - case SpvBuiltInHelperInvocation: { + case spv::BuiltIn::HelperInvocation: { return ValidateHelperInvocationAtDefinition(decoration, inst); } - case SpvBuiltInInvocationId: { + case spv::BuiltIn::InvocationId: { return ValidateInvocationIdAtDefinition(decoration, inst); } - case SpvBuiltInInstanceIndex: { + case spv::BuiltIn::InstanceIndex: { return ValidateInstanceIndexAtDefinition(decoration, inst); } - case SpvBuiltInLayer: - case SpvBuiltInViewportIndex: { + case spv::BuiltIn::Layer: + case spv::BuiltIn::ViewportIndex: { return ValidateLayerOrViewportIndexAtDefinition(decoration, inst); } - case SpvBuiltInPatchVertices: { + case spv::BuiltIn::PatchVertices: { return ValidatePatchVerticesAtDefinition(decoration, inst); } - case SpvBuiltInPointCoord: { + case spv::BuiltIn::PointCoord: { return ValidatePointCoordAtDefinition(decoration, inst); } - case SpvBuiltInPointSize: { + case spv::BuiltIn::PointSize: { return ValidatePointSizeAtDefinition(decoration, inst); } - case SpvBuiltInPosition: { + case spv::BuiltIn::Position: { return ValidatePositionAtDefinition(decoration, inst); } - case SpvBuiltInPrimitiveId: { + case spv::BuiltIn::PrimitiveId: { return ValidatePrimitiveIdAtDefinition(decoration, inst); } - case SpvBuiltInSampleId: { + case spv::BuiltIn::SampleId: { return ValidateSampleIdAtDefinition(decoration, inst); } - case SpvBuiltInSampleMask: { + case spv::BuiltIn::SampleMask: { return ValidateSampleMaskAtDefinition(decoration, inst); } - case SpvBuiltInSamplePosition: { + case spv::BuiltIn::SamplePosition: { return ValidateSamplePositionAtDefinition(decoration, inst); } - case SpvBuiltInSubgroupId: - case SpvBuiltInNumSubgroups: { + case spv::BuiltIn::SubgroupId: + case spv::BuiltIn::NumSubgroups: { return ValidateComputeI32InputAtDefinition(decoration, inst); } - case SpvBuiltInSubgroupLocalInvocationId: - case SpvBuiltInSubgroupSize: { + case spv::BuiltIn::SubgroupLocalInvocationId: + case spv::BuiltIn::SubgroupSize: { return ValidateI32InputAtDefinition(decoration, inst); } - case SpvBuiltInSubgroupEqMask: - case SpvBuiltInSubgroupGeMask: - case SpvBuiltInSubgroupGtMask: - case SpvBuiltInSubgroupLeMask: - case SpvBuiltInSubgroupLtMask: { + case spv::BuiltIn::SubgroupEqMask: + case spv::BuiltIn::SubgroupGeMask: + case spv::BuiltIn::SubgroupGtMask: + case spv::BuiltIn::SubgroupLeMask: + case spv::BuiltIn::SubgroupLtMask: { return ValidateI32Vec4InputAtDefinition(decoration, inst); } - case SpvBuiltInTessCoord: { + case spv::BuiltIn::TessCoord: { return ValidateTessCoordAtDefinition(decoration, inst); } - case SpvBuiltInTessLevelOuter: { + case spv::BuiltIn::TessLevelOuter: { return ValidateTessLevelOuterAtDefinition(decoration, inst); } - case SpvBuiltInTessLevelInner: { + case spv::BuiltIn::TessLevelInner: { return ValidateTessLevelInnerAtDefinition(decoration, inst); } - case SpvBuiltInVertexIndex: { + case spv::BuiltIn::VertexIndex: { return ValidateVertexIndexAtDefinition(decoration, inst); } - case SpvBuiltInWorkgroupSize: { + case spv::BuiltIn::WorkgroupSize: { return ValidateWorkgroupSizeAtDefinition(decoration, inst); } - case SpvBuiltInVertexId: { + case spv::BuiltIn::VertexId: { return ValidateVertexIdAtDefinition(decoration, inst); } - case SpvBuiltInLocalInvocationIndex: { + case spv::BuiltIn::LocalInvocationIndex: { return ValidateLocalInvocationIndexAtDefinition(decoration, inst); } - case SpvBuiltInCoreIDARM: - case SpvBuiltInCoreCountARM: - case SpvBuiltInCoreMaxIDARM: - case SpvBuiltInWarpIDARM: - case SpvBuiltInWarpMaxIDARM: - case SpvBuiltInWarpsPerSMNV: - case SpvBuiltInSMCountNV: - case SpvBuiltInWarpIDNV: - case SpvBuiltInSMIDNV: { + case spv::BuiltIn::CoreIDARM: + case spv::BuiltIn::CoreCountARM: + case spv::BuiltIn::CoreMaxIDARM: + case spv::BuiltIn::WarpIDARM: + case spv::BuiltIn::WarpMaxIDARM: + case spv::BuiltIn::WarpsPerSMNV: + case spv::BuiltIn::SMCountNV: + case spv::BuiltIn::WarpIDNV: + case spv::BuiltIn::SMIDNV: { return ValidateNVSMOrARMCoreBuiltinsAtDefinition(decoration, inst); } - case SpvBuiltInBaseInstance: - case SpvBuiltInBaseVertex: { + case spv::BuiltIn::BaseInstance: + case spv::BuiltIn::BaseVertex: { return ValidateBaseInstanceOrVertexAtDefinition(decoration, inst); } - case SpvBuiltInDrawIndex: { + case spv::BuiltIn::DrawIndex: { return ValidateDrawIndexAtDefinition(decoration, inst); } - case SpvBuiltInViewIndex: { + case spv::BuiltIn::ViewIndex: { return ValidateViewIndexAtDefinition(decoration, inst); } - case SpvBuiltInDeviceIndex: { + case spv::BuiltIn::DeviceIndex: { return ValidateDeviceIndexAtDefinition(decoration, inst); } - case SpvBuiltInFragInvocationCountEXT: { - // alias SpvBuiltInInvocationsPerPixelNV + case spv::BuiltIn::FragInvocationCountEXT: { + // alias spv::BuiltIn::InvocationsPerPixelNV return ValidateFragInvocationCountAtDefinition(decoration, inst); } - case SpvBuiltInFragSizeEXT: { - // alias SpvBuiltInFragmentSizeNV + case spv::BuiltIn::FragSizeEXT: { + // alias spv::BuiltIn::FragmentSizeNV return ValidateFragSizeAtDefinition(decoration, inst); } - case SpvBuiltInFragStencilRefEXT: { + case spv::BuiltIn::FragStencilRefEXT: { return ValidateFragStencilRefAtDefinition(decoration, inst); } - case SpvBuiltInFullyCoveredEXT:{ + case spv::BuiltIn::FullyCoveredEXT:{ return ValidateFullyCoveredAtDefinition(decoration, inst); } // Ray tracing builtins - case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV - case SpvBuiltInHitTNV: // NOT present in KHR - case SpvBuiltInInstanceId: - case SpvBuiltInLaunchIdKHR: // alias SpvBuiltInLaunchIdNV - case SpvBuiltInLaunchSizeKHR: // alias SpvBuiltInLaunchSizeNV - case SpvBuiltInWorldRayOriginKHR: // alias SpvBuiltInWorldRayOriginNV - case SpvBuiltInWorldRayDirectionKHR: // alias SpvBuiltInWorldRayDirectionNV - case SpvBuiltInObjectRayOriginKHR: // alias SpvBuiltInObjectRayOriginNV - case SpvBuiltInObjectRayDirectionKHR: // alias - // SpvBuiltInObjectRayDirectionNV - case SpvBuiltInRayTminKHR: // alias SpvBuiltInRayTminNV - case SpvBuiltInRayTmaxKHR: // alias SpvBuiltInRayTmaxNV - case SpvBuiltInInstanceCustomIndexKHR: // alias - // SpvBuiltInInstanceCustomIndexNV - case SpvBuiltInObjectToWorldKHR: // alias SpvBuiltInObjectToWorldNV - case SpvBuiltInWorldToObjectKHR: // alias SpvBuiltInWorldToObjectNV - case SpvBuiltInIncomingRayFlagsKHR: // alias SpvBuiltInIncomingRayFlagsNV - case SpvBuiltInRayGeometryIndexKHR: // NOT present in NV - case SpvBuiltInCullMaskKHR: { + case spv::BuiltIn::HitKindKHR: // alias spv::BuiltIn::HitKindNV + case spv::BuiltIn::HitTNV: // NOT present in KHR + case spv::BuiltIn::InstanceId: + case spv::BuiltIn::LaunchIdKHR: // alias spv::BuiltIn::LaunchIdNV + case spv::BuiltIn::LaunchSizeKHR: // alias spv::BuiltIn::LaunchSizeNV + case spv::BuiltIn::WorldRayOriginKHR: // alias spv::BuiltIn::WorldRayOriginNV + case spv::BuiltIn::WorldRayDirectionKHR: // alias spv::BuiltIn::WorldRayDirectionNV + case spv::BuiltIn::ObjectRayOriginKHR: // alias spv::BuiltIn::ObjectRayOriginNV + case spv::BuiltIn::ObjectRayDirectionKHR: // alias + // spv::BuiltIn::ObjectRayDirectionNV + case spv::BuiltIn::RayTminKHR: // alias spv::BuiltIn::RayTminNV + case spv::BuiltIn::RayTmaxKHR: // alias spv::BuiltIn::RayTmaxNV + case spv::BuiltIn::InstanceCustomIndexKHR: // alias + // spv::BuiltIn::InstanceCustomIndexNV + case spv::BuiltIn::ObjectToWorldKHR: // alias spv::BuiltIn::ObjectToWorldNV + case spv::BuiltIn::WorldToObjectKHR: // alias spv::BuiltIn::WorldToObjectNV + case spv::BuiltIn::IncomingRayFlagsKHR: // alias spv::BuiltIn::IncomingRayFlagsNV + case spv::BuiltIn::RayGeometryIndexKHR: // NOT present in NV + case spv::BuiltIn::CullMaskKHR: { return ValidateRayTracingBuiltinsAtDefinition(decoration, inst); } - case SpvBuiltInPrimitiveShadingRateKHR: { + case spv::BuiltIn::PrimitiveShadingRateKHR: { return ValidatePrimitiveShadingRateAtDefinition(decoration, inst); } - case SpvBuiltInShadingRateKHR: { + case spv::BuiltIn::ShadingRateKHR: { return ValidateShadingRateAtDefinition(decoration, inst); } default: @@ -4310,7 +4310,7 @@ spv_result_t BuiltInsValidator::ValidateBuiltInsAtDefinition() { assert(inst); for (const auto& decoration : kv.second) { - if (decoration.dec_type() != SpvDecorationBuiltIn) { + if (decoration.dec_type() != spv::Decoration::BuiltIn) { continue; } diff --git a/3rdparty/spirv-tools/source/val/validate_capability.cpp b/3rdparty/spirv-tools/source/val/validate_capability.cpp index 8efd55420..d70c8273c 100644 --- a/3rdparty/spirv-tools/source/val/validate_capability.cpp +++ b/3rdparty/spirv-tools/source/val/validate_capability.cpp @@ -29,74 +29,82 @@ namespace val { namespace { bool IsSupportGuaranteedVulkan_1_0(uint32_t capability) { - switch (capability) { - case SpvCapabilityMatrix: - case SpvCapabilityShader: - case SpvCapabilityInputAttachment: - case SpvCapabilitySampled1D: - case SpvCapabilityImage1D: - case SpvCapabilitySampledBuffer: - case SpvCapabilityImageBuffer: - case SpvCapabilityImageQuery: - case SpvCapabilityDerivativeControl: + switch (spv::Capability(capability)) { + case spv::Capability::Matrix: + case spv::Capability::Shader: + case spv::Capability::InputAttachment: + case spv::Capability::Sampled1D: + case spv::Capability::Image1D: + case spv::Capability::SampledBuffer: + case spv::Capability::ImageBuffer: + case spv::Capability::ImageQuery: + case spv::Capability::DerivativeControl: return true; + default: + break; } return false; } bool IsSupportGuaranteedVulkan_1_1(uint32_t capability) { if (IsSupportGuaranteedVulkan_1_0(capability)) return true; - switch (capability) { - case SpvCapabilityDeviceGroup: - case SpvCapabilityMultiView: + switch (spv::Capability(capability)) { + case spv::Capability::DeviceGroup: + case spv::Capability::MultiView: return true; + default: + break; } return false; } bool IsSupportGuaranteedVulkan_1_2(uint32_t capability) { if (IsSupportGuaranteedVulkan_1_1(capability)) return true; - switch (capability) { - case SpvCapabilityShaderNonUniform: + switch (spv::Capability(capability)) { + case spv::Capability::ShaderNonUniform: return true; + default: + break; } return false; } bool IsSupportOptionalVulkan_1_0(uint32_t capability) { - switch (capability) { - case SpvCapabilityGeometry: - case SpvCapabilityTessellation: - case SpvCapabilityFloat64: - case SpvCapabilityInt64: - case SpvCapabilityInt16: - case SpvCapabilityTessellationPointSize: - case SpvCapabilityGeometryPointSize: - case SpvCapabilityImageGatherExtended: - case SpvCapabilityStorageImageMultisample: - case SpvCapabilityUniformBufferArrayDynamicIndexing: - case SpvCapabilitySampledImageArrayDynamicIndexing: - case SpvCapabilityStorageBufferArrayDynamicIndexing: - case SpvCapabilityStorageImageArrayDynamicIndexing: - case SpvCapabilityClipDistance: - case SpvCapabilityCullDistance: - case SpvCapabilityImageCubeArray: - case SpvCapabilitySampleRateShading: - case SpvCapabilitySparseResidency: - case SpvCapabilityMinLod: - case SpvCapabilitySampledCubeArray: - case SpvCapabilityImageMSArray: - case SpvCapabilityStorageImageExtendedFormats: - case SpvCapabilityInterpolationFunction: - case SpvCapabilityStorageImageReadWithoutFormat: - case SpvCapabilityStorageImageWriteWithoutFormat: - case SpvCapabilityMultiViewport: - case SpvCapabilityInt64Atomics: - case SpvCapabilityTransformFeedback: - case SpvCapabilityGeometryStreams: - case SpvCapabilityFloat16: - case SpvCapabilityInt8: + switch (spv::Capability(capability)) { + case spv::Capability::Geometry: + case spv::Capability::Tessellation: + case spv::Capability::Float64: + case spv::Capability::Int64: + case spv::Capability::Int16: + case spv::Capability::TessellationPointSize: + case spv::Capability::GeometryPointSize: + case spv::Capability::ImageGatherExtended: + case spv::Capability::StorageImageMultisample: + case spv::Capability::UniformBufferArrayDynamicIndexing: + case spv::Capability::SampledImageArrayDynamicIndexing: + case spv::Capability::StorageBufferArrayDynamicIndexing: + case spv::Capability::StorageImageArrayDynamicIndexing: + case spv::Capability::ClipDistance: + case spv::Capability::CullDistance: + case spv::Capability::ImageCubeArray: + case spv::Capability::SampleRateShading: + case spv::Capability::SparseResidency: + case spv::Capability::MinLod: + case spv::Capability::SampledCubeArray: + case spv::Capability::ImageMSArray: + case spv::Capability::StorageImageExtendedFormats: + case spv::Capability::InterpolationFunction: + case spv::Capability::StorageImageReadWithoutFormat: + case spv::Capability::StorageImageWriteWithoutFormat: + case spv::Capability::MultiViewport: + case spv::Capability::Int64Atomics: + case spv::Capability::TransformFeedback: + case spv::Capability::GeometryStreams: + case spv::Capability::Float16: + case spv::Capability::Int8: return true; + default: + break; } return false; } @@ -104,27 +112,29 @@ bool IsSupportOptionalVulkan_1_0(uint32_t capability) { bool IsSupportOptionalVulkan_1_1(uint32_t capability) { if (IsSupportOptionalVulkan_1_0(capability)) return true; - switch (capability) { - case SpvCapabilityGroupNonUniform: - case SpvCapabilityGroupNonUniformVote: - case SpvCapabilityGroupNonUniformArithmetic: - case SpvCapabilityGroupNonUniformBallot: - case SpvCapabilityGroupNonUniformShuffle: - case SpvCapabilityGroupNonUniformShuffleRelative: - case SpvCapabilityGroupNonUniformClustered: - case SpvCapabilityGroupNonUniformQuad: - case SpvCapabilityDrawParameters: - // Alias SpvCapabilityStorageBuffer16BitAccess. - case SpvCapabilityStorageUniformBufferBlock16: - // Alias SpvCapabilityUniformAndStorageBuffer16BitAccess. - case SpvCapabilityStorageUniform16: - case SpvCapabilityStoragePushConstant16: - case SpvCapabilityStorageInputOutput16: - case SpvCapabilityDeviceGroup: - case SpvCapabilityMultiView: - case SpvCapabilityVariablePointersStorageBuffer: - case SpvCapabilityVariablePointers: + switch (spv::Capability(capability)) { + case spv::Capability::GroupNonUniform: + case spv::Capability::GroupNonUniformVote: + case spv::Capability::GroupNonUniformArithmetic: + case spv::Capability::GroupNonUniformBallot: + case spv::Capability::GroupNonUniformShuffle: + case spv::Capability::GroupNonUniformShuffleRelative: + case spv::Capability::GroupNonUniformClustered: + case spv::Capability::GroupNonUniformQuad: + case spv::Capability::DrawParameters: + // Alias spv::Capability::StorageBuffer16BitAccess. + case spv::Capability::StorageUniformBufferBlock16: + // Alias spv::Capability::UniformAndStorageBuffer16BitAccess. + case spv::Capability::StorageUniform16: + case spv::Capability::StoragePushConstant16: + case spv::Capability::StorageInputOutput16: + case spv::Capability::DeviceGroup: + case spv::Capability::MultiView: + case spv::Capability::VariablePointersStorageBuffer: + case spv::Capability::VariablePointers: return true; + default: + break; } return false; } @@ -132,47 +142,51 @@ bool IsSupportOptionalVulkan_1_1(uint32_t capability) { bool IsSupportOptionalVulkan_1_2(uint32_t capability) { if (IsSupportOptionalVulkan_1_1(capability)) return true; - switch (capability) { - case SpvCapabilityDenormPreserve: - case SpvCapabilityDenormFlushToZero: - case SpvCapabilitySignedZeroInfNanPreserve: - case SpvCapabilityRoundingModeRTE: - case SpvCapabilityRoundingModeRTZ: - case SpvCapabilityVulkanMemoryModel: - case SpvCapabilityVulkanMemoryModelDeviceScope: - case SpvCapabilityStorageBuffer8BitAccess: - case SpvCapabilityUniformAndStorageBuffer8BitAccess: - case SpvCapabilityStoragePushConstant8: - case SpvCapabilityShaderViewportIndex: - case SpvCapabilityShaderLayer: - case SpvCapabilityPhysicalStorageBufferAddresses: - case SpvCapabilityRuntimeDescriptorArray: - case SpvCapabilityUniformTexelBufferArrayDynamicIndexing: - case SpvCapabilityStorageTexelBufferArrayDynamicIndexing: - case SpvCapabilityUniformBufferArrayNonUniformIndexing: - case SpvCapabilitySampledImageArrayNonUniformIndexing: - case SpvCapabilityStorageBufferArrayNonUniformIndexing: - case SpvCapabilityStorageImageArrayNonUniformIndexing: - case SpvCapabilityInputAttachmentArrayNonUniformIndexing: - case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing: - case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing: + switch (spv::Capability(capability)) { + case spv::Capability::DenormPreserve: + case spv::Capability::DenormFlushToZero: + case spv::Capability::SignedZeroInfNanPreserve: + case spv::Capability::RoundingModeRTE: + case spv::Capability::RoundingModeRTZ: + case spv::Capability::VulkanMemoryModel: + case spv::Capability::VulkanMemoryModelDeviceScope: + case spv::Capability::StorageBuffer8BitAccess: + case spv::Capability::UniformAndStorageBuffer8BitAccess: + case spv::Capability::StoragePushConstant8: + case spv::Capability::ShaderViewportIndex: + case spv::Capability::ShaderLayer: + case spv::Capability::PhysicalStorageBufferAddresses: + case spv::Capability::RuntimeDescriptorArray: + case spv::Capability::UniformTexelBufferArrayDynamicIndexing: + case spv::Capability::StorageTexelBufferArrayDynamicIndexing: + case spv::Capability::UniformBufferArrayNonUniformIndexing: + case spv::Capability::SampledImageArrayNonUniformIndexing: + case spv::Capability::StorageBufferArrayNonUniformIndexing: + case spv::Capability::StorageImageArrayNonUniformIndexing: + case spv::Capability::InputAttachmentArrayNonUniformIndexing: + case spv::Capability::UniformTexelBufferArrayNonUniformIndexing: + case spv::Capability::StorageTexelBufferArrayNonUniformIndexing: return true; + default: + break; } return false; } bool IsSupportGuaranteedOpenCL_1_2(uint32_t capability, bool embedded_profile) { - switch (capability) { - case SpvCapabilityAddresses: - case SpvCapabilityFloat16Buffer: - case SpvCapabilityInt16: - case SpvCapabilityInt8: - case SpvCapabilityKernel: - case SpvCapabilityLinkage: - case SpvCapabilityVector16: + switch (spv::Capability(capability)) { + case spv::Capability::Addresses: + case spv::Capability::Float16Buffer: + case spv::Capability::Int16: + case spv::Capability::Int8: + case spv::Capability::Kernel: + case spv::Capability::Linkage: + case spv::Capability::Vector16: return true; - case SpvCapabilityInt64: + case spv::Capability::Int64: return !embedded_profile; + default: + break; } return false; } @@ -180,12 +194,14 @@ bool IsSupportGuaranteedOpenCL_1_2(uint32_t capability, bool embedded_profile) { bool IsSupportGuaranteedOpenCL_2_0(uint32_t capability, bool embedded_profile) { if (IsSupportGuaranteedOpenCL_1_2(capability, embedded_profile)) return true; - switch (capability) { - case SpvCapabilityDeviceEnqueue: - case SpvCapabilityGenericPointer: - case SpvCapabilityGroups: - case SpvCapabilityPipes: + switch (spv::Capability(capability)) { + case spv::Capability::DeviceEnqueue: + case spv::Capability::GenericPointer: + case spv::Capability::Groups: + case spv::Capability::Pipes: return true; + default: + break; } return false; } @@ -193,19 +209,23 @@ bool IsSupportGuaranteedOpenCL_2_0(uint32_t capability, bool embedded_profile) { bool IsSupportGuaranteedOpenCL_2_2(uint32_t capability, bool embedded_profile) { if (IsSupportGuaranteedOpenCL_2_0(capability, embedded_profile)) return true; - switch (capability) { - case SpvCapabilitySubgroupDispatch: - case SpvCapabilityPipeStorage: + switch (spv::Capability(capability)) { + case spv::Capability::SubgroupDispatch: + case spv::Capability::PipeStorage: return true; + default: + break; } return false; } bool IsSupportOptionalOpenCL_1_2(uint32_t capability) { - switch (capability) { - case SpvCapabilityImageBasic: - case SpvCapabilityFloat64: + switch (spv::Capability(capability)) { + case spv::Capability::ImageBasic: + case spv::Capability::Float64: return true; + default: + break; } return false; } @@ -229,14 +249,16 @@ bool IsEnabledByExtension(ValidationState_t& _, uint32_t capability) { bool IsEnabledByCapabilityOpenCL_1_2(ValidationState_t& _, uint32_t capability) { - if (_.HasCapability(SpvCapabilityImageBasic)) { - switch (capability) { - case SpvCapabilityLiteralSampler: - case SpvCapabilitySampled1D: - case SpvCapabilityImage1D: - case SpvCapabilitySampledBuffer: - case SpvCapabilityImageBuffer: + if (_.HasCapability(spv::Capability::ImageBasic)) { + switch (spv::Capability(capability)) { + case spv::Capability::LiteralSampler: + case spv::Capability::Sampled1D: + case spv::Capability::Image1D: + case spv::Capability::SampledBuffer: + case spv::Capability::ImageBuffer: return true; + default: + break; } return false; } @@ -245,15 +267,17 @@ bool IsEnabledByCapabilityOpenCL_1_2(ValidationState_t& _, bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, uint32_t capability) { - if (_.HasCapability(SpvCapabilityImageBasic)) { - switch (capability) { - case SpvCapabilityImageReadWrite: - case SpvCapabilityLiteralSampler: - case SpvCapabilitySampled1D: - case SpvCapabilityImage1D: - case SpvCapabilitySampledBuffer: - case SpvCapabilityImageBuffer: + if (_.HasCapability(spv::Capability::ImageBasic)) { + switch (spv::Capability(capability)) { + case spv::Capability::ImageReadWrite: + case spv::Capability::LiteralSampler: + case spv::Capability::Sampled1D: + case spv::Capability::Image1D: + case spv::Capability::SampledBuffer: + case spv::Capability::ImageBuffer: return true; + default: + break; } return false; } @@ -265,7 +289,7 @@ bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, // Validates that capability declarations use operands allowed in the current // context. spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) { - if (inst->opcode() != SpvOpCapability) return SPV_SUCCESS; + if (inst->opcode() != spv::Op::OpCapability) return SPV_SUCCESS; assert(inst->operands().size() == 1); diff --git a/3rdparty/spirv-tools/source/val/validate_cfg.cpp b/3rdparty/spirv-tools/source/val/validate_cfg.cpp index cc0b999f2..9ba66f422 100644 --- a/3rdparty/spirv-tools/source/val/validate_cfg.cpp +++ b/3rdparty/spirv-tools/source/val/validate_cfg.cpp @@ -54,7 +54,7 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { << "OpPhi must not have void result type"; } if (_.IsPointerType(inst->type_id()) && - _.addressing_model() == SpvAddressingModelLogical) { + _.addressing_model() == spv::AddressingModel::Logical) { if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Using pointers with OpPhi requires capability " @@ -64,13 +64,14 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { const Instruction* type_inst = _.FindDef(inst->type_id()); assert(type_inst); - const SpvOp type_opcode = type_inst->opcode(); + const spv::Op type_opcode = type_inst->opcode(); if (!_.options()->before_hlsl_legalization && - !_.HasCapability(SpvCapabilityBindlessTextureNV)) { - if (type_opcode == SpvOpTypeSampledImage || - (_.HasCapability(SpvCapabilityShader) && - (type_opcode == SpvOpTypeImage || type_opcode == SpvOpTypeSampler))) { + !_.HasCapability(spv::Capability::BindlessTextureNV)) { + if (type_opcode == spv::Op::OpTypeSampledImage || + (_.HasCapability(spv::Capability::Shader) && + (type_opcode == spv::Op::OpTypeImage || + type_opcode == spv::Op::OpTypeSampler))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result type cannot be Op" << spvOpcodeString(type_opcode); } @@ -108,7 +109,7 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { << " type " << _.getIdName(inc_type_id) << "."; } } else { - if (_.GetIdOpcode(inc_id) != SpvOpLabel) { + if (_.GetIdOpcode(inc_id) != spv::Op::OpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpPhi's incoming basic block " << _.getIdName(inc_id) << " is not an OpLabel."; @@ -143,7 +144,7 @@ spv_result_t ValidateBranch(ValidationState_t& _, const Instruction* inst) { // target operands must be OpLabel const auto id = inst->GetOperandAs(0); const auto target = _.FindDef(id); - if (!target || SpvOpLabel != target->opcode()) { + if (!target || spv::Op::OpLabel != target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "'Target Label' operands for OpBranch must be the ID " "of an OpLabel instruction"; @@ -178,7 +179,7 @@ spv_result_t ValidateBranchConditional(ValidationState_t& _, // PerformCfgChecks already checks for that const auto true_id = inst->GetOperandAs(1); const auto true_target = _.FindDef(true_id); - if (!true_target || SpvOpLabel != true_target->opcode()) { + if (!true_target || spv::Op::OpLabel != true_target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The 'True Label' operand for OpBranchConditional must be the " "ID of an OpLabel instruction"; @@ -186,7 +187,7 @@ spv_result_t ValidateBranchConditional(ValidationState_t& _, const auto false_id = inst->GetOperandAs(2); const auto false_target = _.FindDef(false_id); - if (!false_target || SpvOpLabel != false_target->opcode()) { + if (!false_target || spv::Op::OpLabel != false_target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The 'False Label' operand for OpBranchConditional must be the " "ID of an OpLabel instruction"; @@ -213,7 +214,7 @@ spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) { } const auto default_label = _.FindDef(inst->GetOperandAs(1)); - if (default_label->opcode() != SpvOpLabel) { + if (default_label->opcode() != spv::Op::OpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Default must be an OpLabel instruction"; } @@ -223,7 +224,7 @@ spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) { // literal, id const auto id = inst->GetOperandAs(i + 1); const auto target = _.FindDef(id); - if (!target || SpvOpLabel != target->opcode()) { + if (!target || spv::Op::OpLabel != target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "'Target Label' operands for OpSwitch must be IDs of an " "OpLabel instruction"; @@ -243,14 +244,14 @@ spv_result_t ValidateReturnValue(ValidationState_t& _, << " does not represent a value."; } auto value_type = _.FindDef(value->type_id()); - if (!value_type || SpvOpTypeVoid == value_type->opcode()) { + if (!value_type || spv::Op::OpTypeVoid == value_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpReturnValue value's type " << _.getIdName(value->type_id()) << " is missing or void."; } - if (_.addressing_model() == SpvAddressingModelLogical && - SpvOpTypePointer == value_type->opcode() && + if (_.addressing_model() == spv::AddressingModel::Logical && + spv::Op::OpTypePointer == value_type->opcode() && !_.features().variable_pointers && !_.options()->relax_logical_pointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpReturnValue value's type " @@ -270,10 +271,15 @@ spv_result_t ValidateReturnValue(ValidationState_t& _, return SPV_SUCCESS; } +uint32_t operator>>(const spv::LoopControlShift& lhs, + const spv::LoopControlShift& rhs) { + return uint32_t(lhs) >> uint32_t(rhs); +} + spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { const auto merge_id = inst->GetOperandAs(0); const auto merge = _.FindDef(merge_id); - if (!merge || merge->opcode() != SpvOpLabel) { + if (!merge || merge->opcode() != spv::Op::OpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Merge Block " << _.getIdName(merge_id) << " must be an OpLabel"; } @@ -284,7 +290,7 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { const auto continue_id = inst->GetOperandAs(1); const auto continue_target = _.FindDef(continue_id); - if (!continue_target || continue_target->opcode() != SpvOpLabel) { + if (!continue_target || continue_target->opcode() != spv::Op::OpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Continue Target " << _.getIdName(continue_id) << " must be an OpLabel"; @@ -295,36 +301,36 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { << "Merge Block and Continue Target must be different ids"; } - const auto loop_control = inst->GetOperandAs(2); - if ((loop_control >> SpvLoopControlUnrollShift) & 0x1 && - (loop_control >> SpvLoopControlDontUnrollShift) & 0x1) { + const auto loop_control = inst->GetOperandAs(2); + if ((loop_control >> spv::LoopControlShift::Unroll) & 0x1 && + (loop_control >> spv::LoopControlShift::DontUnroll) & 0x1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Unroll and DontUnroll loop controls must not both be specified"; } - if ((loop_control >> SpvLoopControlDontUnrollShift) & 0x1 && - (loop_control >> SpvLoopControlPeelCountShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 && + (loop_control >> spv::LoopControlShift::PeelCount) & 0x1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PeelCount and DontUnroll " "loop controls must not " "both be specified"; } - if ((loop_control >> SpvLoopControlDontUnrollShift) & 0x1 && - (loop_control >> SpvLoopControlPartialCountShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 && + (loop_control >> spv::LoopControlShift::PartialCount) & 0x1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PartialCount and " "DontUnroll loop controls " "must not both be specified"; } uint32_t operand = 3; - if ((loop_control >> SpvLoopControlDependencyLengthShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::DependencyLength) & 0x1) { ++operand; } - if ((loop_control >> SpvLoopControlMinIterationsShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::MinIterations) & 0x1) { ++operand; } - if ((loop_control >> SpvLoopControlMaxIterationsShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::MaxIterations) & 0x1) { ++operand; } - if ((loop_control >> SpvLoopControlIterationMultipleShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::IterationMultiple) & 0x1) { if (inst->operands().size() < operand || inst->GetOperandAs(operand) == 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "IterationMultiple loop " @@ -333,10 +339,10 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { } ++operand; } - if ((loop_control >> SpvLoopControlPeelCountShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::PeelCount) & 0x1) { ++operand; } - if ((loop_control >> SpvLoopControlPartialCountShift) & 0x1) { + if ((loop_control >> spv::LoopControlShift::PartialCount) & 0x1) { ++operand; } @@ -554,7 +560,7 @@ spv_result_t StructuredSwitchChecks(ValidationState_t& _, Function* function, target_block->structurally_reachable() && !header->structurally_dominates(*target_block)) { return _.diag(SPV_ERROR_INVALID_CFG, header->label()) - << "Selection header " << _.getIdName(header->id()) + << "Switch header " << _.getIdName(header->id()) << " does not structurally dominate its case construct " << _.getIdName(target); } @@ -644,9 +650,9 @@ spv_result_t ValidateStructuredSelections( const auto index = terminator - &_.ordered_instructions()[0]; auto* merge = &_.ordered_instructions()[index - 1]; // Marks merges and continues as seen. - if (merge->opcode() == SpvOpSelectionMerge) { + if (merge->opcode() == spv::Op::OpSelectionMerge) { seen.insert(merge->GetOperandAs(0)); - } else if (merge->opcode() == SpvOpLoopMerge) { + } else if (merge->opcode() == spv::Op::OpLoopMerge) { seen.insert(merge->GetOperandAs(0)); seen.insert(merge->GetOperandAs(1)); } else { @@ -657,7 +663,7 @@ spv_result_t ValidateStructuredSelections( // Skip unreachable blocks. if (!block->structurally_reachable()) continue; - if (terminator->opcode() == SpvOpBranchConditional) { + if (terminator->opcode() == spv::Op::OpBranchConditional) { const auto true_label = terminator->GetOperandAs(1); const auto false_label = terminator->GetOperandAs(2); // Mark the upcoming blocks as seen now, but only error out if this block @@ -669,7 +675,7 @@ spv_result_t ValidateStructuredSelections( return _.diag(SPV_ERROR_INVALID_CFG, terminator) << "Selection must be structured"; } - } else if (terminator->opcode() == SpvOpSwitch) { + } else if (terminator->opcode() == spv::Op::OpSwitch) { if (!merge) { return _.diag(SPV_ERROR_INVALID_CFG, terminator) << "OpSwitch must be preceded by an OpSelectionMerge " @@ -746,6 +752,7 @@ spv_result_t StructuredControlFlowChecks( _.getIdName(merge->id()), "does not structurally dominate"); } + // If it's really a merge block for a selection or loop, then it must be // *strictly* structrually dominated by the header. if (construct.ExitBlockIsMergeBlock() && (header == merge)) { @@ -798,8 +805,8 @@ spv_result_t StructuredControlFlowChecks( block->is_type(BlockType::kBlockTypeLoop)) { size_t index = (block->terminator() - &_.ordered_instructions()[0]) - 1; const auto& merge_inst = _.ordered_instructions()[index]; - if (merge_inst.opcode() == SpvOpSelectionMerge || - merge_inst.opcode() == SpvOpLoopMerge) { + if (merge_inst.opcode() == spv::Op::OpSelectionMerge || + merge_inst.opcode() == spv::Op::OpLoopMerge) { uint32_t merge_id = merge_inst.GetOperandAs(0); auto merge_block = function->GetBlock(merge_id).first; if (merge_block->structurally_reachable() && @@ -854,7 +861,7 @@ spv_result_t StructuredControlFlowChecks( // Checks rules for case constructs. if (construct.type() == ConstructType::kSelection && - header->terminator()->opcode() == SpvOpSwitch) { + header->terminator()->opcode() == spv::Op::OpSwitch) { const auto terminator = header->terminator(); if (auto error = StructuredSwitchChecks(_, function, terminator, header, merge)) { @@ -928,7 +935,7 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { } // If we have structured control flow, check that no block has a control // flow nesting depth larger than the limit. - if (_.HasCapability(SpvCapabilityShader)) { + if (_.HasCapability(spv::Capability::Shader)) { const int control_flow_nesting_depth_limit = _.options()->universal_limits_.max_control_flow_nesting_depth; for (auto block = begin(blocks); block != end(blocks); ++block) { @@ -942,7 +949,7 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { } /// Structured control flow checks are only required for shader capabilities - if (_.HasCapability(SpvCapabilityShader)) { + if (_.HasCapability(spv::Capability::Shader)) { // Calculate structural dominance. postorder.clear(); std::vector postdom_postorder; @@ -998,9 +1005,9 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { } spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { - SpvOp opcode = inst->opcode(); + spv::Op opcode = inst->opcode(); switch (opcode) { - case SpvOpLabel: + case spv::Op::OpLabel: if (auto error = _.current_function().RegisterBlock(inst->id())) return error; @@ -1009,7 +1016,7 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { // passes the OpLabel ends up not being part of the basic block it starts. _.current_function().current_block()->set_label(inst); break; - case SpvOpLoopMerge: { + case spv::Op::OpLoopMerge: { uint32_t merge_block = inst->GetOperandAs(0); uint32_t continue_block = inst->GetOperandAs(1); CFG_ASSERT(MergeBlockAssert, merge_block); @@ -1018,20 +1025,20 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { continue_block)) return error; } break; - case SpvOpSelectionMerge: { + case spv::Op::OpSelectionMerge: { uint32_t merge_block = inst->GetOperandAs(0); CFG_ASSERT(MergeBlockAssert, merge_block); if (auto error = _.current_function().RegisterSelectionMerge(merge_block)) return error; } break; - case SpvOpBranch: { + case spv::Op::OpBranch: { uint32_t target = inst->GetOperandAs(0); CFG_ASSERT(FirstBlockAssert, target); _.current_function().RegisterBlockEnd({target}); } break; - case SpvOpBranchConditional: { + case spv::Op::OpBranchConditional: { uint32_t tlabel = inst->GetOperandAs(1); uint32_t flabel = inst->GetOperandAs(2); CFG_ASSERT(FirstBlockAssert, tlabel); @@ -1040,7 +1047,7 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { _.current_function().RegisterBlockEnd({tlabel, flabel}); } break; - case SpvOpSwitch: { + case spv::Op::OpSwitch: { std::vector cases; for (size_t i = 1; i < inst->operands().size(); i += 2) { uint32_t target = inst->GetOperandAs(i); @@ -1049,44 +1056,44 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { } _.current_function().RegisterBlockEnd({cases}); } break; - case SpvOpReturn: { + case spv::Op::OpReturn: { const uint32_t return_type = _.current_function().GetResultTypeId(); const Instruction* return_type_inst = _.FindDef(return_type); assert(return_type_inst); - if (return_type_inst->opcode() != SpvOpTypeVoid) + if (return_type_inst->opcode() != spv::Op::OpTypeVoid) return _.diag(SPV_ERROR_INVALID_CFG, inst) << "OpReturn can only be called from a function with void " << "return type."; _.current_function().RegisterBlockEnd(std::vector()); break; } - case SpvOpKill: - case SpvOpReturnValue: - case SpvOpUnreachable: - case SpvOpTerminateInvocation: - case SpvOpIgnoreIntersectionKHR: - case SpvOpTerminateRayKHR: - case SpvOpEmitMeshTasksEXT: + case spv::Op::OpKill: + case spv::Op::OpReturnValue: + case spv::Op::OpUnreachable: + case spv::Op::OpTerminateInvocation: + case spv::Op::OpIgnoreIntersectionKHR: + case spv::Op::OpTerminateRayKHR: + case spv::Op::OpEmitMeshTasksEXT: _.current_function().RegisterBlockEnd(std::vector()); // Ops with dedicated passes check for the Execution Model there - if (opcode == SpvOpKill) { + if (opcode == spv::Op::OpKill) { _.current_function().RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, "OpKill requires Fragment execution model"); } - if (opcode == SpvOpTerminateInvocation) { + if (opcode == spv::Op::OpTerminateInvocation) { _.current_function().RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, "OpTerminateInvocation requires Fragment execution model"); } - if (opcode == SpvOpIgnoreIntersectionKHR) { + if (opcode == spv::Op::OpIgnoreIntersectionKHR) { _.current_function().RegisterExecutionModelLimitation( - SpvExecutionModelAnyHitKHR, + spv::ExecutionModel::AnyHitKHR, "OpIgnoreIntersectionKHR requires AnyHitKHR execution model"); } - if (opcode == SpvOpTerminateRayKHR) { + if (opcode == spv::Op::OpTerminateRayKHR) { _.current_function().RegisterExecutionModelLimitation( - SpvExecutionModelAnyHitKHR, + spv::ExecutionModel::AnyHitKHR, "OpTerminateRayKHR requires AnyHitKHR execution model"); } @@ -1140,22 +1147,22 @@ void ReachabilityPass(ValidationState_t& _) { spv_result_t ControlFlowPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpPhi: + case spv::Op::OpPhi: if (auto error = ValidatePhi(_, inst)) return error; break; - case SpvOpBranch: + case spv::Op::OpBranch: if (auto error = ValidateBranch(_, inst)) return error; break; - case SpvOpBranchConditional: + case spv::Op::OpBranchConditional: if (auto error = ValidateBranchConditional(_, inst)) return error; break; - case SpvOpReturnValue: + case spv::Op::OpReturnValue: if (auto error = ValidateReturnValue(_, inst)) return error; break; - case SpvOpSwitch: + case spv::Op::OpSwitch: if (auto error = ValidateSwitch(_, inst)) return error; break; - case SpvOpLoopMerge: + case spv::Op::OpLoopMerge: if (auto error = ValidateLoopMerge(_, inst)) return error; break; default: diff --git a/3rdparty/spirv-tools/source/val/validate_composites.cpp b/3rdparty/spirv-tools/source/val/validate_composites.cpp index c3d948dc7..e777f1640 100644 --- a/3rdparty/spirv-tools/source/val/validate_composites.cpp +++ b/3rdparty/spirv-tools/source/val/validate_composites.cpp @@ -35,9 +35,10 @@ namespace { spv_result_t GetExtractInsertValueType(ValidationState_t& _, const Instruction* inst, uint32_t* member_type) { - const SpvOp opcode = inst->opcode(); - assert(opcode == SpvOpCompositeExtract || opcode == SpvOpCompositeInsert); - uint32_t word_index = opcode == SpvOpCompositeExtract ? 4 : 5; + const spv::Op opcode = inst->opcode(); + assert(opcode == spv::Op::OpCompositeExtract || + opcode == spv::Op::OpCompositeInsert); + uint32_t word_index = opcode == spv::Op::OpCompositeExtract ? 4 : 5; const uint32_t num_words = static_cast(inst->words().size()); const uint32_t composite_id_index = word_index - 1; const uint32_t num_indices = num_words - word_index; @@ -66,7 +67,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, const Instruction* const type_inst = _.FindDef(*member_type); assert(type_inst); switch (type_inst->opcode()) { - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { *member_type = type_inst->word(2); const uint32_t vector_size = type_inst->word(3); if (component_index >= vector_size) { @@ -76,7 +77,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { *member_type = type_inst->word(2); const uint32_t num_cols = type_inst->word(3); if (component_index >= num_cols) { @@ -86,7 +87,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { uint64_t array_size = 0; auto size = _.FindDef(type_inst->word(3)); *member_type = type_inst->word(2); @@ -105,12 +106,12 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case SpvOpTypeRuntimeArray: { + case spv::Op::OpTypeRuntimeArray: { *member_type = type_inst->word(2); // Array size is unknown. break; } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const size_t num_struct_members = type_inst->words().size() - 2; if (component_index >= num_struct_members) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -123,7 +124,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, *member_type = type_inst->word(component_index + 2); break; } - case SpvOpTypeCooperativeMatrixNV: { + case spv::Op::OpTypeCooperativeMatrixNV: { *member_type = type_inst->word(2); break; } @@ -140,15 +141,15 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, const Instruction* inst) { const uint32_t result_type = inst->type_id(); - const SpvOp result_opcode = _.GetIdOpcode(result_type); + const spv::Op result_opcode = _.GetIdOpcode(result_type); if (!spvOpcodeIsScalarType(result_opcode)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be a scalar type"; } const uint32_t vector_type = _.GetOperandTypeId(inst, 2); - const SpvOp vector_opcode = _.GetIdOpcode(vector_type); - if (vector_opcode != SpvOpTypeVector) { + const spv::Op vector_opcode = _.GetIdOpcode(vector_type); + if (vector_opcode != spv::Op::OpTypeVector) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Vector type to be OpTypeVector"; } @@ -164,7 +165,7 @@ spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, << "Expected Index to be int scalar"; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot extract from a vector of 8- or 16-bit types"; @@ -175,8 +176,8 @@ spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _, const Instruction* inst) { const uint32_t result_type = inst->type_id(); - const SpvOp result_opcode = _.GetIdOpcode(result_type); - if (result_opcode != SpvOpTypeVector) { + const spv::Op result_opcode = _.GetIdOpcode(result_type); + if (result_opcode != spv::Op::OpTypeVector) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeVector"; } @@ -200,7 +201,7 @@ spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _, << "Expected Index to be int scalar"; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot insert into a vector of 8- or 16-bit types"; @@ -212,9 +213,9 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, const Instruction* inst) { const uint32_t num_operands = static_cast(inst->operands().size()); const uint32_t result_type = inst->type_id(); - const SpvOp result_opcode = _.GetIdOpcode(result_type); + const spv::Op result_opcode = _.GetIdOpcode(result_type); switch (result_opcode) { - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { const uint32_t num_result_components = _.GetDimension(result_type); const uint32_t result_component_type = _.GetComponentType(result_type); uint32_t given_component_count = 0; @@ -230,7 +231,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, if (operand_type == result_component_type) { ++given_component_count; } else { - if (_.GetIdOpcode(operand_type) != SpvOpTypeVector || + if (_.GetIdOpcode(operand_type) != spv::Op::OpTypeVector || _.GetComponentType(operand_type) != result_component_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Constituents to be scalars or vectors of" @@ -249,7 +250,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { uint32_t result_num_rows = 0; uint32_t result_num_cols = 0; uint32_t result_col_type = 0; @@ -277,10 +278,10 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { const Instruction* const array_inst = _.FindDef(result_type); assert(array_inst); - assert(array_inst->opcode() == SpvOpTypeArray); + assert(array_inst->opcode() == spv::Op::OpTypeArray); auto size = _.FindDef(array_inst->word(3)); if (spvOpcodeIsSpecConstant(size->opcode())) { @@ -312,10 +313,10 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const Instruction* const struct_inst = _.FindDef(result_type); assert(struct_inst); - assert(struct_inst->opcode() == SpvOpTypeStruct); + assert(struct_inst->opcode() == spv::Op::OpTypeStruct); if (struct_inst->operands().size() + 1 != num_operands) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -336,7 +337,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case SpvOpTypeCooperativeMatrixNV: { + case spv::Op::OpTypeCooperativeMatrixNV: { const auto result_type_inst = _.FindDef(result_type); assert(result_type_inst); const auto component_type_id = @@ -362,7 +363,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, } } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot create a composite containing 8- or 16-bit types"; @@ -386,7 +387,7 @@ spv_result_t ValidateCompositeExtract(ValidationState_t& _, << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot extract from a composite of 8- or 16-bit types"; @@ -421,7 +422,7 @@ spv_result_t ValidateCompositeInsert(ValidationState_t& _, << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot insert into a composite of 8- or 16-bit types"; @@ -480,7 +481,7 @@ spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) { << "to be the reverse of those of Result Type"; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot transpose matrices of 16-bit floats"; @@ -491,11 +492,12 @@ spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateVectorShuffle(ValidationState_t& _, const Instruction* inst) { auto resultType = _.FindDef(inst->type_id()); - if (!resultType || resultType->opcode() != SpvOpTypeVector) { + if (!resultType || resultType->opcode() != spv::Op::OpTypeVector) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The Result Type of OpVectorShuffle must be" << " OpTypeVector. Found Op" - << spvOpcodeString(static_cast(resultType->opcode())) << "."; + << spvOpcodeString(static_cast(resultType->opcode())) + << "."; } // The number of components in Result Type must be the same as the number of @@ -515,11 +517,11 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _, auto vector1Type = _.FindDef(vector1Object->type_id()); auto vector2Object = _.FindDef(inst->GetOperandAs(3)); auto vector2Type = _.FindDef(vector2Object->type_id()); - if (!vector1Type || vector1Type->opcode() != SpvOpTypeVector) { + if (!vector1Type || vector1Type->opcode() != spv::Op::OpTypeVector) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The type of Vector 1 must be OpTypeVector."; } - if (!vector2Type || vector2Type->opcode() != SpvOpTypeVector) { + if (!vector2Type || vector2Type->opcode() != spv::Op::OpTypeVector) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The type of Vector 2 must be OpTypeVector."; } @@ -548,7 +550,7 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _, } } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot shuffle a vector of 8- or 16-bit types"; @@ -572,7 +574,7 @@ spv_result_t ValidateCopyLogical(ValidationState_t& _, << "Result Type does not logically match the Operand type"; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot copy composites of 8- or 16-bit types"; @@ -586,23 +588,23 @@ spv_result_t ValidateCopyLogical(ValidationState_t& _, // Validates correctness of composite instructions. spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpVectorExtractDynamic: + case spv::Op::OpVectorExtractDynamic: return ValidateVectorExtractDynamic(_, inst); - case SpvOpVectorInsertDynamic: + case spv::Op::OpVectorInsertDynamic: return ValidateVectorInsertDyanmic(_, inst); - case SpvOpVectorShuffle: + case spv::Op::OpVectorShuffle: return ValidateVectorShuffle(_, inst); - case SpvOpCompositeConstruct: + case spv::Op::OpCompositeConstruct: return ValidateCompositeConstruct(_, inst); - case SpvOpCompositeExtract: + case spv::Op::OpCompositeExtract: return ValidateCompositeExtract(_, inst); - case SpvOpCompositeInsert: + case spv::Op::OpCompositeInsert: return ValidateCompositeInsert(_, inst); - case SpvOpCopyObject: + case spv::Op::OpCopyObject: return ValidateCopyObject(_, inst); - case SpvOpTranspose: + case spv::Op::OpTranspose: return ValidateTranspose(_, inst); - case SpvOpCopyLogical: + case spv::Op::OpCopyLogical: return ValidateCopyLogical(_, inst); default: break; diff --git a/3rdparty/spirv-tools/source/val/validate_constants.cpp b/3rdparty/spirv-tools/source/val/validate_constants.cpp index fdfaea5f7..a8ee5a6b1 100644 --- a/3rdparty/spirv-tools/source/val/validate_constants.cpp +++ b/3rdparty/spirv-tools/source/val/validate_constants.cpp @@ -24,7 +24,7 @@ namespace { spv_result_t ValidateConstantBool(ValidationState_t& _, const Instruction* inst) { auto type = _.FindDef(inst->type_id()); - if (!type || type->opcode() != SpvOpTypeBool) { + if (!type || type->opcode() != spv::Op::OpTypeBool) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Op" << spvOpcodeString(inst->opcode()) << " Result Type " << _.getIdName(inst->type_id()) << " is not a boolean type."; @@ -46,7 +46,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, const auto constituent_count = inst->words().size() - 3; switch (result_type->opcode()) { - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { const auto component_count = result_type->GetOperandAs(2); if (component_count != constituent_count) { // TODO: Output ID's on diagnostic @@ -85,7 +85,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { const auto column_count = result_type->GetOperandAs(2); if (column_count != constituent_count) { // TODO: Output ID's on diagnostic @@ -155,7 +155,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { auto element_type = _.FindDef(result_type->GetOperandAs(1)); if (!element_type) { return _.diag(SPV_ERROR_INVALID_ID, result_type) @@ -203,7 +203,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const auto member_count = result_type->words().size() - 2; if (member_count != constituent_count) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -243,7 +243,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case SpvOpTypeCooperativeMatrixNV: { + case spv::Op::OpTypeCooperativeMatrixNV: { if (1 != constituent_count) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opcode_name << " Constituent " @@ -281,7 +281,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, spv_result_t ValidateConstantSampler(ValidationState_t& _, const Instruction* inst) { const auto result_type = _.FindDef(inst->type_id()); - if (!result_type || result_type->opcode() != SpvOpTypeSampler) { + if (!result_type || result_type->opcode() != spv::Op::OpTypeSampler) { return _.diag(SPV_ERROR_INVALID_ID, result_type) << "OpConstantSampler Result Type " << _.getIdName(inst->type_id()) << " is not a sampler type."; @@ -298,23 +298,23 @@ bool IsTypeNullable(const std::vector& instruction, uint16_t opcode; uint16_t word_count; spvOpcodeSplit(instruction[0], &word_count, &opcode); - switch (static_cast(opcode)) { - case SpvOpTypeBool: - case SpvOpTypeInt: - case SpvOpTypeFloat: - case SpvOpTypeEvent: - case SpvOpTypeDeviceEvent: - case SpvOpTypeReserveId: - case SpvOpTypeQueue: + switch (static_cast(opcode)) { + case spv::Op::OpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeEvent: + case spv::Op::OpTypeDeviceEvent: + case spv::Op::OpTypeReserveId: + case spv::Op::OpTypeQueue: return true; - case SpvOpTypeArray: - case SpvOpTypeMatrix: - case SpvOpTypeCooperativeMatrixNV: - case SpvOpTypeVector: { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeVector: { auto base_type = _.FindDef(instruction[2]); return base_type && IsTypeNullable(base_type->words(), _); } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { for (size_t elementIndex = 2; elementIndex < instruction.size(); ++elementIndex) { auto element = _.FindDef(instruction[elementIndex]); @@ -322,8 +322,9 @@ bool IsTypeNullable(const std::vector& instruction, } return true; } - case SpvOpTypePointer: - if (instruction[2] == SpvStorageClassPhysicalStorageBuffer) { + case spv::Op::OpTypePointer: + if (spv::StorageClass(instruction[2]) == + spv::StorageClass::PhysicalStorageBuffer) { return false; } return true; @@ -351,7 +352,8 @@ spv_result_t ValidateSpecConstant(ValidationState_t& _, auto type_id = inst->GetOperandAs(0); auto type_instruction = _.FindDef(type_id); auto type_opcode = type_instruction->opcode(); - if (type_opcode != SpvOpTypeInt && type_opcode != SpvOpTypeFloat) { + if (type_opcode != spv::Op::OpTypeInt && + type_opcode != spv::Op::OpTypeFloat) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Specialization constant " "must be an integer or " "floating-point number."; @@ -361,22 +363,22 @@ spv_result_t ValidateSpecConstant(ValidationState_t& _, spv_result_t ValidateSpecConstantOp(ValidationState_t& _, const Instruction* inst) { - const auto op = inst->GetOperandAs(2); + const auto op = inst->GetOperandAs(2); // The binary parser already ensures that the op is valid for *some* // environment. Here we check restrictions. switch (op) { - case SpvOpQuantizeToF16: - if (!_.HasCapability(SpvCapabilityShader)) { + case spv::Op::OpQuantizeToF16: + if (!_.HasCapability(spv::Capability::Shader)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Specialization constant operation " << spvOpcodeString(op) << " requires Shader capability"; } break; - case SpvOpUConvert: + case spv::Op::OpUConvert: if (!_.features().uconvert_spec_constant_op && - !_.HasCapability(SpvCapabilityKernel)) { + !_.HasCapability(spv::Capability::Kernel)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Prior to SPIR-V 1.4, specialization constant operation " "UConvert requires Kernel capability or extension " @@ -384,27 +386,27 @@ spv_result_t ValidateSpecConstantOp(ValidationState_t& _, } break; - case SpvOpConvertFToS: - case SpvOpConvertSToF: - case SpvOpConvertFToU: - case SpvOpConvertUToF: - case SpvOpConvertPtrToU: - case SpvOpConvertUToPtr: - case SpvOpGenericCastToPtr: - case SpvOpPtrCastToGeneric: - case SpvOpBitcast: - case SpvOpFNegate: - case SpvOpFAdd: - case SpvOpFSub: - case SpvOpFMul: - case SpvOpFDiv: - case SpvOpFRem: - case SpvOpFMod: - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpInBoundsPtrAccessChain: - if (!_.HasCapability(SpvCapabilityKernel)) { + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertUToF: + case spv::Op::OpConvertPtrToU: + case spv::Op::OpConvertUToPtr: + case spv::Op::OpGenericCastToPtr: + case spv::Op::OpPtrCastToGeneric: + case spv::Op::OpBitcast: + case spv::Op::OpFNegate: + case spv::Op::OpFAdd: + case spv::Op::OpFSub: + case spv::Op::OpFMul: + case spv::Op::OpFDiv: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + if (!_.HasCapability(spv::Capability::Kernel)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Specialization constant operation " << spvOpcodeString(op) << " requires Kernel capability"; @@ -423,26 +425,26 @@ spv_result_t ValidateSpecConstantOp(ValidationState_t& _, spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpConstantTrue: - case SpvOpConstantFalse: - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: if (auto error = ValidateConstantBool(_, inst)) return error; break; - case SpvOpConstantComposite: - case SpvOpSpecConstantComposite: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: if (auto error = ValidateConstantComposite(_, inst)) return error; break; - case SpvOpConstantSampler: + case spv::Op::OpConstantSampler: if (auto error = ValidateConstantSampler(_, inst)) return error; break; - case SpvOpConstantNull: + case spv::Op::OpConstantNull: if (auto error = ValidateConstantNull(_, inst)) return error; break; - case SpvOpSpecConstant: + case spv::Op::OpSpecConstant: if (auto error = ValidateSpecConstant(_, inst)) return error; break; - case SpvOpSpecConstantOp: + case spv::Op::OpSpecConstantOp: if (auto error = ValidateSpecConstantOp(_, inst)) return error; break; default: @@ -452,7 +454,7 @@ spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) { // Generally disallow creating 8- or 16-bit constants unless the full // capabilities are present. if (spvOpcodeIsConstant(inst->opcode()) && - _.HasCapability(SpvCapabilityShader) && + _.HasCapability(spv::Capability::Shader) && !_.IsPointerType(inst->type_id()) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) diff --git a/3rdparty/spirv-tools/source/val/validate_conversion.cpp b/3rdparty/spirv-tools/source/val/validate_conversion.cpp index dc6b15172..c67b19685 100644 --- a/3rdparty/spirv-tools/source/val/validate_conversion.cpp +++ b/3rdparty/spirv-tools/source/val/validate_conversion.cpp @@ -27,11 +27,11 @@ namespace val { // Validates correctness of conversion instructions. spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpConvertFToU: { + case spv::Op::OpConvertFToU: { if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type) && !_.IsUnsignedIntCooperativeMatrixType(result_type)) @@ -62,7 +62,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpConvertFToS: { + case spv::Op::OpConvertFToS: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && !_.IsIntCooperativeMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -92,8 +92,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpConvertSToF: - case SpvOpConvertUToF: { + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: { if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type) && !_.IsFloatCooperativeMatrixType(result_type)) @@ -124,7 +124,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpUConvert: { + case spv::Op::OpUConvert: { if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type) && !_.IsUnsignedIntCooperativeMatrixType(result_type)) @@ -160,7 +160,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpSConvert: { + case spv::Op::OpSConvert: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && !_.IsIntCooperativeMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -195,7 +195,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpFConvert: { + case spv::Op::OpFConvert: { if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type) && !_.IsFloatCooperativeMatrixType(result_type)) @@ -231,7 +231,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpQuantizeToF16: { + case spv::Op::OpQuantizeToF16: { if ((!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) || _.GetBitWidth(result_type) != 32) @@ -247,7 +247,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpConvertPtrToU: { + case spv::Op::OpConvertPtrToU: { if (!_.IsUnsignedIntScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected unsigned int scalar type as Result Type: " @@ -258,17 +258,18 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (_.addressing_model() == SpvAddressingModelLogical) + if (_.addressing_model() == spv::AddressingModel::Logical) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Logical addressing not supported: " << spvOpcodeString(opcode); - if (_.addressing_model() == SpvAddressingModelPhysicalStorageBuffer64) { - uint32_t input_storage_class = 0; + if (_.addressing_model() == + spv::AddressingModel::PhysicalStorageBuffer64) { + spv::StorageClass input_storage_class; uint32_t input_data_type = 0; _.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class); - if (input_storage_class != SpvStorageClassPhysicalStorageBuffer) + if (input_storage_class != spv::StorageClass::PhysicalStorageBuffer) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Pointer storage class must be PhysicalStorageBuffer: " << spvOpcodeString(opcode); @@ -286,8 +287,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpSatConvertSToU: - case SpvOpSatConvertUToS: { + case spv::Op::OpSatConvertSToU: + case spv::Op::OpSatConvertUToS: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " @@ -307,7 +308,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpConvertUToPtr: { + case spv::Op::OpConvertUToPtr: { if (!_.IsPointerType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be a pointer: " @@ -318,17 +319,18 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar as input: " << spvOpcodeString(opcode); - if (_.addressing_model() == SpvAddressingModelLogical) + if (_.addressing_model() == spv::AddressingModel::Logical) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Logical addressing not supported: " << spvOpcodeString(opcode); - if (_.addressing_model() == SpvAddressingModelPhysicalStorageBuffer64) { - uint32_t result_storage_class = 0; + if (_.addressing_model() == + spv::AddressingModel::PhysicalStorageBuffer64) { + spv::StorageClass result_storage_class; uint32_t result_data_type = 0; _.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class); - if (result_storage_class != SpvStorageClassPhysicalStorageBuffer) + if (result_storage_class != spv::StorageClass::PhysicalStorageBuffer) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Pointer storage class must be PhysicalStorageBuffer: " << spvOpcodeString(opcode); @@ -346,8 +348,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpPtrCastToGeneric: { - uint32_t result_storage_class = 0; + case spv::Op::OpPtrCastToGeneric: { + spv::StorageClass result_storage_class; uint32_t result_data_type = 0; if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) @@ -355,22 +357,22 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer: " << spvOpcodeString(opcode); - if (result_storage_class != SpvStorageClassGeneric) + if (result_storage_class != spv::StorageClass::Generic) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to have storage class Generic: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - uint32_t input_storage_class = 0; + spv::StorageClass input_storage_class; uint32_t input_data_type = 0; if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (input_storage_class != SpvStorageClassWorkgroup && - input_storage_class != SpvStorageClassCrossWorkgroup && - input_storage_class != SpvStorageClassFunction) + if (input_storage_class != spv::StorageClass::Workgroup && + input_storage_class != spv::StorageClass::CrossWorkgroup && + input_storage_class != spv::StorageClass::Function) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to have storage class Workgroup, " << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); @@ -382,8 +384,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpGenericCastToPtr: { - uint32_t result_storage_class = 0; + case spv::Op::OpGenericCastToPtr: { + spv::StorageClass result_storage_class; uint32_t result_data_type = 0; if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) @@ -391,22 +393,22 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer: " << spvOpcodeString(opcode); - if (result_storage_class != SpvStorageClassWorkgroup && - result_storage_class != SpvStorageClassCrossWorkgroup && - result_storage_class != SpvStorageClassFunction) + if (result_storage_class != spv::StorageClass::Workgroup && + result_storage_class != spv::StorageClass::CrossWorkgroup && + result_storage_class != spv::StorageClass::Function) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to have storage class Workgroup, " << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - uint32_t input_storage_class = 0; + spv::StorageClass input_storage_class; uint32_t input_data_type = 0; if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (input_storage_class != SpvStorageClassGeneric) + if (input_storage_class != spv::StorageClass::Generic) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to have storage class Generic: " << spvOpcodeString(opcode); @@ -418,8 +420,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpGenericCastToPtrExplicit: { - uint32_t result_storage_class = 0; + case spv::Op::OpGenericCastToPtrExplicit: { + spv::StorageClass result_storage_class; uint32_t result_data_type = 0; if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) @@ -427,21 +429,22 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer: " << spvOpcodeString(opcode); - const uint32_t target_storage_class = inst->word(4); + const auto target_storage_class = + inst->GetOperandAs(3); if (result_storage_class != target_storage_class) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be of target storage class: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - uint32_t input_storage_class = 0; + spv::StorageClass input_storage_class; uint32_t input_data_type = 0; if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (input_storage_class != SpvStorageClassGeneric) + if (input_storage_class != spv::StorageClass::Generic) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to have storage class Generic: " << spvOpcodeString(opcode); @@ -451,16 +454,16 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected input and Result Type to point to the same type: " << spvOpcodeString(opcode); - if (target_storage_class != SpvStorageClassWorkgroup && - target_storage_class != SpvStorageClassCrossWorkgroup && - target_storage_class != SpvStorageClassFunction) + if (target_storage_class != spv::StorageClass::Workgroup && + target_storage_class != spv::StorageClass::CrossWorkgroup && + target_storage_class != spv::StorageClass::Function) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected target storage class to be Workgroup, " << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); break; } - case SpvOpBitcast: { + case spv::Op::OpBitcast: { const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!input_type) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -490,10 +493,10 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { _.HasExtension(kSPV_KHR_physical_storage_buffer)) { const bool result_is_int_vector = _.IsIntVectorType(result_type); const bool result_has_int32 = - _.ContainsSizedIntOrFloatType(result_type, SpvOpTypeInt, 32); + _.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeInt, 32); const bool input_is_int_vector = _.IsIntVectorType(input_type); const bool input_has_int32 = - _.ContainsSizedIntOrFloatType(input_type, SpvOpTypeInt, 32); + _.ContainsSizedIntOrFloatType(input_type, spv::Op::OpTypeInt, 32); if (result_is_pointer && !input_is_pointer && !input_is_int_scalar && !(input_is_int_vector && input_has_int32)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -534,7 +537,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpConvertUToAccelerationStructureKHR: { + case spv::Op::OpConvertUToAccelerationStructureKHR: { if (!_.IsAccelerationStructureType(result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be a Acceleration Structure: " @@ -556,13 +559,13 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - if (_.HasCapability(SpvCapabilityShader)) { + if (_.HasCapability(spv::Capability::Shader)) { switch (inst->opcode()) { - case SpvOpConvertFToU: - case SpvOpConvertFToS: - case SpvOpConvertSToF: - case SpvOpConvertUToF: - case SpvOpBitcast: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: + case spv::Op::OpBitcast: if (_.ContainsLimitedUseIntOrFloatType(inst->type_id()) || _.ContainsLimitedUseIntOrFloatType(_.GetOperandTypeId(inst, 2u))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) diff --git a/3rdparty/spirv-tools/source/val/validate_debug.cpp b/3rdparty/spirv-tools/source/val/validate_debug.cpp index 7ab597a11..c433c939f 100644 --- a/3rdparty/spirv-tools/source/val/validate_debug.cpp +++ b/3rdparty/spirv-tools/source/val/validate_debug.cpp @@ -26,7 +26,7 @@ namespace { spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) { const auto type_id = inst->GetOperandAs(0); const auto type = _.FindDef(type_id); - if (!type || SpvOpTypeStruct != type->opcode()) { + if (!type || spv::Op::OpTypeStruct != type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpMemberName Type " << _.getIdName(type_id) << " is not a struct type."; @@ -45,7 +45,7 @@ spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) { const auto file_id = inst->GetOperandAs(0); const auto file = _.FindDef(file_id); - if (!file || SpvOpString != file->opcode()) { + if (!file || spv::Op::OpString != file->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpLine Target " << _.getIdName(file_id) << " is not an OpString."; @@ -57,10 +57,10 @@ spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) { spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpMemberName: + case spv::Op::OpMemberName: if (auto error = ValidateMemberName(_, inst)) return error; break; - case SpvOpLine: + case spv::Op::OpLine: if (auto error = ValidateLine(_, inst)) return error; break; default: diff --git a/3rdparty/spirv-tools/source/val/validate_decorations.cpp b/3rdparty/spirv-tools/source/val/validate_decorations.cpp index cd0ff209b..f9c843521 100644 --- a/3rdparty/spirv-tools/source/val/validate_decorations.cpp +++ b/3rdparty/spirv-tools/source/val/validate_decorations.cpp @@ -50,7 +50,7 @@ struct PairHash { // A functor for hashing decoration types. struct SpvDecorationHash { - std::size_t operator()(SpvDecoration dec) const { + std::size_t operator()(spv::Decoration dec) const { return static_cast(dec); } }; @@ -72,7 +72,7 @@ using MemberConstraints = std::unordered_map, // Returns the array stride of the given array type. uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) { for (auto& decoration : vstate.id_decorations(array_id)) { - if (SpvDecorationArrayStride == decoration.dec_type()) { + if (spv::Decoration::ArrayStride == decoration.dec_type()) { return decoration.params()[0]; } } @@ -82,9 +82,10 @@ uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) { // Returns true if the given variable has a BuiltIn decoration. bool isBuiltInVar(uint32_t var_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(var_id); - return std::any_of( - decorations.begin(), decorations.end(), - [](const Decoration& d) { return SpvDecorationBuiltIn == d.dec_type(); }); + return std::any_of(decorations.begin(), decorations.end(), + [](const Decoration& d) { + return spv::Decoration::BuiltIn == d.dec_type(); + }); } // Returns true if the given structure type has any members with BuiltIn @@ -93,7 +94,7 @@ bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(struct_id); return std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return SpvDecorationBuiltIn == d.dec_type() && + return spv::Decoration::BuiltIn == d.dec_type() && Decoration::kInvalidMember != d.struct_member_index(); }); } @@ -101,20 +102,21 @@ bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) { // Returns true if the given structure type has a Block decoration. bool isBlock(uint32_t struct_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(struct_id); - return std::any_of( - decorations.begin(), decorations.end(), - [](const Decoration& d) { return SpvDecorationBlock == d.dec_type(); }); + return std::any_of(decorations.begin(), decorations.end(), + [](const Decoration& d) { + return spv::Decoration::Block == d.dec_type(); + }); } // Returns true if the given ID has the Import LinkageAttributes decoration. bool hasImportLinkageAttribute(uint32_t id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(id); - return std::any_of(decorations.begin(), decorations.end(), - [](const Decoration& d) { - return SpvDecorationLinkageAttributes == d.dec_type() && - d.params().size() >= 2u && - d.params().back() == SpvLinkageTypeImport; - }); + return std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::LinkageAttributes == d.dec_type() && + d.params().size() >= 2u && + spv::LinkageType(d.params().back()) == spv::LinkageType::Import; + }); } // Returns a vector of all members of a structure. @@ -125,7 +127,7 @@ std::vector getStructMembers(uint32_t struct_id, } // Returns a vector of all members of a structure that have specific type. -std::vector getStructMembers(uint32_t struct_id, SpvOp type, +std::vector getStructMembers(uint32_t struct_id, spv::Op type, ValidationState_t& vstate) { std::vector members; for (auto id : getStructMembers(struct_id, vstate)) { @@ -142,21 +144,21 @@ bool isMissingOffsetInStruct(uint32_t struct_id, ValidationState_t& vstate) { const auto* inst = vstate.FindDef(struct_id); std::vector hasOffset; std::vector struct_members; - if (inst->opcode() == SpvOpTypeStruct) { + if (inst->opcode() == spv::Op::OpTypeStruct) { // Check offsets of member decorations. struct_members = getStructMembers(struct_id, vstate); hasOffset.resize(struct_members.size(), false); for (auto& decoration : vstate.id_decorations(struct_id)) { - if (SpvDecorationOffset == decoration.dec_type() && + if (spv::Decoration::Offset == decoration.dec_type() && Decoration::kInvalidMember != decoration.struct_member_index()) { // Offset 0xffffffff is not valid so ignore it for simplicity's sake. if (decoration.params()[0] == 0xffffffff) return true; hasOffset[decoration.struct_member_index()] = true; } } - } else if (inst->opcode() == SpvOpTypeArray || - inst->opcode() == SpvOpTypeRuntimeArray) { + } else if (inst->opcode() == spv::Op::OpTypeArray || + inst->opcode() == spv::Op::OpTypeRuntimeArray) { hasOffset.resize(1, true); struct_members.push_back(inst->GetOperandAs(1u)); } @@ -191,18 +193,18 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, // Minimal alignment is byte-aligned. uint32_t baseAlignment = 1; switch (inst->opcode()) { - case SpvOpTypeSampledImage: - case SpvOpTypeSampler: - case SpvOpTypeImage: - if (vstate.HasCapability(SpvCapabilityBindlessTextureNV)) + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) return baseAlignment = vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; - case SpvOpTypeInt: - case SpvOpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: baseAlignment = words[2] / 8; break; - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { const auto componentId = words[2]; const auto numComponents = words[3]; const auto componentAlignment = getBaseAlignment( @@ -211,7 +213,7 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, componentAlignment * (numComponents == 3 ? 4 : numComponents); break; } - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { const auto column_type = words[2]; if (inherited.majorness == kColumnMajor) { baseAlignment = getBaseAlignment(column_type, roundUp, inherited, @@ -229,13 +231,13 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, } if (roundUp) baseAlignment = align(baseAlignment, 16u); } break; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: baseAlignment = getBaseAlignment(words[2], roundUp, inherited, constraints, vstate); if (roundUp) baseAlignment = align(baseAlignment, 16u); break; - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const auto members = getStructMembers(member_id, vstate); for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); memberIdx < numMembers; ++memberIdx) { @@ -249,7 +251,7 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, if (roundUp) baseAlignment = align(baseAlignment, 16u); break; } - case SpvOpTypePointer: + case spv::Op::OpTypePointer: baseAlignment = vstate.pointer_size_and_alignment(); break; default: @@ -265,24 +267,24 @@ uint32_t getScalarAlignment(uint32_t type_id, ValidationState_t& vstate) { const auto inst = vstate.FindDef(type_id); const auto& words = inst->words(); switch (inst->opcode()) { - case SpvOpTypeSampledImage: - case SpvOpTypeSampler: - case SpvOpTypeImage: - if (vstate.HasCapability(SpvCapabilityBindlessTextureNV)) + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) return vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; - case SpvOpTypeInt: - case SpvOpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: return words[2] / 8; - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: { + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: { const auto compositeMemberTypeId = words[2]; return getScalarAlignment(compositeMemberTypeId, vstate); } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const auto members = getStructMembers(type_id, vstate); uint32_t max_member_alignment = 1; for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); @@ -295,7 +297,7 @@ uint32_t getScalarAlignment(uint32_t type_id, ValidationState_t& vstate) { } return max_member_alignment; } break; - case SpvOpTypePointer: + case spv::Op::OpTypePointer: return vstate.pointer_size_and_alignment(); default: assert(0); @@ -312,17 +314,17 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, const auto inst = vstate.FindDef(member_id); const auto& words = inst->words(); switch (inst->opcode()) { - case SpvOpTypeSampledImage: - case SpvOpTypeSampler: - case SpvOpTypeImage: - if (vstate.HasCapability(SpvCapabilityBindlessTextureNV)) + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) return vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; - case SpvOpTypeInt: - case SpvOpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: return words[2] / 8; - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { const auto componentId = words[2]; const auto numComponents = words[3]; const auto componentSize = @@ -330,10 +332,10 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, const auto size = componentSize * numComponents; return size; } - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { const auto sizeInst = vstate.FindDef(words[3]); if (spvOpcodeIsSpecConstant(sizeInst->opcode())) return 0; - assert(SpvOpConstant == sizeInst->opcode()); + assert(spv::Op::OpConstant == sizeInst->opcode()); const uint32_t num_elem = sizeInst->words()[3]; const uint32_t elem_type = words[2]; const uint32_t elem_size = @@ -344,9 +346,9 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, (num_elem - 1) * GetArrayStride(member_id, vstate) + elem_size; return size; } - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeRuntimeArray: return 0; - case SpvOpTypeMatrix: { + case spv::Op::OpTypeMatrix: { const auto num_columns = words[3]; if (inherited.majorness == kColumnMajor) { return num_columns * inherited.matrix_stride; @@ -362,7 +364,7 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, num_columns * scalar_elem_size; } } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { const auto& members = getStructMembers(member_id, vstate); if (members.empty()) return 0; const auto lastIdx = uint32_t(members.size() - 1); @@ -374,7 +376,7 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, for (auto decoration = member_decorations.begin; decoration != member_decorations.end; ++decoration) { assert(decoration->struct_member_index() == (int)lastIdx); - if (SpvDecorationOffset == decoration->dec_type()) { + if (spv::Decoration::Offset == decoration->dec_type()) { offset = decoration->params()[0]; } } @@ -384,7 +386,7 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, const auto& constraint = constraints[std::make_pair(lastMember, lastIdx)]; return offset + getSize(lastMember, constraint, constraints, vstate); } - case SpvOpTypePointer: + case spv::Op::OpTypePointer: return vstate.pointer_size_and_alignment(); default: assert(0); @@ -477,7 +479,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, decoration != member_decorations.end; ++decoration) { assert(decoration->struct_member_index() == (int)memberIdx); switch (decoration->dec_type()) { - case SpvDecorationOffset: + case spv::Decoration::Offset: offset = decoration->params()[0]; break; default: @@ -517,7 +519,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, if (offset == 0xffffffff) return fail(memberIdx) << "is missing an Offset decoration"; if (!scalar_block_layout && relaxed_block_layout && - opcode == SpvOpTypeVector) { + opcode == spv::Op::OpTypeVector) { // In relaxed block layout, the vector offset must be aligned to the // vector's scalar element type. const auto componentId = inst->words()[2]; @@ -541,21 +543,20 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, << nextValidOffset - 1; if (!scalar_block_layout && relaxed_block_layout) { // Check improper straddle of vectors. - if (SpvOpTypeVector == opcode && + if (spv::Op::OpTypeVector == opcode && hasImproperStraddle(id, offset, constraint, constraints, vstate)) return fail(memberIdx) << "is an improperly straddling vector at offset " << offset; } // Check struct members recursively. spv_result_t recursive_status = SPV_SUCCESS; - if (SpvOpTypeStruct == opcode && + if (spv::Op::OpTypeStruct == opcode && SPV_SUCCESS != (recursive_status = checkLayout( id, storage_class_str, decoration_str, blockRules, - scalar_block_layout, - offset, constraints, vstate))) + scalar_block_layout, offset, constraints, vstate))) return recursive_status; // Check matrix stride. - if (SpvOpTypeMatrix == opcode) { + if (spv::Op::OpTypeMatrix == opcode) { const auto stride = constraint.matrix_stride; if (!IsAlignedTo(stride, alignment)) { return fail(memberIdx) << "is a matrix with stride " << stride @@ -566,14 +567,14 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, // Check arrays and runtime arrays recursively. auto array_inst = inst; auto array_alignment = alignment; - while (array_inst->opcode() == SpvOpTypeArray || - array_inst->opcode() == SpvOpTypeRuntimeArray) { + while (array_inst->opcode() == spv::Op::OpTypeArray || + array_inst->opcode() == spv::Op::OpTypeRuntimeArray) { const auto typeId = array_inst->word(2); const auto element_inst = vstate.FindDef(typeId); // Check array stride. uint32_t array_stride = 0; for (auto& decoration : vstate.id_decorations(array_inst->id())) { - if (SpvDecorationArrayStride == decoration.dec_type()) { + if (spv::Decoration::ArrayStride == decoration.dec_type()) { array_stride = decoration.params()[0]; if (array_stride == 0) { return fail(memberIdx) << "contains an array with stride 0"; @@ -588,7 +589,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, bool is_int32 = false; bool is_const = false; uint32_t num_elements = 0; - if (array_inst->opcode() == SpvOpTypeArray) { + if (array_inst->opcode() == spv::Op::OpTypeArray) { std::tie(is_int32, is_const, num_elements) = vstate.EvalInt32IfConst(array_inst->word(3)); } @@ -597,7 +598,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, // limitation to this check if the array size is a spec constant or is a // runtime array then we will only check a single element. This means // some improper straddles might be missed. - if (SpvOpTypeStruct == element_inst->opcode()) { + if (spv::Op::OpTypeStruct == element_inst->opcode()) { std::vector seen(16, false); for (uint32_t i = 0; i < num_elements; ++i) { uint32_t next_offset = i * array_stride + offset; @@ -632,10 +633,10 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, } } nextValidOffset = offset + size; - if (!scalar_block_layout && blockRules && - (SpvOpTypeArray == opcode || SpvOpTypeStruct == opcode)) { - // Uniform block rules don't permit anything in the padding of a struct - // or array. + if (!scalar_block_layout && + (spv::Op::OpTypeArray == opcode || spv::Op::OpTypeStruct == opcode)) { + // Non-scalar block layout rules don't permit anything in the padding of + // a struct or array. nextValidOffset = align(nextValidOffset, alignment); } } @@ -644,15 +645,15 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, // Returns true if variable or structure id has given decoration. Handles also // nested structures. -bool hasDecoration(uint32_t id, SpvDecoration decoration, +bool hasDecoration(uint32_t id, spv::Decoration decoration, ValidationState_t& vstate) { for (auto& dec : vstate.id_decorations(id)) { if (decoration == dec.dec_type()) return true; } - if (SpvOpTypeStruct != vstate.FindDef(id)->opcode()) { + if (spv::Op::OpTypeStruct != vstate.FindDef(id)->opcode()) { return false; } - for (auto member_id : getStructMembers(id, SpvOpTypeStruct, vstate)) { + for (auto member_id : getStructMembers(id, spv::Op::OpTypeStruct, vstate)) { if (hasDecoration(member_id, decoration, vstate)) { return true; } @@ -662,8 +663,8 @@ bool hasDecoration(uint32_t id, SpvDecoration decoration, // Returns true if all ids of given type have a specified decoration. bool checkForRequiredDecoration(uint32_t struct_id, - std::function checker, - SpvOp type, ValidationState_t& vstate) { + std::function checker, + spv::Op type, ValidationState_t& vstate) { const auto& members = getStructMembers(struct_id, vstate); for (size_t memberIdx = 0; memberIdx < members.size(); memberIdx++) { const auto id = members[memberIdx]; @@ -682,7 +683,7 @@ bool checkForRequiredDecoration(uint32_t struct_id, return false; } } - for (auto id : getStructMembers(struct_id, SpvOpTypeStruct, vstate)) { + for (auto id : getStructMembers(struct_id, spv::Op::OpTypeStruct, vstate)) { if (!checkForRequiredDecoration(id, checker, type, vstate)) { return false; } @@ -738,8 +739,8 @@ spv_result_t CheckBuiltInVariable(uint32_t var_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(var_id); for (const auto& d : decorations) { if (spvIsVulkanEnv(vstate.context()->target_env)) { - if (d.dec_type() == SpvDecorationLocation || - d.dec_type() == SpvDecorationComponent) { + if (d.dec_type() == spv::Decoration::Location || + d.dec_type() == spv::Decoration::Component) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(4915) << "A BuiltIn variable (id " << var_id << ") cannot have any Location or Component decorations"; @@ -762,18 +763,18 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { std::unordered_set seen_vars; for (auto interface : desc.interfaces) { Instruction* var_instr = vstate.FindDef(interface); - if (!var_instr || SpvOpVariable != var_instr->opcode()) { + if (!var_instr || spv::Op::OpVariable != var_instr->opcode()) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << "Interfaces passed to OpEntryPoint must be of type " "OpTypeVariable. Found Op" << spvOpcodeString(var_instr->opcode()) << "."; } - const SpvStorageClass storage_class = - var_instr->GetOperandAs(2); + const spv::StorageClass storage_class = + var_instr->GetOperandAs(2); if (vstate.version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { // Starting in 1.4, OpEntryPoint must list all global variables // it statically uses and those interfaces must be unique. - if (storage_class == SpvStorageClassFunction) { + if (storage_class == spv::StorageClass::Function) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << "OpEntryPoint interfaces should only list global " "variables"; @@ -785,14 +786,14 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { << vstate.getIdName(interface) << " is disallowed"; } } else { - if (storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << "OpEntryPoint interfaces must be OpVariables with " "Storage Class of Input(1) or Output(3). Found Storage " "Class " - << storage_class << " for Entry Point id " << entry_point - << "."; + << uint32_t(storage_class) << " for Entry Point id " + << entry_point << "."; } } @@ -803,7 +804,7 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { // to. const uint32_t type_id = ptr_instr->word(3); Instruction* type_instr = vstate.FindDef(type_id); - if (type_instr && SpvOpTypeStruct == type_instr->opcode() && + if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode() && isBuiltInStruct(type_id, vstate)) { if (!isBlock(type_id, vstate)) { return vstate.diag(SPV_ERROR_INVALID_DATA, vstate.FindDef(type_id)) @@ -814,8 +815,9 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { "OpVariable with a structure type that is a block not " "decorated with Location."; } - if (storage_class == SpvStorageClassInput) ++num_builtin_block_inputs; - if (storage_class == SpvStorageClassOutput) + if (storage_class == spv::StorageClass::Input) + ++num_builtin_block_inputs; + if (storage_class == spv::StorageClass::Output) ++num_builtin_block_outputs; if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) break; @@ -826,12 +828,13 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { return error; } - if (storage_class == SpvStorageClassWorkgroup) { + if (storage_class == spv::StorageClass::Workgroup) { ++num_workgroup_variables; - if (type_instr && SpvOpTypeStruct == type_instr->opcode()) { - if (hasDecoration(type_id, SpvDecorationBlock, vstate)) + if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode()) { + if (hasDecoration(type_id, spv::Decoration::Block, vstate)) ++num_workgroup_variables_with_block; - if (hasDecoration(var_instr->id(), SpvDecorationAliased, vstate)) + if (hasDecoration(var_instr->id(), spv::Decoration::Aliased, + vstate)) ++num_workgroup_variables_with_aliased; } } @@ -839,17 +842,17 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { if (spvIsVulkanEnv(vstate.context()->target_env)) { const auto* models = vstate.GetExecutionModels(entry_point); const bool has_frag = - models->find(SpvExecutionModelFragment) != models->end(); + models->find(spv::ExecutionModel::Fragment) != models->end(); const bool has_vert = - models->find(SpvExecutionModelVertex) != models->end(); + models->find(spv::ExecutionModel::Vertex) != models->end(); for (const auto& decoration : vstate.id_decorations(var_instr->id())) { - if (decoration == SpvDecorationFlat || - decoration == SpvDecorationNoPerspective || - decoration == SpvDecorationSample || - decoration == SpvDecorationCentroid) { + if (decoration == spv::Decoration::Flat || + decoration == spv::Decoration::NoPerspective || + decoration == spv::Decoration::Sample || + decoration == spv::Decoration::Centroid) { // VUID 04670 already validates these decorations are input/output - if (storage_class == SpvStorageClassInput && + if (storage_class == spv::StorageClass::Input && (models->size() > 1 || has_vert)) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << vstate.VkErrorID(6202) @@ -858,7 +861,7 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { "execution model as an Input storage class for Entry " "Point id " << entry_point << "."; - } else if (storage_class == SpvStorageClassOutput && + } else if (storage_class == spv::StorageClass::Output && (models->size() > 1 || has_frag)) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << vstate.VkErrorID(6201) @@ -872,8 +875,9 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { } const bool has_flat = - hasDecoration(var_instr->id(), SpvDecorationFlat, vstate); - if (has_frag && storage_class == SpvStorageClassInput && !has_flat && + hasDecoration(var_instr->id(), spv::Decoration::Flat, vstate); + if (has_frag && storage_class == spv::StorageClass::Input && + !has_flat && ((vstate.IsFloatScalarType(type_id) && vstate.GetBitWidth(type_id) == 64) || vstate.IsIntScalarOrVectorType(type_id))) { @@ -898,7 +902,7 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { // The LinkageAttributes Decoration cannot be applied to functions // targeted by an OpEntryPoint instruction for (auto& decoration : vstate.id_decorations(entry_point)) { - if (SpvDecorationLinkageAttributes == decoration.dec_type()) { + if (spv::Decoration::LinkageAttributes == decoration.dec_type()) { const std::string linkage_name = spvtools::utils::MakeString(decoration.params()); return vstate.diag(SPV_ERROR_INVALID_BINARY, @@ -910,7 +914,8 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { } } - if (vstate.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR) && + if (vstate.HasCapability( + spv::Capability::WorkgroupMemoryExplicitLayoutKHR) && num_workgroup_variables > 0 && num_workgroup_variables_with_block > 0) { if (num_workgroup_variables != num_workgroup_variables_with_block) { @@ -964,13 +969,13 @@ void ComputeMemberConstraintsForStruct(MemberConstraints* constraints, decoration != member_decorations.end; ++decoration) { assert(decoration->struct_member_index() == (int)memberIdx); switch (decoration->dec_type()) { - case SpvDecorationRowMajor: + case spv::Decoration::RowMajor: constraint.majorness = kRowMajor; break; - case SpvDecorationColMajor: + case spv::Decoration::ColMajor: constraint.majorness = kColumnMajor; break; - case SpvDecorationMatrixStride: + case spv::Decoration::MatrixStride: constraint.matrix_stride = decoration->params()[0]; break; default: @@ -983,12 +988,12 @@ void ComputeMemberConstraintsForStruct(MemberConstraints* constraints, const auto member_type_inst = vstate.FindDef(member_type_id); const auto opcode = member_type_inst->opcode(); switch (opcode) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: ComputeMemberConstraintsForArray(constraints, member_type_id, inherited, vstate); break; - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: ComputeMemberConstraintsForStruct(constraints, member_type_id, inherited, vstate); break; @@ -1007,12 +1012,12 @@ void ComputeMemberConstraintsForArray(MemberConstraints* constraints, const auto elem_type_inst = vstate.FindDef(elem_type_id); const auto opcode = elem_type_inst->opcode(); switch (opcode) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: ComputeMemberConstraintsForArray(constraints, elem_type_id, inherited, vstate); break; - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: ComputeMemberConstraintsForStruct(constraints, elem_type_id, inherited, vstate); break; @@ -1026,16 +1031,18 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { std::unordered_set uses_push_constant; for (const auto& inst : vstate.ordered_instructions()) { const auto& words = inst.words(); - if (SpvOpVariable == inst.opcode()) { + if (spv::Op::OpVariable == inst.opcode()) { const auto var_id = inst.id(); // For storage class / decoration combinations, see Vulkan 14.5.4 "Offset // and Stride Assignment". - const auto storageClass = words[3]; - const bool uniform = storageClass == SpvStorageClassUniform; + const auto storageClass = inst.GetOperandAs(2); + const bool uniform = storageClass == spv::StorageClass::Uniform; const bool uniform_constant = - storageClass == SpvStorageClassUniformConstant; - const bool push_constant = storageClass == SpvStorageClassPushConstant; - const bool storage_buffer = storageClass == SpvStorageClassStorageBuffer; + storageClass == spv::StorageClass::UniformConstant; + const bool push_constant = + storageClass == spv::StorageClass::PushConstant; + const bool storage_buffer = + storageClass == spv::StorageClass::StorageBuffer; if (spvIsVulkanEnv(vstate.context()->target_env)) { // Vulkan: There must be no more than one PushConstant block per entry @@ -1059,7 +1066,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { if (uniform_constant) { auto entry_points = vstate.EntryPointReferences(var_id); if (!entry_points.empty() && - !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) { + !hasDecoration(var_id, spv::Decoration::DescriptorSet, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id << "' is missing DescriptorSet decoration.\n" @@ -1068,7 +1075,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { "decorations specified"; } if (!entry_points.empty() && - !hasDecoration(var_id, SpvDecorationBinding, vstate)) { + !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id << "' is missing Binding decoration.\n" @@ -1080,14 +1087,14 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } if (spvIsOpenGLEnv(vstate.context()->target_env)) { - bool has_block = hasDecoration(var_id, SpvDecorationBlock, vstate); + bool has_block = hasDecoration(var_id, spv::Decoration::Block, vstate); bool has_buffer_block = - hasDecoration(var_id, SpvDecorationBufferBlock, vstate); + hasDecoration(var_id, spv::Decoration::BufferBlock, vstate); if ((uniform && (has_block || has_buffer_block)) || (storage_buffer && has_block)) { auto entry_points = vstate.EntryPointReferences(var_id); if (!entry_points.empty() && - !hasDecoration(var_id, SpvDecorationBinding, vstate)) { + !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << (uniform ? "Uniform" : "Storage Buffer") << " id '" << var_id << "' is missing Binding decoration.\n" @@ -1099,24 +1106,25 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } const bool phys_storage_buffer = - storageClass == SpvStorageClassPhysicalStorageBuffer; + storageClass == spv::StorageClass::PhysicalStorageBuffer; const bool workgroup = - storageClass == SpvStorageClassWorkgroup && - vstate.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR); + storageClass == spv::StorageClass::Workgroup && + vstate.HasCapability( + spv::Capability::WorkgroupMemoryExplicitLayoutKHR); if (uniform || push_constant || storage_buffer || phys_storage_buffer || workgroup) { const auto ptrInst = vstate.FindDef(words[1]); - assert(SpvOpTypePointer == ptrInst->opcode()); + assert(spv::Op::OpTypePointer == ptrInst->opcode()); auto id = ptrInst->words()[3]; auto id_inst = vstate.FindDef(id); // Jump through one level of arraying. - if (!workgroup && (id_inst->opcode() == SpvOpTypeArray || - id_inst->opcode() == SpvOpTypeRuntimeArray)) { + if (!workgroup && (id_inst->opcode() == spv::Op::OpTypeArray || + id_inst->opcode() == spv::Op::OpTypeRuntimeArray)) { id = id_inst->GetOperandAs(1u); id_inst = vstate.FindDef(id); } // Struct requirement is checked on variables so just move on here. - if (SpvOpTypeStruct != id_inst->opcode()) continue; + if (spv::Op::OpTypeStruct != id_inst->opcode()) continue; MemberConstraints constraints; ComputeMemberConstraintsForStruct(&constraints, id, LayoutConstraints(), vstate); @@ -1128,9 +1136,9 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { : "StorageBuffer")); if (spvIsVulkanEnv(vstate.context()->target_env)) { - const bool block = hasDecoration(id, SpvDecorationBlock, vstate); + const bool block = hasDecoration(id, spv::Decoration::Block, vstate); const bool buffer_block = - hasDecoration(id, SpvDecorationBufferBlock, vstate); + hasDecoration(id, spv::Decoration::BufferBlock, vstate); if (storage_buffer && buffer_block) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6675) << "Storage buffer id '" << var_id @@ -1168,7 +1176,8 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { if (uniform || storage_buffer) { auto entry_points = vstate.EntryPointReferences(var_id); if (!entry_points.empty() && - !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) { + !hasDecoration(var_id, spv::Decoration::DescriptorSet, + vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << sc_str << " id '" << var_id << "' is missing DescriptorSet decoration.\n" @@ -1177,7 +1186,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { "decorations specified"; } if (!entry_points.empty() && - !hasDecoration(var_id, SpvDecorationBinding, vstate)) { + !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << sc_str << " id '" << var_id << "' is missing Binding decoration.\n" @@ -1189,8 +1198,9 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } for (const auto& dec : vstate.id_decorations(id)) { - const bool blockDeco = SpvDecorationBlock == dec.dec_type(); - const bool bufferDeco = SpvDecorationBufferBlock == dec.dec_type(); + const bool blockDeco = spv::Decoration::Block == dec.dec_type(); + const bool bufferDeco = + spv::Decoration::BufferBlock == dec.dec_type(); const bool blockRules = uniform && blockDeco; const bool bufferRules = (uniform && bufferDeco) || @@ -1220,24 +1230,24 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { "decorations."; } - if (!checkForRequiredDecoration(id, - [](SpvDecoration d) { - return d == - SpvDecorationArrayStride; - }, - SpvOpTypeArray, vstate)) { + if (!checkForRequiredDecoration( + id, + [](spv::Decoration d) { + return d == spv::Decoration::ArrayStride; + }, + spv::Op::OpTypeArray, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with ArrayStride " "decorations."; } - if (!checkForRequiredDecoration(id, - [](SpvDecoration d) { - return d == - SpvDecorationMatrixStride; - }, - SpvOpTypeMatrix, vstate)) { + if (!checkForRequiredDecoration( + id, + [](spv::Decoration d) { + return d == spv::Decoration::MatrixStride; + }, + spv::Op::OpTypeMatrix, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with MatrixStride " @@ -1246,11 +1256,11 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { if (!checkForRequiredDecoration( id, - [](SpvDecoration d) { - return d == SpvDecorationRowMajor || - d == SpvDecorationColMajor; + [](spv::Decoration d) { + return d == spv::Decoration::RowMajor || + d == spv::Decoration::ColMajor; }, - SpvOpTypeMatrix, vstate)) { + spv::Op::OpTypeMatrix, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with RowMajor or " @@ -1280,18 +1290,18 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } // Returns true if |decoration| cannot be applied to the same id more than once. -bool AtMostOncePerId(SpvDecoration decoration) { - return decoration == SpvDecorationArrayStride; +bool AtMostOncePerId(spv::Decoration decoration) { + return decoration == spv::Decoration::ArrayStride; } // Returns true if |decoration| cannot be applied to the same member more than // once. -bool AtMostOncePerMember(SpvDecoration decoration) { +bool AtMostOncePerMember(spv::Decoration decoration) { switch (decoration) { - case SpvDecorationOffset: - case SpvDecorationMatrixStride: - case SpvDecorationRowMajor: - case SpvDecorationColMajor: + case spv::Decoration::Offset: + case spv::Decoration::MatrixStride: + case spv::Decoration::RowMajor: + case spv::Decoration::ColMajor: return true; default: return false; @@ -1299,32 +1309,32 @@ bool AtMostOncePerMember(SpvDecoration decoration) { } spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { - using PerIDKey = std::tuple; - using PerMemberKey = std::tuple; + using PerIDKey = std::tuple; + using PerMemberKey = std::tuple; // An Array of pairs where the decorations in the pair cannot both be applied // to the same id. - static const SpvDecoration mutually_exclusive_per_id[][2] = { - {SpvDecorationBlock, SpvDecorationBufferBlock}, - {SpvDecorationRestrict, SpvDecorationAliased}}; + static const spv::Decoration mutually_exclusive_per_id[][2] = { + {spv::Decoration::Block, spv::Decoration::BufferBlock}, + {spv::Decoration::Restrict, spv::Decoration::Aliased}}; static const auto num_mutually_exclusive_per_id_pairs = - sizeof(mutually_exclusive_per_id) / (2 * sizeof(SpvDecoration)); + sizeof(mutually_exclusive_per_id) / (2 * sizeof(spv::Decoration)); // An Array of pairs where the decorations in the pair cannot both be applied // to the same member. - static const SpvDecoration mutually_exclusive_per_member[][2] = { - {SpvDecorationRowMajor, SpvDecorationColMajor}}; + static const spv::Decoration mutually_exclusive_per_member[][2] = { + {spv::Decoration::RowMajor, spv::Decoration::ColMajor}}; static const auto num_mutually_exclusive_per_mem_pairs = - sizeof(mutually_exclusive_per_member) / (2 * sizeof(SpvDecoration)); + sizeof(mutually_exclusive_per_member) / (2 * sizeof(spv::Decoration)); std::set seen_per_id; std::set seen_per_member; for (const auto& inst : vstate.ordered_instructions()) { const auto& words = inst.words(); - if (SpvOpDecorate == inst.opcode()) { + if (spv::Op::OpDecorate == inst.opcode()) { const auto id = words[1]; - const auto dec_type = static_cast(words[2]); + const auto dec_type = static_cast(words[2]); const auto k = PerIDKey(dec_type, id); const auto already_used = !seen_per_id.insert(k).second; if (already_used && AtMostOncePerId(dec_type)) { @@ -1337,7 +1347,7 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { // an ID. for (uint32_t pair_idx = 0; pair_idx < num_mutually_exclusive_per_id_pairs; ++pair_idx) { - SpvDecoration excl_dec_type = SpvDecorationMax; + spv::Decoration excl_dec_type = spv::Decoration::Max; if (mutually_exclusive_per_id[pair_idx][0] == dec_type) { excl_dec_type = mutually_exclusive_per_id[pair_idx][1]; } else if (mutually_exclusive_per_id[pair_idx][1] == dec_type) { @@ -1355,10 +1365,10 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { << " is not allowed."; } } - } else if (SpvOpMemberDecorate == inst.opcode()) { + } else if (spv::Op::OpMemberDecorate == inst.opcode()) { const auto id = words[1]; const auto member_id = words[2]; - const auto dec_type = static_cast(words[3]); + const auto dec_type = static_cast(words[3]); const auto k = PerMemberKey(dec_type, id, member_id); const auto already_used = !seen_per_member.insert(k).second; if (already_used && AtMostOncePerMember(dec_type)) { @@ -1371,7 +1381,7 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { // a (ID, member) tuple. for (uint32_t pair_idx = 0; pair_idx < num_mutually_exclusive_per_mem_pairs; ++pair_idx) { - SpvDecoration excl_dec_type = SpvDecorationMax; + spv::Decoration excl_dec_type = spv::Decoration::Max; if (mutually_exclusive_per_member[pair_idx][0] == dec_type) { excl_dec_type = mutually_exclusive_per_member[pair_idx][1]; } else if (mutually_exclusive_per_member[pair_idx][1] == dec_type) { @@ -1397,7 +1407,7 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { spv_result_t CheckVulkanMemoryModelDeprecatedDecorations( ValidationState_t& vstate) { - if (vstate.memory_model() != SpvMemoryModelVulkanKHR) return SPV_SUCCESS; + if (vstate.memory_model() != spv::MemoryModel::VulkanKHR) return SPV_SUCCESS; std::string msg; std::ostringstream str(msg); @@ -1406,10 +1416,10 @@ spv_result_t CheckVulkanMemoryModelDeprecatedDecorations( const auto id = inst->id(); for (const auto& dec : vstate.id_decorations(id)) { const auto member = dec.struct_member_index(); - if (dec.dec_type() == SpvDecorationCoherent || - dec.dec_type() == SpvDecorationVolatile) { - str << (dec.dec_type() == SpvDecorationCoherent ? "Coherent" - : "Volatile"); + if (dec.dec_type() == spv::Decoration::Coherent || + dec.dec_type() == spv::Decoration::Volatile) { + str << (dec.dec_type() == spv::Decoration::Coherent ? "Coherent" + : "Volatile"); str << " decoration targeting " << vstate.getIdName(id); if (member != Decoration::kInvalidMember) { str << " (member index " << member << ")"; @@ -1430,7 +1440,7 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, const Decoration& decoration) { // Validates width-only conversion instruction for floating-point object // i.e., OpFConvert - if (inst.opcode() != SpvOpFConvert) { + if (inst.opcode() != spv::Op::OpFConvert) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "FPRoundingMode decoration can be applied only to a " "width-only conversion instruction for floating-point " @@ -1438,8 +1448,9 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, } if (spvIsVulkanEnv(vstate.context()->target_env)) { - const auto mode = decoration.params()[0]; - if ((mode != SpvFPRoundingModeRTE) && (mode != SpvFPRoundingModeRTZ)) { + const auto mode = spv::FPRoundingMode(decoration.params()[0]); + if ((mode != spv::FPRoundingMode::RTE) && + (mode != spv::FPRoundingMode::RTZ)) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << vstate.VkErrorID(4675) << "In Vulkan, the FPRoundingMode mode must only by RTE or RTZ."; @@ -1449,11 +1460,11 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, // Validates Object operand of an OpStore for (const auto& use : inst.uses()) { const auto store = use.first; - if (store->opcode() == SpvOpFConvert) continue; + if (store->opcode() == spv::Op::OpFConvert) continue; if (spvOpcodeIsDebug(store->opcode())) continue; if (store->IsNonSemantic()) continue; if (spvOpcodeIsDecoration(store->opcode())) continue; - if (store->opcode() != SpvOpStore) { + if (store->opcode() != spv::Op::OpStore) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "FPRoundingMode decoration can be applied only to the " "Object operand of an OpStore."; @@ -1479,12 +1490,13 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, } // Validates storage class of the pointer to the OpStore - const auto storage = ptr_type->GetOperandAs(1); - if (storage != SpvStorageClassStorageBuffer && - storage != SpvStorageClassUniform && - storage != SpvStorageClassPushConstant && - storage != SpvStorageClassInput && storage != SpvStorageClassOutput && - storage != SpvStorageClassPhysicalStorageBuffer) { + const auto storage = ptr_type->GetOperandAs(1); + if (storage != spv::StorageClass::StorageBuffer && + storage != spv::StorageClass::Uniform && + storage != spv::StorageClass::PushConstant && + storage != spv::StorageClass::Input && + storage != spv::StorageClass::Output && + storage != spv::StorageClass::PhysicalStorageBuffer) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "FPRoundingMode decoration can be applied only to the " "Object operand of an OpStore in the StorageBuffer, " @@ -1509,16 +1521,17 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, // First, it must be a variable or function parameter. const auto opcode = inst.opcode(); const auto type_id = inst.type_id(); - if (opcode != SpvOpVariable && opcode != SpvOpFunctionParameter) { + if (opcode != spv::Op::OpVariable && + opcode != spv::Op::OpFunctionParameter) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of NonWritable decoration must be a memory object " "declaration (a variable or a function parameter)"; } - const auto var_storage_class = opcode == SpvOpVariable - ? inst.GetOperandAs(2) - : SpvStorageClassMax; - if ((var_storage_class == SpvStorageClassFunction || - var_storage_class == SpvStorageClassPrivate) && + const auto var_storage_class = opcode == spv::Op::OpVariable + ? inst.GetOperandAs(2) + : spv::StorageClass::Max; + if ((var_storage_class == spv::StorageClass::Function || + var_storage_class == spv::StorageClass::Private) && vstate.features().nonwritable_var_in_function_or_private) { // New permitted feature in SPIR-V 1.4. } else if ( @@ -1548,8 +1561,9 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, spv_result_t CheckUniformDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { - const char* const dec_name = - decoration.dec_type() == SpvDecorationUniform ? "Uniform" : "UniformId"; + const char* const dec_name = decoration.dec_type() == spv::Decoration::Uniform + ? "Uniform" + : "UniformId"; // Uniform or UniformId must decorate an "object" // - has a result ID @@ -1563,7 +1577,7 @@ spv_result_t CheckUniformDecoration(ValidationState_t& vstate, << dec_name << " decoration applied to a non-object"; } if (Instruction* type_inst = vstate.FindDef(inst.type_id())) { - if (type_inst->opcode() == SpvOpTypeVoid) { + if (type_inst->opcode() == spv::Op::OpTypeVoid) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << dec_name << " decoration applied to a value with void type"; } @@ -1577,7 +1591,7 @@ spv_result_t CheckUniformDecoration(ValidationState_t& vstate, // Use of Uniform with OpDecorate is checked elsewhere. // Use of UniformId with OpDecorateId is checked elsewhere. - if (decoration.dec_type() == SpvDecorationUniformId) { + if (decoration.dec_type() == spv::Decoration::UniformId) { assert(decoration.params().size() == 1 && "Grammar ensures UniformId has one parameter"); @@ -1598,13 +1612,13 @@ spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { switch (inst.opcode()) { - case SpvOpIAdd: - case SpvOpISub: - case SpvOpIMul: - case SpvOpShiftLeftLogical: - case SpvOpSNegate: + case spv::Op::OpIAdd: + case spv::Op::OpISub: + case spv::Op::OpIMul: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpSNegate: return SPV_SUCCESS; - case SpvOpExtInst: + case spv::Op::OpExtInst: // TODO(dneto): Only certain extended instructions allow these // decorations. For now allow anything. return SPV_SUCCESS; @@ -1613,7 +1627,7 @@ spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate, } return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << (decoration.dec_type() == SpvDecorationNoSignedWrap + << (decoration.dec_type() == spv::Decoration::NoSignedWrap ? "NoSignedWrap" : "NoUnsignedWrap") << " decoration may not be applied to " @@ -1634,24 +1648,25 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, if (decoration.struct_member_index() == Decoration::kInvalidMember) { // The target must be a memory object declaration. const auto opcode = inst.opcode(); - if (opcode != SpvOpVariable && opcode != SpvOpFunctionParameter) { + if (opcode != spv::Op::OpVariable && + opcode != spv::Op::OpFunctionParameter) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of Component decoration must be a memory object " "declaration (a variable or a function parameter)"; } // Only valid for the Input and Output Storage Classes. - const auto storage_class = opcode == SpvOpVariable - ? inst.GetOperandAs(2) - : SpvStorageClassMax; - if (storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput && - storage_class != SpvStorageClassMax) { + const auto storage_class = opcode == spv::Op::OpVariable + ? inst.GetOperandAs(2) + : spv::StorageClass::Max; + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output && + storage_class != spv::StorageClass::Max) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of Component decoration is invalid: must point to a " "Storage Class of Input(1) or Output(3). Found Storage " "Class " - << storage_class; + << uint32_t(storage_class); } type_id = inst.type_id(); @@ -1660,7 +1675,7 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, type_id = pointer->GetOperandAs(2); } } else { - if (inst.opcode() != SpvOpTypeStruct) { + if (inst.opcode() != spv::Op::OpTypeStruct) { return vstate.diag(SPV_ERROR_INVALID_DATA, &inst) << "Attempted to get underlying data type via member index for " "non-struct type."; @@ -1670,7 +1685,7 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, if (spvIsVulkanEnv(vstate.context()->target_env)) { // Strip the array, if present. - if (vstate.GetIdOpcode(type_id) == SpvOpTypeArray) { + if (vstate.GetIdOpcode(type_id) == spv::Op::OpTypeArray) { type_id = vstate.FindDef(type_id)->word(2u); } @@ -1703,6 +1718,7 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, } else if (bit_width == 64) { if (dimension > 2) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(7703) << "Component decoration only allowed on 64-bit scalar and " "2-component vector"; } @@ -1734,9 +1750,10 @@ spv_result_t CheckBlockDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { assert(inst.id() && "Parser ensures the target of the decoration has an ID"); - if (inst.opcode() != SpvOpTypeStruct) { - const char* const dec_name = - decoration.dec_type() == SpvDecorationBlock ? "Block" : "BufferBlock"; + if (inst.opcode() != spv::Op::OpTypeStruct) { + const char* const dec_name = decoration.dec_type() == spv::Decoration::Block + ? "Block" + : "BufferBlock"; return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << dec_name << " decoration on a non-struct type."; } @@ -1746,10 +1763,10 @@ spv_result_t CheckBlockDecoration(ValidationState_t& vstate, spv_result_t CheckLocationDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { - if (inst.opcode() == SpvOpVariable) return SPV_SUCCESS; + if (inst.opcode() == spv::Op::OpVariable) return SPV_SUCCESS; if (decoration.struct_member_index() != Decoration::kInvalidMember && - inst.opcode() == SpvOpTypeStruct) { + inst.opcode() == spv::Op::OpTypeStruct) { return SPV_SUCCESS; } @@ -1769,7 +1786,7 @@ spv_result_t CheckRelaxPrecisionDecoration(ValidationState_t& vstate, } if (decoration.struct_member_index() != Decoration::kInvalidMember && - inst.opcode() == SpvOpTypeStruct) { + inst.opcode() == spv::Op::OpTypeStruct) { return SPV_SUCCESS; } return vstate.diag(SPV_ERROR_INVALID_ID, &inst) @@ -1788,7 +1805,7 @@ spv_result_t CheckRelaxPrecisionDecoration(ValidationState_t& vstate, // propagated down to the group members. spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) { // Some rules are only checked for shaders. - const bool is_shader = vstate.HasCapability(SpvCapabilityShader); + const bool is_shader = vstate.HasCapability(spv::Capability::Shader); for (const auto& kv : vstate.id_decorations()) { const uint32_t id = kv.first; @@ -1800,37 +1817,37 @@ spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) { // We assume the decorations applied to a decoration group have already // been propagated down to the group members. - if (inst->opcode() == SpvOpDecorationGroup) continue; + if (inst->opcode() == spv::Op::OpDecorationGroup) continue; for (const auto& decoration : decorations) { switch (decoration.dec_type()) { - case SpvDecorationComponent: + case spv::Decoration::Component: PASS_OR_BAIL(CheckComponentDecoration(vstate, *inst, decoration)); break; - case SpvDecorationFPRoundingMode: + case spv::Decoration::FPRoundingMode: if (is_shader) PASS_OR_BAIL( CheckFPRoundingModeForShaders(vstate, *inst, decoration)); break; - case SpvDecorationNonWritable: + case spv::Decoration::NonWritable: PASS_OR_BAIL(CheckNonWritableDecoration(vstate, *inst, decoration)); break; - case SpvDecorationUniform: - case SpvDecorationUniformId: + case spv::Decoration::Uniform: + case spv::Decoration::UniformId: PASS_OR_BAIL(CheckUniformDecoration(vstate, *inst, decoration)); break; - case SpvDecorationNoSignedWrap: - case SpvDecorationNoUnsignedWrap: + case spv::Decoration::NoSignedWrap: + case spv::Decoration::NoUnsignedWrap: PASS_OR_BAIL(CheckIntegerWrapDecoration(vstate, *inst, decoration)); break; - case SpvDecorationBlock: - case SpvDecorationBufferBlock: + case spv::Decoration::Block: + case spv::Decoration::BufferBlock: PASS_OR_BAIL(CheckBlockDecoration(vstate, *inst, decoration)); break; - case SpvDecorationLocation: + case spv::Decoration::Location: PASS_OR_BAIL(CheckLocationDecoration(vstate, *inst, decoration)); break; - case SpvDecorationRelaxedPrecision: + case spv::Decoration::RelaxedPrecision: PASS_OR_BAIL( CheckRelaxPrecisionDecoration(vstate, *inst, decoration)); break; diff --git a/3rdparty/spirv-tools/source/val/validate_derivatives.cpp b/3rdparty/spirv-tools/source/val/validate_derivatives.cpp index 25b941aba..d87240f60 100644 --- a/3rdparty/spirv-tools/source/val/validate_derivatives.cpp +++ b/3rdparty/spirv-tools/source/val/validate_derivatives.cpp @@ -28,25 +28,26 @@ namespace val { // Validates correctness of derivative instructions. spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpDPdx: - case SpvOpDPdy: - case SpvOpFwidth: - case SpvOpDPdxFine: - case SpvOpDPdyFine: - case SpvOpFwidthFine: - case SpvOpDPdxCoarse: - case SpvOpDPdyCoarse: - case SpvOpFwidthCoarse: { + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpFwidth: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpFwidthFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidthCoarse: { if (!_.IsFloatScalarOrVectorType(result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be float scalar or vector type: " << spvOpcodeString(opcode); } - if (!_.ContainsSizedIntOrFloatType(result_type, SpvOpTypeFloat, 32)) { + if (!_.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeFloat, + 32)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Result type component width must be 32 bits"; } @@ -58,10 +59,10 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { << spvOpcodeString(opcode); } _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, + ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model, std::string* message) { - if (model != SpvExecutionModelFragment && - model != SpvExecutionModelGLCompute) { + if (model != spv::ExecutionModel::Fragment && + model != spv::ExecutionModel::GLCompute) { if (message) { *message = std::string( @@ -80,11 +81,11 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { const auto* models = state.GetExecutionModels(entry_point->id()); const auto* modes = state.GetExecutionModes(entry_point->id()); if (models && - models->find(SpvExecutionModelGLCompute) != models->end() && + models->find(spv::ExecutionModel::GLCompute) != models->end() && (!modes || - (modes->find(SpvExecutionModeDerivativeGroupLinearNV) == + (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == modes->end() && - modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == + modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == modes->end()))) { if (message) { *message = std::string( diff --git a/3rdparty/spirv-tools/source/val/validate_execution_limitations.cpp b/3rdparty/spirv-tools/source/val/validate_execution_limitations.cpp index e1f4d7b04..00c660358 100644 --- a/3rdparty/spirv-tools/source/val/validate_execution_limitations.cpp +++ b/3rdparty/spirv-tools/source/val/validate_execution_limitations.cpp @@ -22,7 +22,7 @@ namespace val { spv_result_t ValidateExecutionLimitations(ValidationState_t& _, const Instruction* inst) { - if (inst->opcode() != SpvOpFunction) { + if (inst->opcode() != spv::Op::OpFunction) { return SPV_SUCCESS; } diff --git a/3rdparty/spirv-tools/source/val/validate_extensions.cpp b/3rdparty/spirv-tools/source/val/validate_extensions.cpp index 1e69cb37f..fa58e0f94 100644 --- a/3rdparty/spirv-tools/source/val/validate_extensions.cpp +++ b/3rdparty/spirv-tools/source/val/validate_extensions.cpp @@ -39,10 +39,24 @@ namespace spvtools { namespace val { namespace { -uint32_t GetSizeTBitWidth(const ValidationState_t& _) { - if (_.addressing_model() == SpvAddressingModelPhysical32) return 32; +std::string ReflectionInstructionName(ValidationState_t& _, + const Instruction* inst) { + spv_ext_inst_desc desc = nullptr; + if (_.grammar().lookupExtInst(SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, + inst->word(4), &desc) != SPV_SUCCESS || + !desc) { + return std::string("Unknown ExtInst"); + } + std::ostringstream ss; + ss << desc->name; - if (_.addressing_model() == SpvAddressingModelPhysical64) return 64; + return ss.str(); +} + +uint32_t GetSizeTBitWidth(const ValidationState_t& _) { + if (_.addressing_model() == spv::AddressingModel::Physical32) return 32; + + if (_.addressing_model() == spv::AddressingModel::Physical64) return 64; return 0; } @@ -50,7 +64,7 @@ uint32_t GetSizeTBitWidth(const ValidationState_t& _) { bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32, bool must_unsigned) { auto type = _.FindDef(id); - if (!type || type->opcode() != SpvOpTypeInt) { + if (!type || type->opcode() != spv::Op::OpTypeInt) { return false; } @@ -63,7 +77,7 @@ bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32, bool IsUint32Constant(ValidationState_t& _, uint32_t id) { auto inst = _.FindDef(id); - if (!inst || inst->opcode() != SpvOpConstant) { + if (!inst || inst->opcode() != spv::Op::OpConstant) { return false; } @@ -79,7 +93,7 @@ uint32_t GetUint32Constant(ValidationState_t& _, uint32_t id) { // is a result id of an instruction with |expected_opcode|. spv_result_t ValidateOperandForDebugInfo( ValidationState_t& _, const std::string& operand_name, - SpvOp expected_opcode, const Instruction* inst, uint32_t word_index, + spv::Op expected_opcode, const Instruction* inst, uint32_t word_index, const std::function& ext_inst_name) { auto* operand = _.FindDef(inst->word(word_index)); if (operand->opcode() != expected_opcode) { @@ -137,7 +151,7 @@ bool DoesDebugInfoOperandMatchExpectation( const Instruction* inst, uint32_t word_index) { if (inst->words().size() <= word_index) return false; auto* debug_inst = _.FindDef(inst->word(word_index)); - if (debug_inst->opcode() != SpvOpExtInst || + if (debug_inst->opcode() != spv::Op::OpExtInst || (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 && debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || @@ -155,7 +169,7 @@ bool DoesDebugInfoOperandMatchExpectation( const Instruction* inst, uint32_t word_index) { if (inst->words().size() <= word_index) return false; auto* debug_inst = _.FindDef(inst->word(word_index)); - if (debug_inst->opcode() != SpvOpExtInst || + if (debug_inst->opcode() != spv::Op::OpExtInst || (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || !expectation( @@ -273,12 +287,14 @@ spv_result_t ValidateOperandDebugType( } spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, - const Instruction* inst) { + const Instruction* inst, + uint32_t version) { + const auto inst_name = ReflectionInstructionName(_, inst); const auto kernel_id = inst->GetOperandAs(4); const auto kernel = _.FindDef(kernel_id); - if (kernel->opcode() != SpvOpFunction) { + if (kernel->opcode() != spv::Op::OpFunction) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Kernel does not reference a function"; + << inst_name << " does not reference a function"; } bool found_kernel = false; @@ -290,23 +306,23 @@ spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, } if (!found_kernel) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Kernel does not reference an entry-point"; + << inst_name << " does not reference an entry-point"; } const auto* exec_models = _.GetExecutionModels(kernel_id); if (!exec_models || exec_models->empty()) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Kernel does not reference an entry-point"; + << inst_name << " does not reference an entry-point"; } for (auto exec_model : *exec_models) { - if (exec_model != SpvExecutionModelGLCompute) { + if (exec_model != spv::ExecutionModel::GLCompute) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Kernel must refer only to GLCompute entry-points"; + << inst_name << " must refer only to GLCompute entry-points"; } } auto name = _.FindDef(inst->GetOperandAs(5)); - if (!name || name->opcode() != SpvOpString) { + if (!name || name->opcode() != spv::Op::OpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString"; } @@ -323,17 +339,48 @@ spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, << "Name must match an entry-point for Kernel"; } + const auto num_operands = inst->operands().size(); + if (version < 5 && num_operands > 6) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Version " << version << " of the " << inst_name + << " instruction can only have 2 additional operands"; + } + + if (num_operands > 6) { + const auto num_args_id = inst->GetOperandAs(6); + if (!IsUint32Constant(_, num_args_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "NumArguments must be a 32-bit unsigned integer OpConstant"; + } + } + + if (num_operands > 7) { + const auto flags_id = inst->GetOperandAs(7); + if (!IsUint32Constant(_, flags_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Flags must be a 32-bit unsigned integer OpConstant"; + } + } + + if (num_operands > 8) { + const auto atts_id = inst->GetOperandAs(8); + if (_.GetIdOpcode(atts_id) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Attributes must be an OpString"; + } + } + return SPV_SUCCESS; } spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _, const Instruction* inst) { const auto num_operands = inst->operands().size(); - if (_.GetIdOpcode(inst->GetOperandAs(4)) != SpvOpString) { + if (_.GetIdOpcode(inst->GetOperandAs(4)) != spv::Op::OpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString"; } if (num_operands > 5) { - if (_.GetIdOpcode(inst->GetOperandAs(5)) != SpvOpString) { + if (_.GetIdOpcode(inst->GetOperandAs(5)) != spv::Op::OpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "TypeName must be an OpString"; } @@ -366,7 +413,7 @@ spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _, spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { const auto decl_id = inst->GetOperandAs(4); const auto decl = _.FindDef(decl_id); - if (!decl || decl->opcode() != SpvOpExtInst) { + if (!decl || decl->opcode() != spv::Op::OpExtInst) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Kernel must be a Kernel extended instruction"; } @@ -389,7 +436,7 @@ spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst, uint32_t info_index) { auto info = _.FindDef(inst->GetOperandAs(info_index)); - if (!info || info->opcode() != SpvOpExtInst) { + if (!info || info->opcode() != spv::Op::OpExtInst) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "ArgInfo must be an ArgumentInfo extended instruction"; } @@ -439,8 +486,8 @@ spv_result_t ValidateClspvReflectionArgumentBuffer(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionArgumentPodBuffer(ValidationState_t& _, - const Instruction* inst) { +spv_result_t ValidateClspvReflectionArgumentOffsetBuffer(ValidationState_t& _, + const Instruction* inst) { const auto num_operands = inst->operands().size(); if (auto error = ValidateKernelDecl(_, inst)) { return error; @@ -480,7 +527,7 @@ spv_result_t ValidateClspvReflectionArgumentPodBuffer(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionArgumentPodPushConstant( +spv_result_t ValidateClspvReflectionArgumentPushConstant( ValidationState_t& _, const Instruction* inst) { const auto num_operands = inst->operands().size(); if (auto error = ValidateKernelDecl(_, inst)) { @@ -587,8 +634,8 @@ spv_result_t ValidateClspvReflectionPushConstant(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionConstantData(ValidationState_t& _, - const Instruction* inst) { +spv_result_t ValidateClspvReflectionInitializedData(ValidationState_t& _, + const Instruction* inst) { if (!IsUint32Constant(_, inst->GetOperandAs(4))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; @@ -599,7 +646,7 @@ spv_result_t ValidateClspvReflectionConstantData(ValidationState_t& _, << "Binding must be a 32-bit unsigned integer OpConstant"; } - if (_.GetIdOpcode(inst->GetOperandAs(6)) != SpvOpString) { + if (_.GetIdOpcode(inst->GetOperandAs(6)) != spv::Op::OpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString"; } @@ -650,18 +697,250 @@ spv_result_t ValidateClspvReflectionPropertyRequiredWorkgroupSize( return SPV_SUCCESS; } +spv_result_t ValidateClspvReflectionSubgroupMaxSize(ValidationState_t& _, + const Instruction* inst) { + const auto size_id = inst->GetOperandAs(4); + if (!IsUint32Constant(_, size_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPointerRelocation(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ObjectOffset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PointerOffset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PointerSize must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionImageMetadataPushConstant( + ValidationState_t& _, const Instruction* inst) { + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionImageMetadataUniform( + ValidationState_t& _, const Instruction* inst) { + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(8))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(9))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPushConstantData(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + if (_.GetIdOpcode(inst->GetOperandAs(6)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPrintfInfo(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PrintfID must be a 32-bit unsigned integer OpConstant"; + } + + if (_.GetIdOpcode(inst->GetOperandAs(5)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "FormatString must be an OpString"; + } + + for (size_t i = 6; i < inst->operands().size(); ++i) { + if (!IsUint32Constant(_, inst->GetOperandAs(i))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ArgumentSizes must be a 32-bit unsigned integer OpConstant"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPrintfStorageBuffer(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPrintfPushConstant(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "BufferSize must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, const Instruction* inst, - uint32_t /*version*/) { + uint32_t version) { if (!_.IsVoidType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Return Type must be OpTypeVoid"; } - auto ext_inst = inst->GetOperandAs(3); + uint32_t required_version = 0; + const auto ext_inst = + inst->GetOperandAs(3); switch (ext_inst) { case NonSemanticClspvReflectionKernel: - return ValidateClspvReflectionKernel(_, inst); + case NonSemanticClspvReflectionArgumentInfo: + case NonSemanticClspvReflectionArgumentStorageBuffer: + case NonSemanticClspvReflectionArgumentUniform: + case NonSemanticClspvReflectionArgumentPodStorageBuffer: + case NonSemanticClspvReflectionArgumentPodUniform: + case NonSemanticClspvReflectionArgumentPodPushConstant: + case NonSemanticClspvReflectionArgumentSampledImage: + case NonSemanticClspvReflectionArgumentStorageImage: + case NonSemanticClspvReflectionArgumentSampler: + case NonSemanticClspvReflectionArgumentWorkgroup: + case NonSemanticClspvReflectionSpecConstantWorkgroupSize: + case NonSemanticClspvReflectionSpecConstantGlobalOffset: + case NonSemanticClspvReflectionSpecConstantWorkDim: + case NonSemanticClspvReflectionPushConstantGlobalOffset: + case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize: + case NonSemanticClspvReflectionPushConstantGlobalSize: + case NonSemanticClspvReflectionPushConstantRegionOffset: + case NonSemanticClspvReflectionPushConstantNumWorkgroups: + case NonSemanticClspvReflectionPushConstantRegionGroupOffset: + case NonSemanticClspvReflectionConstantDataStorageBuffer: + case NonSemanticClspvReflectionConstantDataUniform: + case NonSemanticClspvReflectionLiteralSampler: + case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: + required_version = 1; + break; + case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: + required_version = 2; + break; + case NonSemanticClspvReflectionArgumentPointerPushConstant: + case NonSemanticClspvReflectionArgumentPointerUniform: + case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer: + case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation: + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform: + required_version = 3; + break; + case NonSemanticClspvReflectionArgumentStorageTexelBuffer: + case NonSemanticClspvReflectionArgumentUniformTexelBuffer: + required_version = 4; + break; + case NonSemanticClspvReflectionConstantDataPointerPushConstant: + case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant: + case NonSemanticClspvReflectionPrintfInfo: + case NonSemanticClspvReflectionPrintfBufferStorageBuffer: + case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: + required_version = 5; + break; + default: + break; + } + if (version < required_version) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << ReflectionInstructionName(_, inst) << " requires version " + << required_version << ", but parsed version is " << version; + } + + switch (ext_inst) { + case NonSemanticClspvReflectionKernel: + return ValidateClspvReflectionKernel(_, inst, version); case NonSemanticClspvReflectionArgumentInfo: return ValidateClspvReflectionArgumentInfo(_, inst); case NonSemanticClspvReflectionArgumentStorageBuffer: @@ -669,12 +948,16 @@ spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, case NonSemanticClspvReflectionArgumentSampledImage: case NonSemanticClspvReflectionArgumentStorageImage: case NonSemanticClspvReflectionArgumentSampler: + case NonSemanticClspvReflectionArgumentStorageTexelBuffer: + case NonSemanticClspvReflectionArgumentUniformTexelBuffer: return ValidateClspvReflectionArgumentBuffer(_, inst); case NonSemanticClspvReflectionArgumentPodStorageBuffer: case NonSemanticClspvReflectionArgumentPodUniform: - return ValidateClspvReflectionArgumentPodBuffer(_, inst); + case NonSemanticClspvReflectionArgumentPointerUniform: + return ValidateClspvReflectionArgumentOffsetBuffer(_, inst); case NonSemanticClspvReflectionArgumentPodPushConstant: - return ValidateClspvReflectionArgumentPodPushConstant(_, inst); + case NonSemanticClspvReflectionArgumentPointerPushConstant: + return ValidateClspvReflectionArgumentPushConstant(_, inst); case NonSemanticClspvReflectionArgumentWorkgroup: return ValidateClspvReflectionArgumentWorkgroup(_, inst); case NonSemanticClspvReflectionSpecConstantWorkgroupSize: @@ -691,11 +974,31 @@ spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, return ValidateClspvReflectionPushConstant(_, inst); case NonSemanticClspvReflectionConstantDataStorageBuffer: case NonSemanticClspvReflectionConstantDataUniform: - return ValidateClspvReflectionConstantData(_, inst); + case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer: + return ValidateClspvReflectionInitializedData(_, inst); case NonSemanticClspvReflectionLiteralSampler: return ValidateClspvReflectionSampler(_, inst); case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: return ValidateClspvReflectionPropertyRequiredWorkgroupSize(_, inst); + case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: + return ValidateClspvReflectionSubgroupMaxSize(_, inst); + case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation: + return ValidateClspvReflectionPointerRelocation(_, inst); + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: + return ValidateClspvReflectionImageMetadataPushConstant(_, inst); + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform: + return ValidateClspvReflectionImageMetadataUniform(_, inst); + case NonSemanticClspvReflectionConstantDataPointerPushConstant: + case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant: + return ValidateClspvReflectionPushConstantData(_, inst); + case NonSemanticClspvReflectionPrintfInfo: + return ValidateClspvReflectionPrintfInfo(_, inst); + case NonSemanticClspvReflectionPrintfBufferStorageBuffer: + return ValidateClspvReflectionPrintfStorageBuffer(_, inst); + case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: + return ValidateClspvReflectionPrintfPushConstant(_, inst); default: break; } @@ -705,7 +1008,7 @@ spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _, Instruction* instr) { - if (instr->opcode() != SpvOpConstant) return false; + if (instr->opcode() != spv::Op::OpConstant) return false; if (!_.IsIntScalarType(instr->type_id())) return false; uint32_t size_in_bits = _.GetBitWidth(instr->type_id()); return size_in_bits == 32 || size_in_bits == 64; @@ -714,7 +1017,7 @@ bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _, bool IsConstWithIntScalarType(ValidationState_t& _, const Instruction* inst, uint32_t word_index) { auto* int_scalar_const = _.FindDef(inst->word(word_index)); - if (int_scalar_const->opcode() == SpvOpConstant && + if (int_scalar_const->opcode() == spv::Op::OpConstant && _.IsIntScalarType(int_scalar_const->type_id())) { return true; } @@ -757,7 +1060,8 @@ spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) { std::string extension = GetExtensionString(&(inst->c_inst())); if (extension == ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) || - extension == ExtensionToString(kSPV_EXT_mesh_shader)) { + extension == ExtensionToString(kSPV_EXT_mesh_shader) || + extension == ExtensionToString(kSPV_NV_shader_invocation_reorder)) { return _.diag(SPV_ERROR_WRONG_VERSION, inst) << extension << " extension requires SPIR-V version 1.4 or later."; } @@ -1020,7 +1324,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand X type to be equal to Result Type"; } - uint32_t i_storage_class = 0; + spv::StorageClass i_storage_class; uint32_t i_data_type = 0; if (!_.GetPointerTypeInfo(i_type, &i_data_type, &i_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1075,7 +1379,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand X type to be equal to Result Type"; } - uint32_t exp_storage_class = 0; + spv::StorageClass exp_storage_class; uint32_t exp_data_type = 0; if (!_.GetPointerTypeInfo(exp_type, &exp_data_type, &exp_storage_class)) { @@ -1424,7 +1728,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { case GLSLstd450InterpolateAtCentroid: case GLSLstd450InterpolateAtSample: case GLSLstd450InterpolateAtOffset: { - if (!_.HasCapability(SpvCapabilityInterpolationFunction)) { + if (!_.HasCapability(spv::Capability::InterpolationFunction)) { return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) << ext_inst_name() << " requires capability InterpolationFunction"; @@ -1444,11 +1748,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { uint32_t interp_id = inst->GetOperandAs(4); auto* interp_inst = _.FindDef(interp_id); uint32_t interpolant_type = (_.options()->before_hlsl_legalization && - interp_inst->opcode() == SpvOpLoad) + interp_inst->opcode() == spv::Op::OpLoad) ? _.GetOperandTypeId(interp_inst, 2) : _.GetOperandTypeId(inst, 4); - uint32_t interpolant_storage_class = 0; + spv::StorageClass interpolant_storage_class; uint32_t interpolant_data_type = 0; if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type, &interpolant_storage_class)) { @@ -1463,7 +1767,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected Interpolant data type to be equal to Result Type"; } - if (interpolant_storage_class != SpvStorageClassInput) { + if (interpolant_storage_class != spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected Interpolant storage class to be Input"; @@ -1492,7 +1796,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, ext_inst_name() + std::string(" requires Fragment execution model")); break; @@ -1662,7 +1966,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } const uint32_t p_type = _.GetOperandTypeId(inst, 5); - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1670,10 +1974,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected the last operand to be a pointer"; } - if (p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected storage class of the pointer to be Generic, " @@ -1724,7 +2028,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++); - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1732,10 +2036,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected the last operand to be a pointer"; } - if (p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected storage class of the pointer to be Generic, " @@ -2254,7 +2558,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2262,11 +2566,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != SpvStorageClassUniformConstant && - p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::UniformConstant && + p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be UniformConstant, " @@ -2291,7 +2595,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } case OpenCLLIB::Vstoren: { - if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": expected Result Type to be void"; } @@ -2329,7 +2633,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2337,10 +2641,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be Generic, " @@ -2382,7 +2686,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2390,11 +2694,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != SpvStorageClassUniformConstant && - p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::UniformConstant && + p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be UniformConstant, " @@ -2444,7 +2748,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2452,11 +2756,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != SpvStorageClassUniformConstant && - p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::UniformConstant && + p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be UniformConstant, " @@ -2486,7 +2790,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { case OpenCLLIB::Vstore_halfn_r: case OpenCLLIB::Vstorea_halfn: case OpenCLLIB::Vstorea_halfn_r: { - if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": expected Result Type to be void"; } @@ -2537,7 +2841,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2545,10 +2849,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != SpvStorageClassGeneric && - p_storage_class != SpvStorageClassCrossWorkgroup && - p_storage_class != SpvStorageClassWorkgroup && - p_storage_class != SpvStorageClassFunction) { + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be Generic, " @@ -2653,7 +2957,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } const uint32_t format_type = _.GetOperandTypeId(inst, 4); - uint32_t format_storage_class = 0; + spv::StorageClass format_storage_class; uint32_t format_data_type = 0; if (!_.GetPointerTypeInfo(format_type, &format_data_type, &format_storage_class)) { @@ -2662,7 +2966,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand Format to be a pointer"; } - if (format_storage_class != SpvStorageClassUniformConstant) { + if (format_storage_class != spv::StorageClass::UniformConstant) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected Format storage class to be UniformConstant"; @@ -2678,7 +2982,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } case OpenCLLIB::Prefetch: { - if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": expected Result Type to be void"; } @@ -2686,7 +2990,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { const uint32_t p_type = _.GetOperandTypeId(inst, 4); const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5); - uint32_t p_storage_class = 0; + spv::StorageClass p_storage_class; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2694,7 +2998,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand Ptr to be a pointer"; } - if (p_storage_class != SpvStorageClassCrossWorkgroup) { + if (p_storage_class != spv::StorageClass::CrossWorkgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand Ptr storage class to be CrossWorkgroup"; @@ -2857,13 +3161,13 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugSource: { - CHECK_OPERAND("File", SpvOpString, 5); - if (num_words == 7) CHECK_OPERAND("Text", SpvOpString, 6); + CHECK_OPERAND("File", spv::Op::OpString, 5); + if (num_words == 7) CHECK_OPERAND("Text", spv::Op::OpString, 6); break; } case CommonDebugInfoDebugTypeBasic: { - CHECK_OPERAND("Name", SpvOpString, 5); - CHECK_OPERAND("Size", SpvOpConstant, 6); + CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Size", spv::Op::OpConstant, 6); CHECK_CONST_UINT_OPERAND("Encoding", 7); break; } @@ -2966,7 +3270,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypedef: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); auto validate_base_type = ValidateOperandBaseType(_, inst, 6, ext_inst_name); if (validate_base_type != SPV_SUCCESS) return validate_base_type; @@ -2983,7 +3287,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto* return_type = _.FindDef(inst->word(6)); // TODO: We need a spec discussion that we have to allow return and // parameter types of a DebugTypeFunction to have template parameter. - if (return_type->opcode() != SpvOpTypeVoid) { + if (return_type->opcode() != spv::Op::OpTypeVoid) { auto validate_return = ValidateOperandDebugType( _, "Return Type", inst, 6, ext_inst_name, true); if (validate_return != SPV_SUCCESS) return validate_return; @@ -2996,7 +3300,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypeEnum: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); if (!DoesDebugInfoOperandMatchExpectation( _, [](CommonDebugInfoInstructions dbg_inst) { @@ -3014,7 +3318,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Size", SpvOpConstant, 11); + CHECK_OPERAND("Size", spv::Op::OpConstant, 11); auto* size = _.FindDef(inst->word(11)); if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -3024,27 +3328,27 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { CHECK_CONST_UINT_OPERAND("Flags", 12); for (uint32_t word_index = 13; word_index + 1 < num_words; word_index += 2) { - CHECK_OPERAND("Value", SpvOpConstant, word_index); - CHECK_OPERAND("Name", SpvOpString, word_index + 1); + CHECK_OPERAND("Value", spv::Op::OpConstant, word_index); + CHECK_OPERAND("Name", spv::Op::OpString, word_index + 1); } break; } case CommonDebugInfoDebugTypeComposite: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); CHECK_CONST_UINT_OPERAND("Line", 8); CHECK_CONST_UINT_OPERAND("Column", 9); auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Linkage Name", SpvOpString, 11); + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); if (!DoesDebugInfoOperandMatchExpectation( _, [](CommonDebugInfoInstructions dbg_inst) { return dbg_inst == CommonDebugInfoDebugInfoNone; }, inst, 12)) { - CHECK_OPERAND("Size", SpvOpConstant, 12); + CHECK_OPERAND("Size", spv::Op::OpConstant, 12); } CHECK_CONST_UINT_OPERAND("Flags", 13); for (uint32_t word_index = 14; word_index < num_words; ++word_index) { @@ -3066,7 +3370,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypeMember: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); // TODO: We need a spec discussion that we have to allow member types // to have template parameter. auto validate_type = @@ -3077,17 +3381,19 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { CHECK_CONST_UINT_OPERAND("Column", 9); // NonSemantic.Shader.DebugInfo doesn't have the Parent operand if (vulkanDebugInfo) { - CHECK_OPERAND("Offset", SpvOpConstant, 10); - CHECK_OPERAND("Size", SpvOpConstant, 11); + CHECK_OPERAND("Offset", spv::Op::OpConstant, 10); + CHECK_OPERAND("Size", spv::Op::OpConstant, 11); CHECK_CONST_UINT_OPERAND("Flags", 12); - if (num_words == 14) CHECK_OPERAND("Value", SpvOpConstant, 13); + if (num_words == 14) + CHECK_OPERAND("Value", spv::Op::OpConstant, 13); } else { CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, 10); - CHECK_OPERAND("Offset", SpvOpConstant, 11); - CHECK_OPERAND("Size", SpvOpConstant, 12); + CHECK_OPERAND("Offset", spv::Op::OpConstant, 11); + CHECK_OPERAND("Size", spv::Op::OpConstant, 12); CHECK_CONST_UINT_OPERAND("Flags", 13); - if (num_words == 15) CHECK_OPERAND("Value", SpvOpConstant, 14); + if (num_words == 15) + CHECK_OPERAND("Value", spv::Op::OpConstant, 14); } break; } @@ -3114,13 +3420,13 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand Parent must be class or struct debug " "type"; } - CHECK_OPERAND("Offset", SpvOpConstant, 7); - CHECK_OPERAND("Size", SpvOpConstant, 8); + CHECK_OPERAND("Offset", spv::Op::OpConstant, 7); + CHECK_OPERAND("Size", spv::Op::OpConstant, 8); CHECK_CONST_UINT_OPERAND("Flags", 9); break; } case CommonDebugInfoDebugFunction: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false); if (validate_type != SPV_SUCCESS) return validate_type; @@ -3130,7 +3436,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Linkage Name", SpvOpString, 11); + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); CHECK_CONST_UINT_OPERAND("Flags", 12); CHECK_CONST_UINT_OPERAND("Scope Line", 13); // NonSemantic.Shader.DebugInfo.100 doesn't include a reference to the @@ -3147,7 +3453,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { return dbg_inst == CommonDebugInfoDebugInfoNone; }, inst, 14)) { - CHECK_OPERAND("Function", SpvOpFunction, 14); + CHECK_OPERAND("Function", spv::Op::OpFunction, 14); } if (num_words == 16) { CHECK_DEBUG_OPERAND("Declaration", @@ -3157,7 +3463,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugFunctionDeclaration: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false); if (validate_type != SPV_SUCCESS) return validate_type; @@ -3167,7 +3473,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Linkage Name", SpvOpString, 11); + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); CHECK_CONST_UINT_OPERAND("Flags", 12); break; } @@ -3178,7 +3484,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - if (num_words == 10) CHECK_OPERAND("Name", SpvOpString, 9); + if (num_words == 10) CHECK_OPERAND("Name", spv::Op::OpString, 9); break; } case CommonDebugInfoDebugScope: { @@ -3191,7 +3497,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugLocalVariable: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); // TODO: We need a spec discussion that we have to allow local // variable types to have template parameter. auto validate_type = @@ -3213,8 +3519,8 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { CHECK_DEBUG_OPERAND("Local Variable", CommonDebugInfoDebugLocalVariable, 5); auto* operand = _.FindDef(inst->word(6)); - if (operand->opcode() != SpvOpVariable && - operand->opcode() != SpvOpFunctionParameter) { + if (operand->opcode() != spv::Op::OpVariable && + operand->opcode() != spv::Op::OpFunctionParameter) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand Variable must be a result id of " @@ -3276,7 +3582,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypeTemplateParameter: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); auto validate_actual_type = ValidateOperandDebugType( _, "Actual Type", inst, 6, ext_inst_name, false); if (validate_actual_type != SPV_SUCCESS) return validate_actual_type; @@ -3286,7 +3592,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { return dbg_inst == CommonDebugInfoDebugInfoNone; }, inst, 7)) { - CHECK_OPERAND("Value", SpvOpConstant, 7); + CHECK_OPERAND("Value", spv::Op::OpConstant, 7); } CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 8); CHECK_CONST_UINT_OPERAND("Line", 9); @@ -3294,7 +3600,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugGlobalVariable: { - CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Name", spv::Op::OpString, 5); auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false); if (validate_type != SPV_SUCCESS) return validate_type; @@ -3304,7 +3610,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_scope = ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name); if (validate_scope != SPV_SUCCESS) return validate_scope; - CHECK_OPERAND("Linkage Name", SpvOpString, 11); + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); if (!DoesDebugInfoOperandMatchExpectation( _, [](CommonDebugInfoInstructions dbg_inst) { @@ -3312,8 +3618,8 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { }, inst, 12)) { auto* operand = _.FindDef(inst->word(12)); - if (operand->opcode() != SpvOpVariable && - operand->opcode() != SpvOpConstant) { + if (operand->opcode() != spv::Op::OpVariable && + operand->opcode() != spv::Op::OpConstant) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand Variable must be a result id of " @@ -3401,10 +3707,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); - if (opcode == SpvOpExtension) return ValidateExtension(_, inst); - if (opcode == SpvOpExtInstImport) return ValidateExtInstImport(_, inst); - if (opcode == SpvOpExtInst) return ValidateExtInst(_, inst); + const spv::Op opcode = inst->opcode(); + if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst); + if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst); + if (opcode == spv::Op::OpExtInst) return ValidateExtInst(_, inst); return SPV_SUCCESS; } diff --git a/3rdparty/spirv-tools/source/val/validate_function.cpp b/3rdparty/spirv-tools/source/val/validate_function.cpp index 0ccf5a9ea..db402aa32 100644 --- a/3rdparty/spirv-tools/source/val/validate_function.cpp +++ b/3rdparty/spirv-tools/source/val/validate_function.cpp @@ -28,7 +28,8 @@ namespace { // of the decorations that apply to |a|. bool DoPointeesLogicallyMatch(val::Instruction* a, val::Instruction* b, ValidationState_t& _) { - if (a->opcode() != SpvOpTypePointer || b->opcode() != SpvOpTypePointer) { + if (a->opcode() != spv::Op::OpTypePointer || + b->opcode() != spv::Op::OpTypePointer) { return false; } @@ -56,7 +57,7 @@ bool DoPointeesLogicallyMatch(val::Instruction* a, val::Instruction* b, spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) { const auto function_type_id = inst->GetOperandAs(3); const auto function_type = _.FindDef(function_type_id); - if (!function_type || SpvOpTypeFunction != function_type->opcode()) { + if (!function_type || spv::Op::OpTypeFunction != function_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpFunction Function Type " << _.getIdName(function_type_id) << " is not a function type."; @@ -70,21 +71,21 @@ spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) { << _.getIdName(return_id) << "."; } - const std::vector acceptable = { - SpvOpGroupDecorate, - SpvOpDecorate, - SpvOpEnqueueKernel, - SpvOpEntryPoint, - SpvOpExecutionMode, - SpvOpExecutionModeId, - SpvOpFunctionCall, - SpvOpGetKernelNDrangeSubGroupCount, - SpvOpGetKernelNDrangeMaxSubGroupSize, - SpvOpGetKernelWorkGroupSize, - SpvOpGetKernelPreferredWorkGroupSizeMultiple, - SpvOpGetKernelLocalSizeForSubgroupCount, - SpvOpGetKernelMaxNumSubgroups, - SpvOpName}; + const std::vector acceptable = { + spv::Op::OpGroupDecorate, + spv::Op::OpDecorate, + spv::Op::OpEnqueueKernel, + spv::Op::OpEntryPoint, + spv::Op::OpExecutionMode, + spv::Op::OpExecutionModeId, + spv::Op::OpFunctionCall, + spv::Op::OpGetKernelNDrangeSubGroupCount, + spv::Op::OpGetKernelNDrangeMaxSubGroupSize, + spv::Op::OpGetKernelWorkGroupSize, + spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, + spv::Op::OpGetKernelLocalSizeForSubgroupCount, + spv::Op::OpGetKernelMaxNumSubgroups, + spv::Op::OpName}; for (auto& pair : inst->uses()) { const auto* use = pair.first; if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) == @@ -112,14 +113,14 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _, auto func_inst = &_.ordered_instructions()[inst_num]; while (--inst_num) { func_inst = &_.ordered_instructions()[inst_num]; - if (func_inst->opcode() == SpvOpFunction) { + if (func_inst->opcode() == spv::Op::OpFunction) { break; - } else if (func_inst->opcode() == SpvOpFunctionParameter) { + } else if (func_inst->opcode() == spv::Op::OpFunctionParameter) { ++param_index; } } - if (func_inst->opcode() != SpvOpFunction) { + if (func_inst->opcode() != spv::Op::OpFunction) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Function parameter must be preceded by a function."; } @@ -150,25 +151,25 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _, // Validate that PhysicalStorageBuffer have one of Restrict, Aliased, // RestrictPointer, or AliasedPointer. auto param_nonarray_type_id = param_type->id(); - while (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypeArray) { + while (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypeArray) { param_nonarray_type_id = _.FindDef(param_nonarray_type_id)->GetOperandAs(1u); } - if (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypePointer) { + if (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypePointer) { auto param_nonarray_type = _.FindDef(param_nonarray_type_id); - if (param_nonarray_type->GetOperandAs(1u) == - SpvStorageClassPhysicalStorageBuffer) { + if (param_nonarray_type->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { // check for Aliased or Restrict const auto& decorations = _.id_decorations(inst->id()); bool foundAliased = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return SpvDecorationAliased == d.dec_type(); + return spv::Decoration::Aliased == d.dec_type(); }); bool foundRestrict = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return SpvDecorationRestrict == d.dec_type(); + return spv::Decoration::Restrict == d.dec_type(); }); if (!foundAliased && !foundRestrict) { @@ -187,20 +188,20 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _, const auto pointee_type_id = param_nonarray_type->GetOperandAs(2); const auto pointee_type = _.FindDef(pointee_type_id); - if (SpvOpTypePointer == pointee_type->opcode() && - pointee_type->GetOperandAs(1u) == - SpvStorageClassPhysicalStorageBuffer) { + if (spv::Op::OpTypePointer == pointee_type->opcode() && + pointee_type->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { // check for AliasedPointer/RestrictPointer const auto& decorations = _.id_decorations(inst->id()); bool foundAliased = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return SpvDecorationAliasedPointer == d.dec_type(); + return spv::Decoration::AliasedPointer == d.dec_type(); }); bool foundRestrict = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return SpvDecorationRestrictPointer == d.dec_type(); + return spv::Decoration::RestrictPointer == d.dec_type(); }); if (!foundAliased && !foundRestrict) { @@ -226,7 +227,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, const Instruction* inst) { const auto function_id = inst->GetOperandAs(2); const auto function = _.FindDef(function_id); - if (!function || SpvOpFunction != function->opcode()) { + if (!function || spv::Op::OpFunction != function->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpFunctionCall Function " << _.getIdName(function_id) << " is not a function."; @@ -242,7 +243,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, const auto function_type_id = function->GetOperandAs(3); const auto function_type = _.FindDef(function_type_id); - if (!function_type || function_type->opcode() != SpvOpTypeFunction) { + if (!function_type || function_type->opcode() != spv::Op::OpTypeFunction) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Missing function type definition."; } @@ -285,20 +286,21 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, } } - if (_.addressing_model() == SpvAddressingModelLogical) { - if (parameter_type->opcode() == SpvOpTypePointer && + if (_.addressing_model() == spv::AddressingModel::Logical) { + if (parameter_type->opcode() == spv::Op::OpTypePointer && !_.options()->relax_logical_pointer) { - SpvStorageClass sc = parameter_type->GetOperandAs(1u); + spv::StorageClass sc = + parameter_type->GetOperandAs(1u); // Validate which storage classes can be pointer operands. switch (sc) { - case SpvStorageClassUniformConstant: - case SpvStorageClassFunction: - case SpvStorageClassPrivate: - case SpvStorageClassWorkgroup: - case SpvStorageClassAtomicCounter: + case spv::StorageClass::UniformConstant: + case spv::StorageClass::Function: + case spv::StorageClass::Private: + case spv::StorageClass::Workgroup: + case spv::StorageClass::AtomicCounter: // These are always allowed. break; - case SpvStorageClassStorageBuffer: + case spv::StorageClass::StorageBuffer: if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "StorageBuffer pointer operand " @@ -313,13 +315,14 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, } // Validate memory object declaration requirements. - if (argument->opcode() != SpvOpVariable && - argument->opcode() != SpvOpFunctionParameter) { + if (argument->opcode() != spv::Op::OpVariable && + argument->opcode() != spv::Op::OpFunctionParameter) { const bool ssbo_vptr = _.features().variable_pointers && - sc == SpvStorageClassStorageBuffer; - const bool wg_vptr = _.HasCapability(SpvCapabilityVariablePointers) && - sc == SpvStorageClassWorkgroup; - const bool uc_ptr = sc == SpvStorageClassUniformConstant; + sc == spv::StorageClass::StorageBuffer; + const bool wg_vptr = + _.HasCapability(spv::Capability::VariablePointers) && + sc == spv::StorageClass::Workgroup; + const bool uc_ptr = sc == spv::StorageClass::UniformConstant; if (!ssbo_vptr && !wg_vptr && !uc_ptr) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Pointer operand " << _.getIdName(argument_id) @@ -336,13 +339,13 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpFunction: + case spv::Op::OpFunction: if (auto error = ValidateFunction(_, inst)) return error; break; - case SpvOpFunctionParameter: + case spv::Op::OpFunctionParameter: if (auto error = ValidateFunctionParameter(_, inst)) return error; break; - case SpvOpFunctionCall: + case spv::Op::OpFunctionCall: if (auto error = ValidateFunctionCall(_, inst)) return error; break; default: diff --git a/3rdparty/spirv-tools/source/val/validate_id.cpp b/3rdparty/spirv-tools/source/val/validate_id.cpp index 2bab20349..89a5ddd79 100644 --- a/3rdparty/spirv-tools/source/val/validate_id.cpp +++ b/3rdparty/spirv-tools/source/val/validate_id.cpp @@ -71,7 +71,7 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) { const Instruction* use = use_index_pair.first; if (const BasicBlock* use_block = use->block()) { if (use_block->reachable() == false) continue; - if (use->opcode() == SpvOpPhi) { + if (use->opcode() == spv::Op::OpPhi) { if (phi_ids.insert(use->id()).second) { phi_instructions.push_back(use); } @@ -131,7 +131,7 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) { // instruction operand's ID can be forward referenced. spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { auto can_have_forward_declared_ids = - inst->opcode() == SpvOpExtInst && + inst->opcode() == spv::Op::OpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type()) ? spvDbgInfoExtOperandCanBeForwardDeclaredFunction( inst->ext_inst_type(), inst->word(4)) @@ -172,23 +172,27 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { if (spvOpcodeGeneratesType(def->opcode()) && !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() && !inst->IsNonSemantic() && - !spvOpcodeIsDecoration(opcode) && opcode != SpvOpFunction && - opcode != SpvOpCooperativeMatrixLengthNV && - !(opcode == SpvOpSpecConstantOp && - inst->word(3) == SpvOpCooperativeMatrixLengthNV)) { + !spvOpcodeIsDecoration(opcode) && opcode != spv::Op::OpFunction && + opcode != spv::Op::OpCooperativeMatrixLengthNV && + !(opcode == spv::Op::OpSpecConstantOp && + spv::Op(inst->word(3)) == + spv::Op::OpCooperativeMatrixLengthNV)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Operand " << _.getIdName(operand_word) << " cannot be a type"; } else if (def->type_id() == 0 && !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() && !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) && - !spvOpcodeIsBranch(opcode) && opcode != SpvOpPhi && - opcode != SpvOpExtInst && opcode != SpvOpExtInstImport && - opcode != SpvOpSelectionMerge && - opcode != SpvOpLoopMerge && opcode != SpvOpFunction && - opcode != SpvOpCooperativeMatrixLengthNV && - !(opcode == SpvOpSpecConstantOp && - inst->word(3) == SpvOpCooperativeMatrixLengthNV)) { + !spvOpcodeIsBranch(opcode) && opcode != spv::Op::OpPhi && + opcode != spv::Op::OpExtInst && + opcode != spv::Op::OpExtInstImport && + opcode != spv::Op::OpSelectionMerge && + opcode != spv::Op::OpLoopMerge && + opcode != spv::Op::OpFunction && + opcode != spv::Op::OpCooperativeMatrixLengthNV && + !(opcode == spv::Op::OpSpecConstantOp && + spv::Op(inst->word(3)) == + spv::Op::OpCooperativeMatrixLengthNV)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Operand " << _.getIdName(operand_word) << " requires a type"; diff --git a/3rdparty/spirv-tools/source/val/validate_image.cpp b/3rdparty/spirv-tools/source/val/validate_image.cpp index 9c7c8c1c1..8f0e6c4d4 100644 --- a/3rdparty/spirv-tools/source/val/validate_image.cpp +++ b/3rdparty/spirv-tools/source/val/validate_image.cpp @@ -32,47 +32,47 @@ namespace spvtools { namespace val { namespace { -// Performs compile time check that all SpvImageOperandsXXX cases are handled in -// this module. If SpvImageOperandsXXX list changes, this function will fail the -// build. -// For all other purposes this is a placeholder function. +// Performs compile time check that all spv::ImageOperandsMask::XXX cases are +// handled in this module. If spv::ImageOperandsMask::XXX list changes, this +// function will fail the build. For all other purposes this is a placeholder +// function. bool CheckAllImageOperandsHandled() { - SpvImageOperandsMask enum_val = SpvImageOperandsBiasMask; + spv::ImageOperandsMask enum_val = spv::ImageOperandsMask::Bias; // Some improvised code to prevent the compiler from considering enum_val // constant and optimizing the switch away. uint32_t stack_var = 0; if (reinterpret_cast(&stack_var) % 256) - enum_val = SpvImageOperandsLodMask; + enum_val = spv::ImageOperandsMask::Lod; switch (enum_val) { // Please update the validation rules in this module if you are changing // the list of image operands, and add new enum values to this switch. - case SpvImageOperandsMaskNone: + case spv::ImageOperandsMask::MaskNone: return false; - case SpvImageOperandsBiasMask: - case SpvImageOperandsLodMask: - case SpvImageOperandsGradMask: - case SpvImageOperandsConstOffsetMask: - case SpvImageOperandsOffsetMask: - case SpvImageOperandsConstOffsetsMask: - case SpvImageOperandsSampleMask: - case SpvImageOperandsMinLodMask: + case spv::ImageOperandsMask::Bias: + case spv::ImageOperandsMask::Lod: + case spv::ImageOperandsMask::Grad: + case spv::ImageOperandsMask::ConstOffset: + case spv::ImageOperandsMask::Offset: + case spv::ImageOperandsMask::ConstOffsets: + case spv::ImageOperandsMask::Sample: + case spv::ImageOperandsMask::MinLod: // TODO(dneto): Support image operands related to the Vulkan memory model. // https://gitlab.khronos.org/spirv/spirv-tools/issues/32 - case SpvImageOperandsMakeTexelAvailableKHRMask: - case SpvImageOperandsMakeTexelVisibleKHRMask: - case SpvImageOperandsNonPrivateTexelKHRMask: - case SpvImageOperandsVolatileTexelKHRMask: - case SpvImageOperandsSignExtendMask: - case SpvImageOperandsZeroExtendMask: + case spv::ImageOperandsMask::MakeTexelAvailableKHR: + case spv::ImageOperandsMask::MakeTexelVisibleKHR: + case spv::ImageOperandsMask::NonPrivateTexelKHR: + case spv::ImageOperandsMask::VolatileTexelKHR: + case spv::ImageOperandsMask::SignExtend: + case spv::ImageOperandsMask::ZeroExtend: // TODO(jaebaek): Move this line properly after handling image offsets // operand. This line temporarily fixes CI failure that // blocks other PRs. // https://github.com/KhronosGroup/SPIRV-Tools/issues/4565 - case SpvImageOperandsOffsetsMask: - case SpvImageOperandsNontemporalMask: + case spv::ImageOperandsMask::Offsets: + case spv::ImageOperandsMask::Nontemporal: return true; } return false; @@ -81,13 +81,13 @@ bool CheckAllImageOperandsHandled() { // Used by GetImageTypeInfo. See OpTypeImage spec for more information. struct ImageTypeInfo { uint32_t sampled_type = 0; - SpvDim dim = SpvDimMax; + spv::Dim dim = spv::Dim::Max; uint32_t depth = 0; uint32_t arrayed = 0; uint32_t multisampled = 0; uint32_t sampled = 0; - SpvImageFormat format = SpvImageFormatMax; - SpvAccessQualifier access_qualifier = SpvAccessQualifierMax; + spv::ImageFormat format = spv::ImageFormat::Max; + spv::AccessQualifier access_qualifier = spv::AccessQualifier::Max; }; // Provides information on image type. |id| should be object of either @@ -100,39 +100,39 @@ bool GetImageTypeInfo(const ValidationState_t& _, uint32_t id, const Instruction* inst = _.FindDef(id); assert(inst); - if (inst->opcode() == SpvOpTypeSampledImage) { + if (inst->opcode() == spv::Op::OpTypeSampledImage) { inst = _.FindDef(inst->word(2)); assert(inst); } - if (inst->opcode() != SpvOpTypeImage) return false; + if (inst->opcode() != spv::Op::OpTypeImage) return false; const size_t num_words = inst->words().size(); if (num_words != 9 && num_words != 10) return false; info->sampled_type = inst->word(2); - info->dim = static_cast(inst->word(3)); + info->dim = static_cast(inst->word(3)); info->depth = inst->word(4); info->arrayed = inst->word(5); info->multisampled = inst->word(6); info->sampled = inst->word(7); - info->format = static_cast(inst->word(8)); - info->access_qualifier = num_words < 10 - ? SpvAccessQualifierMax - : static_cast(inst->word(9)); + info->format = static_cast(inst->word(8)); + info->access_qualifier = + num_words < 10 ? spv::AccessQualifier::Max + : static_cast(inst->word(9)); return true; } -bool IsImplicitLod(SpvOp opcode) { +bool IsImplicitLod(spv::Op opcode) { switch (opcode) { - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseSampleProjImplicitLod: - case SpvOpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: return true; default: break; @@ -140,16 +140,16 @@ bool IsImplicitLod(SpvOp opcode) { return false; } -bool IsExplicitLod(SpvOp opcode) { +bool IsExplicitLod(spv::Op opcode) { switch (opcode) { - case SpvOpImageSampleExplicitLod: - case SpvOpImageSampleDrefExplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageSparseSampleExplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: - case SpvOpImageSparseSampleProjExplicitLod: - case SpvOpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: return true; default: break; @@ -157,22 +157,22 @@ bool IsExplicitLod(SpvOp opcode) { return false; } -bool IsValidLodOperand(const ValidationState_t& _, SpvOp opcode) { +bool IsValidLodOperand(const ValidationState_t& _, spv::Op opcode) { switch (opcode) { - case SpvOpImageRead: - case SpvOpImageWrite: - case SpvOpImageSparseRead: - return _.HasCapability(SpvCapabilityImageReadWriteLodAMD); + case spv::Op::OpImageRead: + case spv::Op::OpImageWrite: + case spv::Op::OpImageSparseRead: + return _.HasCapability(spv::Capability::ImageReadWriteLodAMD); default: return IsExplicitLod(opcode); } } -bool IsValidGatherLodBiasAMD(const ValidationState_t& _, SpvOp opcode) { +bool IsValidGatherLodBiasAMD(const ValidationState_t& _, spv::Op opcode) { switch (opcode) { - case SpvOpImageGather: - case SpvOpImageSparseGather: - return _.HasCapability(SpvCapabilityImageGatherBiasLodAMD); + case spv::Op::OpImageGather: + case spv::Op::OpImageSparseGather: + return _.HasCapability(spv::Capability::ImageGatherBiasLodAMD); default: break; } @@ -181,16 +181,16 @@ bool IsValidGatherLodBiasAMD(const ValidationState_t& _, SpvOp opcode) { // Returns true if the opcode is a Image instruction which applies // homogenous projection to the coordinates. -bool IsProj(SpvOp opcode) { +bool IsProj(spv::Op opcode) { switch (opcode) { - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleProjImplicitLod: - case SpvOpImageSparseSampleProjDrefImplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageSparseSampleProjExplicitLod: - case SpvOpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: return true; default: break; @@ -204,21 +204,21 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) { uint32_t plane_size = 0; // If this switch breaks your build, please add new values below. switch (info.dim) { - case SpvDim1D: - case SpvDimBuffer: + case spv::Dim::Dim1D: + case spv::Dim::Buffer: plane_size = 1; break; - case SpvDim2D: - case SpvDimRect: - case SpvDimSubpassData: + case spv::Dim::Dim2D: + case spv::Dim::Rect: + case spv::Dim::SubpassData: plane_size = 2; break; - case SpvDim3D: - case SpvDimCube: + case spv::Dim::Dim3D: + case spv::Dim::Cube: // For Cube direction vector is used instead of UV. plane_size = 3; break; - case SpvDimMax: + case spv::Dim::Max: assert(0); break; } @@ -228,10 +228,10 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) { // Returns minimal number of coordinates based on image dim, arrayed and whether // the instruction uses projection coordinates. -uint32_t GetMinCoordSize(SpvOp opcode, const ImageTypeInfo& info) { - if (info.dim == SpvDimCube && - (opcode == SpvOpImageRead || opcode == SpvOpImageWrite || - opcode == SpvOpImageSparseRead)) { +uint32_t GetMinCoordSize(spv::Op opcode, const ImageTypeInfo& info) { + if (info.dim == spv::Dim::Cube && + (opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || + opcode == spv::Op::OpImageSparseRead)) { // These opcodes use UV for Cube, not direction vector. return 3; } @@ -248,7 +248,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled(); (void)kAllImageOperandsHandled; - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const size_t num_words = inst->words().size(); const bool have_explicit_mask = (word_index - 1 < num_words); @@ -257,14 +257,14 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, if (have_explicit_mask) { // NonPrivate, Volatile, SignExtend, ZeroExtend take no operand words. const uint32_t mask_bits_having_operands = - mask & ~uint32_t(SpvImageOperandsNonPrivateTexelKHRMask | - SpvImageOperandsVolatileTexelKHRMask | - SpvImageOperandsSignExtendMask | - SpvImageOperandsZeroExtendMask | - SpvImageOperandsNontemporalMask); + mask & ~uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR | + spv::ImageOperandsMask::VolatileTexelKHR | + spv::ImageOperandsMask::SignExtend | + spv::ImageOperandsMask::ZeroExtend | + spv::ImageOperandsMask::Nontemporal); size_t expected_num_image_operand_words = spvtools::utils::CountSetBits(mask_bits_having_operands); - if (mask & SpvImageOperandsGradMask) { + if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { // Grad uses two words. ++expected_num_image_operand_words; } @@ -279,7 +279,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, << "Number of image operand ids doesn't correspond to the bit mask"; } - if (info.multisampled & (0 == (mask & SpvImageOperandsSampleMask))) { + if (info.multisampled & + (0 == (mask & uint32_t(spv::ImageOperandsMask::Sample)))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Sample is required for operation on " "multi-sampled image"; @@ -289,10 +290,11 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // the module to be invalid. if (mask == 0) return SPV_SUCCESS; - if (spvtools::utils::CountSetBits(mask & (SpvImageOperandsOffsetMask | - SpvImageOperandsConstOffsetMask | - SpvImageOperandsConstOffsetsMask | - SpvImageOperandsOffsetsMask)) > 1) { + if (spvtools::utils::CountSetBits( + mask & uint32_t(spv::ImageOperandsMask::Offset | + spv::ImageOperandsMask::ConstOffset | + spv::ImageOperandsMask::ConstOffsets | + spv::ImageOperandsMask::Offsets)) > 1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4662) << "Image Operands Offset, ConstOffset, ConstOffsets, Offsets " @@ -306,7 +308,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // The checks should be done in the order of definition of OperandImage. - if (mask & SpvImageOperandsBiasMask) { + if (mask & uint32_t(spv::ImageOperandsMask::Bias)) { if (!is_implicit_lod && !is_valid_gather_lod_bias_amd) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Bias can only be used with ImplicitLod opcodes"; @@ -318,8 +320,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, << "Expected Image Operand Bias to be float scalar"; } - if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && - info.dim != SpvDimCube) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Bias requires 'Dim' parameter to be 1D, 2D, 3D " "or Cube"; @@ -328,15 +330,16 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Multisampled is already checked. } - if (mask & SpvImageOperandsLodMask) { - if (!is_valid_lod_operand && opcode != SpvOpImageFetch && - opcode != SpvOpImageSparseFetch && !is_valid_gather_lod_bias_amd) { + if (mask & uint32_t(spv::ImageOperandsMask::Lod)) { + if (!is_valid_lod_operand && opcode != spv::Op::OpImageFetch && + opcode != spv::Op::OpImageSparseFetch && + !is_valid_gather_lod_bias_amd) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Lod can only be used with ExplicitLod opcodes " << "and OpImageFetch"; } - if (mask & SpvImageOperandsGradMask) { + if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand bits Lod and Grad cannot be set at the same " "time"; @@ -357,8 +360,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && - info.dim != SpvDimCube) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Lod requires 'Dim' parameter to be 1D, 2D, 3D " "or Cube"; @@ -367,7 +370,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Multisampled is already checked. } - if (mask & SpvImageOperandsGradMask) { + if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { if (!is_explicit_lod) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Grad can only be used with ExplicitLod opcodes"; @@ -400,8 +403,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Multisampled is already checked. } - if (mask & SpvImageOperandsConstOffsetMask) { - if (info.dim == SpvDimCube) { + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { + if (info.dim == spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand ConstOffset cannot be used with Cube Image " "'Dim'"; @@ -429,8 +432,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & SpvImageOperandsOffsetMask) { - if (info.dim == SpvDimCube) { + if (mask & uint32_t(spv::ImageOperandsMask::Offset)) { + if (info.dim == spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Offset cannot be used with Cube Image 'Dim'"; } @@ -453,9 +456,10 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, if (!_.options()->before_hlsl_legalization && spvIsVulkanEnv(_.context()->target_env)) { - if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather && - opcode != SpvOpImageSparseGather && - opcode != SpvOpImageSparseDrefGather) { + if (opcode != spv::Op::OpImageGather && + opcode != spv::Op::OpImageDrefGather && + opcode != spv::Op::OpImageSparseGather && + opcode != spv::Op::OpImageSparseDrefGather) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4663) << "Image Operand Offset can only be used with " @@ -464,16 +468,17 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & SpvImageOperandsConstOffsetsMask) { - if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather && - opcode != SpvOpImageSparseGather && - opcode != SpvOpImageSparseDrefGather) { + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffsets)) { + if (opcode != spv::Op::OpImageGather && + opcode != spv::Op::OpImageDrefGather && + opcode != spv::Op::OpImageSparseGather && + opcode != spv::Op::OpImageSparseDrefGather) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand ConstOffsets can only be used with " "OpImageGather and OpImageDrefGather"; } - if (info.dim == SpvDimCube) { + if (info.dim == spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand ConstOffsets cannot be used with Cube Image " "'Dim'"; @@ -484,7 +489,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, const Instruction* type_inst = _.FindDef(type_id); assert(type_inst); - if (type_inst->opcode() != SpvOpTypeArray) { + if (type_inst->opcode() != spv::Op::OpTypeArray) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image Operand ConstOffsets to be an array of size 4"; } @@ -513,10 +518,11 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & SpvImageOperandsSampleMask) { - if (opcode != SpvOpImageFetch && opcode != SpvOpImageRead && - opcode != SpvOpImageWrite && opcode != SpvOpImageSparseFetch && - opcode != SpvOpImageSparseRead) { + if (mask & uint32_t(spv::ImageOperandsMask::Sample)) { + if (opcode != spv::Op::OpImageFetch && opcode != spv::Op::OpImageRead && + opcode != spv::Op::OpImageWrite && + opcode != spv::Op::OpImageSparseFetch && + opcode != spv::Op::OpImageSparseRead) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Sample can only be used with OpImageFetch, " << "OpImageRead, OpImageWrite, OpImageSparseFetch and " @@ -535,8 +541,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & SpvImageOperandsMinLodMask) { - if (!is_implicit_lod && !(mask & SpvImageOperandsGradMask)) { + if (mask & uint32_t(spv::ImageOperandsMask::MinLod)) { + if (!is_implicit_lod && !(mask & uint32_t(spv::ImageOperandsMask::Grad))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MinLod can only be used with ImplicitLod " << "opcodes or together with Image Operand Grad"; @@ -548,8 +554,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, << "Expected Image Operand MinLod to be float scalar"; } - if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && - info.dim != SpvDimCube) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MinLod requires 'Dim' parameter to be 1D, 2D, " "3D or Cube"; @@ -561,16 +567,16 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & SpvImageOperandsMakeTexelAvailableKHRMask) { + if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR)) { // Checked elsewhere: capability and memory model are correct. - if (opcode != SpvOpImageWrite) { + if (opcode != spv::Op::OpImageWrite) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelAvailableKHR can only be used with Op" - << spvOpcodeString(SpvOpImageWrite) << ": Op" + << spvOpcodeString(spv::Op::OpImageWrite) << ": Op" << spvOpcodeString(opcode); } - if (!(mask & SpvImageOperandsNonPrivateTexelKHRMask)) { + if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelAvailableKHR requires " "NonPrivateTexelKHR is also specified: Op" @@ -582,17 +588,18 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, return error; } - if (mask & SpvImageOperandsMakeTexelVisibleKHRMask) { + if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR)) { // Checked elsewhere: capability and memory model are correct. - if (opcode != SpvOpImageRead && opcode != SpvOpImageSparseRead) { + if (opcode != spv::Op::OpImageRead && + opcode != spv::Op::OpImageSparseRead) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelVisibleKHR can only be used with Op" - << spvOpcodeString(SpvOpImageRead) << " or Op" - << spvOpcodeString(SpvOpImageSparseRead) << ": Op" + << spvOpcodeString(spv::Op::OpImageRead) << " or Op" + << spvOpcodeString(spv::Op::OpImageSparseRead) << ": Op" << spvOpcodeString(opcode); } - if (!(mask & SpvImageOperandsNonPrivateTexelKHRMask)) { + if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelVisibleKHR requires NonPrivateTexelKHR " "is also specified: Op" @@ -603,7 +610,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error; } - if (mask & SpvImageOperandsSignExtendMask) { + if (mask & uint32_t(spv::ImageOperandsMask::SignExtend)) { // Checked elsewhere: SPIR-V 1.4 version or later. // "The texel value is converted to the target value via sign extension. @@ -616,7 +623,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // setup. } - if (mask & SpvImageOperandsZeroExtendMask) { + if (mask & uint32_t(spv::ImageOperandsMask::ZeroExtend)) { // Checked elsewhere: SPIR-V 1.4 version or later. // "The texel value is converted to the target value via zero extension. @@ -629,11 +636,11 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // setup. } - if (mask & SpvImageOperandsOffsetsMask) { + if (mask & uint32_t(spv::ImageOperandsMask::Offsets)) { // TODO: add validation } - if (mask & SpvImageOperandsNontemporalMask) { + if (mask & uint32_t(spv::ImageOperandsMask::Nontemporal)) { // Checked elsewhere: SPIR-V 1.6 version or later. } @@ -643,8 +650,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Validate OpImage*Proj* instructions spv_result_t ValidateImageProj(ValidationState_t& _, const Instruction* inst, const ImageTypeInfo& info) { - if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && - info.dim != SpvDimRect) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Rect) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect"; } @@ -667,25 +674,27 @@ spv_result_t ValidateImageReadWrite(ValidationState_t& _, const Instruction* inst, const ImageTypeInfo& info) { if (info.sampled == 2) { - if (info.dim == SpvDim1D && !_.HasCapability(SpvCapabilityImage1D)) { + if (info.dim == spv::Dim::Dim1D && + !_.HasCapability(spv::Capability::Image1D)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability Image1D is required to access storage image"; - } else if (info.dim == SpvDimRect && - !_.HasCapability(SpvCapabilityImageRect)) { + } else if (info.dim == spv::Dim::Rect && + !_.HasCapability(spv::Capability::ImageRect)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability ImageRect is required to access storage image"; - } else if (info.dim == SpvDimBuffer && - !_.HasCapability(SpvCapabilityImageBuffer)) { + } else if (info.dim == spv::Dim::Buffer && + !_.HasCapability(spv::Capability::ImageBuffer)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability ImageBuffer is required to access storage image"; - } else if (info.dim == SpvDimCube && info.arrayed == 1 && - !_.HasCapability(SpvCapabilityImageCubeArray)) { + } else if (info.dim == spv::Dim::Cube && info.arrayed == 1 && + !_.HasCapability(spv::Capability::ImageCubeArray)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability ImageCubeArray is required to access " << "storage image"; } - if (info.multisampled == 1 && !_.HasCapability(SpvCapabilityImageMSArray)) { + if (info.multisampled == 1 && + !_.HasCapability(spv::Capability::ImageMSArray)) { #if 0 // TODO(atgoo@github.com) The description of this rule in the spec // is unclear and Glslang doesn't declare ImageMSArray. Need to clarify @@ -704,21 +713,21 @@ spv_result_t ValidateImageReadWrite(ValidationState_t& _, } // Returns true if opcode is *ImageSparse*, false otherwise. -bool IsSparse(SpvOp opcode) { +bool IsSparse(spv::Op opcode) { switch (opcode) { - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleExplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: - case SpvOpImageSparseSampleProjImplicitLod: - case SpvOpImageSparseSampleProjExplicitLod: - case SpvOpImageSparseSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleProjDrefExplicitLod: - case SpvOpImageSparseFetch: - case SpvOpImageSparseGather: - case SpvOpImageSparseDrefGather: - case SpvOpImageSparseTexelsResident: - case SpvOpImageSparseRead: { + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageSparseTexelsResident: + case spv::Op::OpImageSparseRead: { return true; } @@ -733,13 +742,13 @@ bool IsSparse(SpvOp opcode) { // Not valid for sparse image opcodes which do not return a struct. spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst, uint32_t* actual_result_type) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); if (IsSparse(opcode)) { const Instruction* const type_inst = _.FindDef(inst->type_id()); assert(type_inst); - if (!type_inst || type_inst->opcode() != SpvOpTypeStruct) { + if (!type_inst || type_inst->opcode() != spv::Op::OpTypeStruct) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeStruct"; } @@ -761,7 +770,7 @@ spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst, // Returns a string describing actual result type of an opcode. // Not valid for sparse image opcodes which do not return a struct. -const char* GetActualResultTypeStr(SpvOp opcode) { +const char* GetActualResultTypeStr(spv::Op opcode) { if (IsSparse(opcode)) return "Result Type's second member"; return "Result Type"; } @@ -777,7 +786,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { if (_.IsIntScalarType(info.sampled_type) && (64 == _.GetBitWidth(info.sampled_type)) && - !_.HasCapability(SpvCapabilityInt64ImageEXT)) { + !_.HasCapability(spv::Capability::Int64ImageEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability Int64ImageEXT is required when using Sampled Type of " "64-bit int"; @@ -802,10 +811,10 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Sampled Type must be OpTypeVoid in the OpenCL environment."; } } else { - const SpvOp sampled_type_opcode = _.GetIdOpcode(info.sampled_type); - if (sampled_type_opcode != SpvOpTypeVoid && - sampled_type_opcode != SpvOpTypeInt && - sampled_type_opcode != SpvOpTypeFloat) { + const spv::Op sampled_type_opcode = _.GetIdOpcode(info.sampled_type); + if (sampled_type_opcode != spv::Op::OpTypeVoid && + sampled_type_opcode != spv::Op::OpTypeInt && + sampled_type_opcode != spv::Op::OpTypeFloat) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Type to be either void or" << " numerical scalar type"; @@ -835,19 +844,19 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)"; } - if (info.dim == SpvDimSubpassData) { + if (info.dim == spv::Dim::SubpassData) { if (info.sampled != 2) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(6214) << "Dim SubpassData requires Sampled to be 2"; } - if (info.format != SpvImageFormatUnknown) { + if (info.format != spv::ImageFormat::Unknown) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Dim SubpassData requires format Unknown"; } } else { if (info.multisampled && (info.sampled == 2) && - !_.HasCapability(SpvCapabilityStorageImageMultisample)) { + !_.HasCapability(spv::Capability::StorageImageMultisample)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability StorageImageMultisample is required when using " "multisampled storage image"; @@ -855,8 +864,8 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { } if (spvIsOpenCLEnv(target_env)) { - if ((info.arrayed == 1) && (info.dim != SpvDim1D) && - (info.dim != SpvDim2D)) { + if ((info.arrayed == 1) && (info.dim != spv::Dim::Dim1D) && + (info.dim != spv::Dim::Dim2D)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "In the OpenCL environment, Arrayed may only be set to 1 " << "when Dim is either 1D or 2D."; @@ -872,7 +881,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Sampled must be 0 in the OpenCL environment."; } - if (info.access_qualifier == SpvAccessQualifierMax) { + if (info.access_qualifier == spv::AccessQualifier::Max) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "In the OpenCL environment, the optional Access Qualifier" << " must be present."; @@ -886,7 +895,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Sampled must be 1 or 2 in the Vulkan environment."; } - if (info.dim == SpvDimSubpassData && info.arrayed != 0) { + if (info.dim == spv::Dim::SubpassData && info.arrayed != 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0"; } @@ -898,7 +907,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateTypeSampledImage(ValidationState_t& _, const Instruction* inst) { const uint32_t image_type = inst->word(2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -918,7 +927,8 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _, } // This covers both OpTypeSampledImage and OpSampledImage. - if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && info.dim == SpvDimBuffer) { + if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && + info.dim == spv::Dim::Buffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "In SPIR-V 1.6 or later, sampled image dimension must not be " "Buffer"; @@ -927,31 +937,31 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _, return SPV_SUCCESS; } -bool IsAllowedSampledImageOperand(SpvOp opcode, ValidationState_t& _) { +bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) { switch (opcode) { - case SpvOpSampledImage: - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleExplicitLod: - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleDrefExplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageGather: - case SpvOpImageDrefGather: - case SpvOpImage: - case SpvOpImageQueryLod: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleExplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: - case SpvOpImageSparseGather: - case SpvOpImageSparseDrefGather: - case SpvOpCopyObject: + case spv::Op::OpSampledImage: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImage: + case spv::Op::OpImageQueryLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpCopyObject: return true; - case SpvOpStore: - if (_.HasCapability(SpvCapabilityBindlessTextureNV)) return true; + case spv::Op::OpStore: + if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true; return false; default: return false; @@ -960,13 +970,13 @@ bool IsAllowedSampledImageOperand(SpvOp opcode, ValidationState_t& _) { spv_result_t ValidateSampledImage(ValidationState_t& _, const Instruction* inst) { - if (_.GetIdOpcode(inst->type_id()) != SpvOpTypeSampledImage) { + if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeSampledImage."; } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage."; } @@ -994,12 +1004,12 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, } } - if (info.dim == SpvDimSubpassData) { + if (info.dim == spv::Dim::SubpassData) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image 'Dim' parameter to be not SubpassData."; } - if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != SpvOpTypeSampler) { + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != spv::Op::OpTypeSampler) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampler to be of type OpTypeSampler"; } @@ -1027,12 +1037,13 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, << _.getIdName(consumer_instr->id()) << "."; } - if (consumer_opcode == SpvOpPhi || consumer_opcode == SpvOpSelect) { + if (consumer_opcode == spv::Op::OpPhi || + consumer_opcode == spv::Op::OpSelect) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result from OpSampledImage instruction must not appear " "as " "operands of Op" - << spvOpcodeString(static_cast(consumer_opcode)) << "." + << spvOpcodeString(static_cast(consumer_opcode)) << "." << " Found result " << _.getIdName(inst->id()) << " as an operand of " << _.getIdName(consumer_instr->id()) << "."; @@ -1042,7 +1053,7 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result from OpSampledImage instruction must not appear " "as operand for Op" - << spvOpcodeString(static_cast(consumer_opcode)) + << spvOpcodeString(static_cast(consumer_opcode)) << ", since it is not specified as taking an " << "OpTypeSampledImage." << " Found result " << _.getIdName(inst->id()) @@ -1057,13 +1068,13 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, spv_result_t ValidateImageTexelPointer(ValidationState_t& _, const Instruction* inst) { const auto result_type = _.FindDef(inst->type_id()); - if (result_type->opcode() != SpvOpTypePointer) { + if (result_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypePointer"; } - const auto storage_class = result_type->GetOperandAs(1); - if (storage_class != SpvStorageClassImage) { + const auto storage_class = result_type->GetOperandAs(1); + if (storage_class != spv::StorageClass::Image) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypePointer whose Storage Class " "operand is Image"; @@ -1071,21 +1082,21 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, const auto ptr_type = result_type->GetOperandAs(2); const auto ptr_opcode = _.GetIdOpcode(ptr_type); - if (ptr_opcode != SpvOpTypeInt && ptr_opcode != SpvOpTypeFloat && - ptr_opcode != SpvOpTypeVoid) { + if (ptr_opcode != spv::Op::OpTypeInt && ptr_opcode != spv::Op::OpTypeFloat && + ptr_opcode != spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypePointer whose Type operand " "must be a scalar numerical type or OpTypeVoid"; } const auto image_ptr = _.FindDef(_.GetOperandTypeId(inst, 2)); - if (!image_ptr || image_ptr->opcode() != SpvOpTypePointer) { + if (!image_ptr || image_ptr->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be OpTypePointer"; } const auto image_type = image_ptr->GetOperandAs(2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be OpTypePointer with Type OpTypeImage"; } @@ -1102,7 +1113,7 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, "pointed to by Result Type"; } - if (info.dim == SpvDimSubpassData) { + if (info.dim == spv::Dim::SubpassData) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Dim SubpassData cannot be used with OpImageTexelPointer"; } @@ -1118,11 +1129,11 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, expected_coord_size = GetPlaneCoordSize(info); } else if (info.arrayed == 1) { switch (info.dim) { - case SpvDim1D: + case spv::Dim::Dim1D: expected_coord_size = 2; break; - case SpvDimCube: - case SpvDim2D: + case spv::Dim::Cube: + case spv::Dim::Dim2D: expected_coord_size = 3; break; default: @@ -1157,11 +1168,11 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, } if (spvIsVulkanEnv(_.context()->target_env)) { - if ((info.format != SpvImageFormatR64i) && - (info.format != SpvImageFormatR64ui) && - (info.format != SpvImageFormatR32f) && - (info.format != SpvImageFormatR32i) && - (info.format != SpvImageFormatR32ui)) { + if ((info.format != spv::ImageFormat::R64i) && + (info.format != spv::ImageFormat::R64ui) && + (info.format != spv::ImageFormat::R32f) && + (info.format != spv::ImageFormat::R32i) && + (info.format != spv::ImageFormat::R32ui)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4658) << "Expected the Image Format in Image to be R64i, R64ui, R32f, " @@ -1173,7 +1184,7 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, } spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); uint32_t actual_result_type = 0; if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { return error; @@ -1193,7 +1204,7 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Image to be of type OpTypeSampledImage"; } @@ -1216,7 +1227,7 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { << "Sampling operation is invalid for multisample image"; } - if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { const uint32_t texel_component_type = _.GetComponentType(actual_result_type); if (texel_component_type != info.sampled_type) { @@ -1227,9 +1238,9 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { } const uint32_t coord_type = _.GetOperandTypeId(inst, 3); - if ((opcode == SpvOpImageSampleExplicitLod || - opcode == SpvOpImageSparseSampleExplicitLod) && - _.HasCapability(SpvCapabilityKernel)) { + if ((opcode == spv::Op::OpImageSampleExplicitLod || + opcode == spv::Op::OpImageSparseSampleExplicitLod) && + _.HasCapability(spv::Capability::Kernel)) { if (!_.IsFloatScalarOrVectorType(coord_type) && !_.IsIntScalarOrVectorType(coord_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1252,9 +1263,9 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5); - if (mask & SpvImageOperandsConstOffsetMask) { + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { if (spvIsOpenCLEnv(_.context()->target_env)) { - if (opcode == SpvOpImageSampleExplicitLod) { + if (opcode == spv::Op::OpImageSampleExplicitLod) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "ConstOffset image operand not allowed " << "in the OpenCL environment."; @@ -1279,7 +1290,7 @@ spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst, } if (spvIsVulkanEnv(_.context()->target_env)) { - if (info.dim == SpvDim3D) { + if (info.dim == spv::Dim::Dim3D) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4777) << "In Vulkan, OpImage*Dref* instructions must not use images " @@ -1292,7 +1303,7 @@ spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateImageDrefLod(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); uint32_t actual_result_type = 0; if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { return error; @@ -1306,7 +1317,7 @@ spv_result_t ValidateImageDrefLod(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Image to be of type OpTypeSampledImage"; } @@ -1364,7 +1375,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { return error; } - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); if (!_.IsIntVectorType(actual_result_type) && !_.IsFloatVectorType(actual_result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1379,7 +1390,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1390,7 +1401,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { << "Corrupt image type definition"; } - if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { const uint32_t result_component_type = _.GetComponentType(actual_result_type); if (result_component_type != info.sampled_type) { @@ -1400,7 +1411,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { } } - if (info.dim == SpvDimCube) { + if (info.dim == spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be Cube"; } @@ -1436,7 +1447,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) return error; - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); if (!_.IsIntVectorType(actual_result_type) && !_.IsFloatVectorType(actual_result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1451,7 +1462,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Image to be of type OpTypeSampledImage"; } @@ -1470,8 +1481,9 @@ spv_result_t ValidateImageGather(ValidationState_t& _, << "Gather operation is invalid for multisample image"; } - if (opcode == SpvOpImageDrefGather || opcode == SpvOpImageSparseDrefGather || - _.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { + if (opcode == spv::Op::OpImageDrefGather || + opcode == spv::Op::OpImageSparseDrefGather || + _.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { const uint32_t result_component_type = _.GetComponentType(actual_result_type); if (result_component_type != info.sampled_type) { @@ -1481,8 +1493,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } } - if (info.dim != SpvDim2D && info.dim != SpvDimCube && - info.dim != SpvDimRect) { + if (info.dim != spv::Dim::Dim2D && info.dim != spv::Dim::Cube && + info.dim != spv::Dim::Rect) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4777) << "Expected Image 'Dim' to be 2D, Cube, or Rect"; @@ -1502,7 +1514,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, << " components, but given only " << actual_coord_size; } - if (opcode == SpvOpImageGather || opcode == SpvOpImageSparseGather) { + if (opcode == spv::Op::OpImageGather || + opcode == spv::Op::OpImageSparseGather) { const uint32_t component = inst->GetOperandAs(4); const uint32_t component_index_type = _.GetTypeId(component); if (!_.IsIntScalarType(component_index_type) || @@ -1519,8 +1532,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } } } else { - assert(opcode == SpvOpImageDrefGather || - opcode == SpvOpImageSparseDrefGather); + assert(opcode == spv::Op::OpImageDrefGather || + opcode == spv::Op::OpImageSparseDrefGather); if (spv_result_t result = ValidateImageDref(_, inst, info)) return result; } @@ -1532,7 +1545,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); uint32_t actual_result_type = 0; if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { return error; @@ -1557,7 +1570,7 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } // Check OpenCL below, after we get the image info. const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1591,27 +1604,27 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5); - if (mask & SpvImageOperandsConstOffsetMask) { + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "ConstOffset image operand not allowed " << "in the OpenCL environment."; } } - if (info.dim == SpvDimSubpassData) { - if (opcode == SpvOpImageSparseRead) { + if (info.dim == spv::Dim::SubpassData) { + if (opcode == spv::Op::OpImageSparseRead) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Dim SubpassData cannot be used with ImageSparseRead"; } _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, std::string("Dim SubpassData requires Fragment execution model: ") + spvOpcodeString(opcode)); } - if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { const uint32_t result_component_type = _.GetComponentType(actual_result_type); if (result_component_type != info.sampled_type) { @@ -1639,8 +1652,9 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env)) { - if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData && - !_.HasCapability(SpvCapabilityStorageImageReadWithoutFormat)) { + if (info.format == spv::ImageFormat::Unknown && + info.dim != spv::Dim::SubpassData && + !_.HasCapability(spv::Capability::StorageImageReadWithoutFormat)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability StorageImageReadWithoutFormat is required to " << "read storage image"; @@ -1656,7 +1670,7 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { const uint32_t image_type = _.GetOperandTypeId(inst, 0); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1667,7 +1681,7 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { << "Corrupt image type definition"; } - if (info.dim == SpvDimSubpassData) { + if (info.dim == spv::Dim::SubpassData) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be SubpassData"; } @@ -1697,7 +1711,7 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { << "Expected Texel to be int or float vector or scalar"; } - if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { const uint32_t texel_component_type = _.GetComponentType(texel_type); if (texel_component_type != info.sampled_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1707,8 +1721,9 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env)) { - if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData && - !_.HasCapability(SpvCapabilityStorageImageWriteWithoutFormat)) { + if (info.format == spv::ImageFormat::Unknown && + info.dim != spv::Dim::SubpassData && + !_.HasCapability(spv::Capability::StorageImageWriteWithoutFormat)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability StorageImageWriteWithoutFormat is required to " "write " @@ -1733,7 +1748,7 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateImage(ValidationState_t& _, const Instruction* inst) { const uint32_t result_type = inst->type_id(); - if (_.GetIdOpcode(result_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeImage"; } @@ -1742,7 +1757,7 @@ spv_result_t ValidateImage(ValidationState_t& _, const Instruction* inst) { const Instruction* sampled_image_type_inst = _.FindDef(sampled_image_type); assert(sampled_image_type_inst); - if (sampled_image_type_inst->opcode() != SpvOpTypeSampledImage) { + if (sampled_image_type_inst->opcode() != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sample Image to be of type OpTypeSampleImage"; } @@ -1764,7 +1779,7 @@ spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1777,14 +1792,14 @@ spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _, uint32_t expected_num_components = info.arrayed; switch (info.dim) { - case SpvDim1D: + case spv::Dim::Dim1D: expected_num_components += 1; break; - case SpvDim2D: - case SpvDimCube: + case spv::Dim::Dim2D: + case spv::Dim::Cube: expected_num_components += 2; break; - case SpvDim3D: + case spv::Dim::Dim3D: expected_num_components += 3; break; default: @@ -1830,7 +1845,7 @@ spv_result_t ValidateImageQuerySize(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1843,16 +1858,16 @@ spv_result_t ValidateImageQuerySize(ValidationState_t& _, uint32_t expected_num_components = info.arrayed; switch (info.dim) { - case SpvDim1D: - case SpvDimBuffer: + case spv::Dim::Dim1D: + case spv::Dim::Buffer: expected_num_components += 1; break; - case SpvDim2D: - case SpvDimCube: - case SpvDimRect: + case spv::Dim::Dim2D: + case spv::Dim::Cube: + case spv::Dim::Rect: expected_num_components += 2; break; - case SpvDim3D: + case spv::Dim::Dim3D: expected_num_components += 3; break; default: @@ -1860,8 +1875,8 @@ spv_result_t ValidateImageQuerySize(ValidationState_t& _, << "Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"; } - if (info.dim == SpvDim1D || info.dim == SpvDim2D || info.dim == SpvDim3D || - info.dim == SpvDimCube) { + if (info.dim == spv::Dim::Dim1D || info.dim == spv::Dim::Dim2D || + info.dim == spv::Dim::Dim3D || info.dim == spv::Dim::Cube) { if (info.multisampled != 1 && info.sampled != 0 && info.sampled != 2) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"; @@ -1885,7 +1900,7 @@ spv_result_t ValidateImageQueryFormatOrOrder(ValidationState_t& _, << "Expected Result Type to be int scalar type"; } - if (_.GetIdOpcode(_.GetOperandTypeId(inst, 2)) != SpvOpTypeImage) { + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 2)) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected operand to be of type OpTypeImage"; } @@ -1896,9 +1911,9 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, const Instruction* inst) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [&](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelFragment && - model != SpvExecutionModelGLCompute) { + [&](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::Fragment && + model != spv::ExecutionModel::GLCompute) { if (message) { *message = std::string( "OpImageQueryLod requires Fragment or GLCompute execution " @@ -1914,10 +1929,10 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, std::string* message) { const auto* models = state.GetExecutionModels(entry_point->id()); const auto* modes = state.GetExecutionModes(entry_point->id()); - if (models->find(SpvExecutionModelGLCompute) != models->end() && - modes->find(SpvExecutionModeDerivativeGroupLinearNV) == + if (models->find(spv::ExecutionModel::GLCompute) != models->end() && + modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == modes->end() && - modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == + modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == modes->end()) { if (message) { *message = std::string( @@ -1942,7 +1957,7 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image operand to be of type OpTypeSampledImage"; } @@ -1953,14 +1968,14 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, << "Corrupt image type definition"; } - if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && - info.dim != SpvDimCube) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 1D, 2D, 3D or Cube"; } const uint32_t coord_type = _.GetOperandTypeId(inst, 3); - if (_.HasCapability(SpvCapabilityKernel)) { + if (_.HasCapability(spv::Capability::Kernel)) { if (!_.IsFloatScalarOrVectorType(coord_type) && !_.IsIntScalarOrVectorType(coord_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2005,7 +2020,7 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -2016,10 +2031,10 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, << "Corrupt image type definition"; } - const SpvOp opcode = inst->opcode(); - if (opcode == SpvOpImageQueryLevels) { - if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && - info.dim != SpvDimCube) { + const spv::Op opcode = inst->opcode(); + if (opcode == spv::Op::OpImageQueryLevels) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 1D, 2D, 3D or Cube"; } @@ -2033,8 +2048,8 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, } } } else { - assert(opcode == SpvOpImageQuerySamples); - if (info.dim != SpvDim2D) { + assert(opcode == spv::Op::OpImageQuerySamples); + if (info.dim != spv::Dim::Dim2D) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 2D"; } @@ -2065,13 +2080,13 @@ spv_result_t ValidateImageSparseTexelsResident(ValidationState_t& _, // Validates correctness of image instructions. spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); if (IsImplicitLod(opcode)) { _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, + ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model, std::string* message) { - if (model != SpvExecutionModelFragment && - model != SpvExecutionModelGLCompute) { + if (model != spv::ExecutionModel::Fragment && + model != spv::ExecutionModel::GLCompute) { if (message) { *message = std::string( @@ -2090,11 +2105,11 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { const auto* models = state.GetExecutionModels(entry_point->id()); const auto* modes = state.GetExecutionModes(entry_point->id()); if (models && - models->find(SpvExecutionModelGLCompute) != models->end() && + models->find(spv::ExecutionModel::GLCompute) != models->end() && (!modes || - (modes->find(SpvExecutionModeDerivativeGroupLinearNV) == + (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == modes->end() && - modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == + modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == modes->end()))) { if (message) { *message = @@ -2111,73 +2126,73 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { } switch (opcode) { - case SpvOpTypeImage: + case spv::Op::OpTypeImage: return ValidateTypeImage(_, inst); - case SpvOpTypeSampledImage: + case spv::Op::OpTypeSampledImage: return ValidateTypeSampledImage(_, inst); - case SpvOpSampledImage: + case spv::Op::OpSampledImage: return ValidateSampledImage(_, inst); - case SpvOpImageTexelPointer: + case spv::Op::OpImageTexelPointer: return ValidateImageTexelPointer(_, inst); - case SpvOpImageSampleImplicitLod: - case SpvOpImageSampleExplicitLod: - case SpvOpImageSampleProjImplicitLod: - case SpvOpImageSampleProjExplicitLod: - case SpvOpImageSparseSampleImplicitLod: - case SpvOpImageSparseSampleExplicitLod: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: return ValidateImageLod(_, inst); - case SpvOpImageSampleDrefImplicitLod: - case SpvOpImageSampleDrefExplicitLod: - case SpvOpImageSampleProjDrefImplicitLod: - case SpvOpImageSampleProjDrefExplicitLod: - case SpvOpImageSparseSampleDrefImplicitLod: - case SpvOpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: return ValidateImageDrefLod(_, inst); - case SpvOpImageFetch: - case SpvOpImageSparseFetch: + case spv::Op::OpImageFetch: + case spv::Op::OpImageSparseFetch: return ValidateImageFetch(_, inst); - case SpvOpImageGather: - case SpvOpImageDrefGather: - case SpvOpImageSparseGather: - case SpvOpImageSparseDrefGather: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: return ValidateImageGather(_, inst); - case SpvOpImageRead: - case SpvOpImageSparseRead: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: return ValidateImageRead(_, inst); - case SpvOpImageWrite: + case spv::Op::OpImageWrite: return ValidateImageWrite(_, inst); - case SpvOpImage: + case spv::Op::OpImage: return ValidateImage(_, inst); - case SpvOpImageQueryFormat: - case SpvOpImageQueryOrder: + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: return ValidateImageQueryFormatOrOrder(_, inst); - case SpvOpImageQuerySizeLod: + case spv::Op::OpImageQuerySizeLod: return ValidateImageQuerySizeLod(_, inst); - case SpvOpImageQuerySize: + case spv::Op::OpImageQuerySize: return ValidateImageQuerySize(_, inst); - case SpvOpImageQueryLod: + case spv::Op::OpImageQueryLod: return ValidateImageQueryLod(_, inst); - case SpvOpImageQueryLevels: - case SpvOpImageQuerySamples: + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: return ValidateImageQueryLevelsOrSamples(_, inst); - case SpvOpImageSparseSampleProjImplicitLod: - case SpvOpImageSparseSampleProjExplicitLod: - case SpvOpImageSparseSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: return ValidateImageSparseLod(_, inst); - case SpvOpImageSparseTexelsResident: + case spv::Op::OpImageSparseTexelsResident: return ValidateImageSparseTexelsResident(_, inst); default: diff --git a/3rdparty/spirv-tools/source/val/validate_instruction.cpp b/3rdparty/spirv-tools/source/val/validate_instruction.cpp index 767c0cee1..1b7847cac 100644 --- a/3rdparty/spirv-tools/source/val/validate_instruction.cpp +++ b/3rdparty/spirv-tools/source/val/validate_instruction.cpp @@ -44,13 +44,13 @@ namespace { std::string ToString(const CapabilitySet& capabilities, const AssemblyGrammar& grammar) { std::stringstream ss; - capabilities.ForEach([&grammar, &ss](SpvCapability cap) { + capabilities.ForEach([&grammar, &ss](spv::Capability cap) { spv_operand_desc desc; - if (SPV_SUCCESS == - grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) + if (SPV_SUCCESS == grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + uint32_t(cap), &desc)) ss << desc->name << " "; else - ss << cap << " "; + ss << uint32_t(cap) << " "; }); return ss.str(); } @@ -60,18 +60,18 @@ std::string ToString(const CapabilitySet& capabilities, // the opcode may only be used if at least one of the capabilities is specified // by the module. CapabilitySet EnablingCapabilitiesForOp(const ValidationState_t& state, - SpvOp opcode) { + spv::Op opcode) { // Exceptions for SPV_AMD_shader_ballot switch (opcode) { // Normally these would require Group capability - case SpvOpGroupIAddNonUniformAMD: - case SpvOpGroupFAddNonUniformAMD: - case SpvOpGroupFMinNonUniformAMD: - case SpvOpGroupUMinNonUniformAMD: - case SpvOpGroupSMinNonUniformAMD: - case SpvOpGroupFMaxNonUniformAMD: - case SpvOpGroupUMaxNonUniformAMD: - case SpvOpGroupSMaxNonUniformAMD: + case spv::Op::OpGroupIAddNonUniformAMD: + case spv::Op::OpGroupFAddNonUniformAMD: + case spv::Op::OpGroupFMinNonUniformAMD: + case spv::Op::OpGroupUMinNonUniformAMD: + case spv::Op::OpGroupSMinNonUniformAMD: + case spv::Op::OpGroupFMaxNonUniformAMD: + case spv::Op::OpGroupUMaxNonUniformAMD: + case spv::Op::OpGroupSMaxNonUniformAMD: if (state.HasExtension(kSPV_AMD_shader_ballot)) return CapabilitySet(); break; default: @@ -151,10 +151,10 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, // not implemented yet. This rule is independent of target environment. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365 if (operand.type == SPV_OPERAND_TYPE_BUILT_IN) { - switch (word) { - case SpvBuiltInPointSize: - case SpvBuiltInClipDistance: - case SpvBuiltInCullDistance: + switch (spv::BuiltIn(word)) { + case spv::BuiltIn::PointSize: + case spv::BuiltIn::ClipDistance: + case spv::BuiltIn::CullDistance: return SPV_SUCCESS; default: break; @@ -166,7 +166,7 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, } } else if (operand.type == SPV_OPERAND_TYPE_GROUP_OPERATION && state.features().group_ops_reduce_and_scans && - (word <= uint32_t(SpvGroupOperationExclusiveScan))) { + (word <= uint32_t(spv::GroupOperation::ExclusiveScan))) { // Allow certain group operations if requested. return SPV_SUCCESS; } @@ -178,15 +178,16 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, if (lookup_result == SPV_SUCCESS) { // Allow FPRoundingMode decoration if requested. if (operand.type == SPV_OPERAND_TYPE_DECORATION && - operand_desc->value == SpvDecorationFPRoundingMode) { + spv::Decoration(operand_desc->value) == + spv::Decoration::FPRoundingMode) { if (state.features().free_fp_rounding_mode) return SPV_SUCCESS; // Vulkan API requires more capabilities on rounding mode. if (spvIsVulkanEnv(state.context()->target_env)) { - enabling_capabilities.Add(SpvCapabilityStorageUniformBufferBlock16); - enabling_capabilities.Add(SpvCapabilityStorageUniform16); - enabling_capabilities.Add(SpvCapabilityStoragePushConstant16); - enabling_capabilities.Add(SpvCapabilityStorageInputOutput16); + enabling_capabilities.Add(spv::Capability::StorageUniformBufferBlock16); + enabling_capabilities.Add(spv::Capability::StorageUniform16); + enabling_capabilities.Add(spv::Capability::StoragePushConstant16); + enabling_capabilities.Add(spv::Capability::StorageInputOutput16); } } else { enabling_capabilities = state.grammar().filterCapsAgainstTargetEnv( @@ -197,7 +198,7 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, // registers a capability with the module *before* checking capabilities. // So in the case of an OpCapability instruction, don't bother checking // enablement by another capability. - if (inst->opcode() != SpvOpCapability) { + if (inst->opcode() != spv::Op::OpCapability) { const bool enabled_by_cap = state.HasAnyOfCapabilities(enabling_capabilities); if (!enabling_capabilities.IsEmpty() && !enabled_by_cap) { @@ -218,14 +219,14 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, // is explicitly reserved in the SPIR-V core spec. Otherwise return // SPV_SUCCESS. spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); switch (opcode) { // These instructions are enabled by a capability, but should never // be used anyway. - case SpvOpImageSparseSampleProjImplicitLod: - case SpvOpImageSparseSampleProjExplicitLod: - case SpvOpImageSparseSampleProjDrefImplicitLod: - case SpvOpImageSparseSampleProjDrefExplicitLod: { + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: { spv_opcode_desc inst_desc; _.grammar().lookupOpcode(opcode, &inst_desc); return _.diag(SPV_ERROR_INVALID_BINARY, inst) @@ -241,7 +242,7 @@ spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) { // instruction is invalid because the required capability isn't declared // in the module. spv_result_t CapabilityCheck(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); CapabilitySet opcode_caps = EnablingCapabilitiesForOp(_, opcode); if (!_.HasAnyOfCapabilities(opcode_caps)) { return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) @@ -299,7 +300,7 @@ spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) { // OpTerminateInvocation is special because it is enabled by Shader // capability, but also requires an extension and/or version check. const bool capability_check_is_sufficient = - inst->opcode() != SpvOpTerminateInvocation; + inst->opcode() != spv::Op::OpTerminateInvocation; if (capability_check_is_sufficient && (inst_desc->numCapabilities > 0u)) { // We already checked that the direct capability dependency has been @@ -357,7 +358,7 @@ spv_result_t LimitCheckIdBound(ValidationState_t& _, const Instruction* inst) { // Checks that the number of OpTypeStruct members is within the limit. spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { - if (SpvOpTypeStruct != inst->opcode()) { + if (spv::Op::OpTypeStruct != inst->opcode()) { return SPV_SUCCESS; } @@ -382,7 +383,7 @@ spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) { auto member = inst->word(word_i); auto memberTypeInstr = _.FindDef(member); - if (memberTypeInstr && SpvOpTypeStruct == memberTypeInstr->opcode()) { + if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) { max_member_depth = std::max( max_member_depth, _.struct_nesting_depth(memberTypeInstr->id())); } @@ -402,7 +403,7 @@ spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { // Checks that the number of (literal, label) pairs in OpSwitch is within // the limit. spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) { - if (SpvOpSwitch == inst->opcode()) { + if (spv::Op::OpSwitch == inst->opcode()) { // The instruction syntax is as follows: // OpSwitch literal label literal label ... // literal,label pairs come after the first 2 operands. @@ -422,8 +423,8 @@ spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) { // Ensure the number of variables of the given class does not exceed the // limit. spv_result_t LimitCheckNumVars(ValidationState_t& _, const uint32_t var_id, - const SpvStorageClass storage_class) { - if (SpvStorageClassFunction == storage_class) { + const spv::StorageClass storage_class) { + if (spv::StorageClass::Function == storage_class) { _.registerLocalVariable(var_id); const uint32_t num_local_vars_limit = _.options()->universal_limits_.max_local_variables; @@ -462,29 +463,29 @@ spv_result_t CheckIfKnownExtension(ValidationState_t& _, } // namespace spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); - if (opcode == SpvOpExtension) { + const spv::Op opcode = inst->opcode(); + if (opcode == spv::Op::OpExtension) { CheckIfKnownExtension(_, inst); - } else if (opcode == SpvOpCapability) { - _.RegisterCapability(inst->GetOperandAs(0)); - } else if (opcode == SpvOpMemoryModel) { + } else if (opcode == spv::Op::OpCapability) { + _.RegisterCapability(inst->GetOperandAs(0)); + } else if (opcode == spv::Op::OpMemoryModel) { if (_.has_memory_model_specified()) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "OpMemoryModel should only be provided once."; } - _.set_addressing_model(inst->GetOperandAs(0)); - _.set_memory_model(inst->GetOperandAs(1)); - } else if (opcode == SpvOpExecutionMode) { + _.set_addressing_model(inst->GetOperandAs(0)); + _.set_memory_model(inst->GetOperandAs(1)); + } else if (opcode == spv::Op::OpExecutionMode) { const uint32_t entry_point = inst->word(1); _.RegisterExecutionModeForEntryPoint(entry_point, - SpvExecutionMode(inst->word(2))); - } else if (opcode == SpvOpVariable) { - const auto storage_class = inst->GetOperandAs(2); + spv::ExecutionMode(inst->word(2))); + } else if (opcode == spv::Op::OpVariable) { + const auto storage_class = inst->GetOperandAs(2); if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) { return error; } - } else if (opcode == SpvOpSamplerImageAddressingModeNV) { - if (!_.HasCapability(SpvCapabilityBindlessTextureNV)) { + } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) { + if (!_.HasCapability(spv::Capability::BindlessTextureNV)) { return _.diag(SPV_ERROR_MISSING_EXTENSION, inst) << "OpSamplerImageAddressingModeNV supported only with extension " "SPV_NV_bindless_texture"; diff --git a/3rdparty/spirv-tools/source/val/validate_interfaces.cpp b/3rdparty/spirv-tools/source/val/validate_interfaces.cpp index 7f2d6488c..00a5999bd 100644 --- a/3rdparty/spirv-tools/source/val/validate_interfaces.cpp +++ b/3rdparty/spirv-tools/source/val/validate_interfaces.cpp @@ -35,12 +35,15 @@ const uint32_t kMaxLocations = 4096 * 4; bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) { if (is_spv_1_4) { // Starting in SPIR-V 1.4, all global variables are interface variables. - return inst->opcode() == SpvOpVariable && - inst->word(3u) != SpvStorageClassFunction; + return inst->opcode() == spv::Op::OpVariable && + inst->GetOperandAs(2u) != + spv::StorageClass::Function; } else { - return inst->opcode() == SpvOpVariable && - (inst->word(3u) == SpvStorageClassInput || - inst->word(3u) == SpvStorageClassOutput); + return inst->opcode() == spv::Op::OpVariable && + (inst->GetOperandAs(2u) == + spv::StorageClass::Input || + inst->GetOperandAs(2u) == + spv::StorageClass::Output); } } @@ -114,29 +117,30 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, uint32_t* num_locations) { *num_locations = 0; switch (type->opcode()) { - case SpvOpTypeInt: - case SpvOpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: // Scalars always consume a single location. *num_locations = 1; break; - case SpvOpTypeVector: + case spv::Op::OpTypeVector: // 3- and 4-component 64-bit vectors consume two locations. - if ((_.ContainsSizedIntOrFloatType(type->id(), SpvOpTypeInt, 64) || - _.ContainsSizedIntOrFloatType(type->id(), SpvOpTypeFloat, 64)) && + if ((_.ContainsSizedIntOrFloatType(type->id(), spv::Op::OpTypeInt, 64) || + _.ContainsSizedIntOrFloatType(type->id(), spv::Op::OpTypeFloat, + 64)) && (type->GetOperandAs(2) > 2)) { *num_locations = 2; } else { *num_locations = 1; } break; - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: // Matrices consume locations equal to the underlying vector type for // each column. NumConsumedLocations(_, _.FindDef(type->GetOperandAs(1)), num_locations); *num_locations *= type->GetOperandAs(2); break; - case SpvOpTypeArray: { + case spv::Op::OpTypeArray: { // Arrays consume locations equal to the underlying type times the number // of elements in the vector. NumConsumedLocations(_, _.FindDef(type->GetOperandAs(1)), @@ -150,9 +154,9 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, if (is_int && is_const) *num_locations *= value; break; } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { // Members cannot have location decorations at this point. - if (_.HasDecoration(type->id(), SpvDecorationLocation)) { + if (_.HasDecoration(type->id(), spv::Decoration::Location)) { return _.diag(SPV_ERROR_INVALID_DATA, type) << _.VkErrorID(4918) << "Members cannot be assigned a location"; } @@ -182,8 +186,8 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { uint32_t num_components = 0; switch (type->opcode()) { - case SpvOpTypeInt: - case SpvOpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: // 64-bit types consume two components. if (type->GetOperandAs(1) == 64) { num_components = 2; @@ -191,7 +195,7 @@ uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { num_components = 1; } break; - case SpvOpTypeVector: + case spv::Op::OpTypeVector: // Vectors consume components equal to the underlying type's consumption // times the number of elements in the vector. Note that 3- and 4-element // vectors cannot have a component decoration (i.e. assumed to be zero). @@ -199,7 +203,7 @@ uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { NumConsumedComponents(_, _.FindDef(type->GetOperandAs(1))); num_components *= type->GetOperandAs(2); break; - case SpvOpTypeArray: + case spv::Op::OpTypeArray: // Skip the array. return NumConsumedComponents(_, _.FindDef(type->GetOperandAs(1))); @@ -218,10 +222,10 @@ spv_result_t GetLocationsForVariable( ValidationState_t& _, const Instruction* entry_point, const Instruction* variable, std::unordered_set* locations, std::unordered_set* output_index1_locations) { - const bool is_fragment = entry_point->GetOperandAs(0) == - SpvExecutionModelFragment; + const bool is_fragment = entry_point->GetOperandAs(0) == + spv::ExecutionModel::Fragment; const bool is_output = - variable->GetOperandAs(2) == SpvStorageClassOutput; + variable->GetOperandAs(2) == spv::StorageClass::Output; auto ptr_type_id = variable->GetOperandAs(0); auto ptr_type = _.FindDef(ptr_type_id); auto type_id = ptr_type->GetOperandAs(2); @@ -240,21 +244,21 @@ spv_result_t GetLocationsForVariable( bool has_per_task_nv = false; bool has_per_vertex_khr = false; for (auto& dec : _.id_decorations(variable->id())) { - if (dec.dec_type() == SpvDecorationLocation) { + if (dec.dec_type() == spv::Decoration::Location) { if (has_location && dec.params()[0] != location) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Variable has conflicting location decorations"; } has_location = true; location = dec.params()[0]; - } else if (dec.dec_type() == SpvDecorationComponent) { + } else if (dec.dec_type() == spv::Decoration::Component) { if (has_component && dec.params()[0] != component) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Variable has conflicting component decorations"; } has_component = true; component = dec.params()[0]; - } else if (dec.dec_type() == SpvDecorationIndex) { + } else if (dec.dec_type() == spv::Decoration::Index) { if (!is_output || !is_fragment) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Index can only be applied to Fragment output variables"; @@ -265,22 +269,22 @@ spv_result_t GetLocationsForVariable( } has_index = true; index = dec.params()[0]; - } else if (dec.dec_type() == SpvDecorationBuiltIn) { + } else if (dec.dec_type() == spv::Decoration::BuiltIn) { // Don't check built-ins. return SPV_SUCCESS; - } else if (dec.dec_type() == SpvDecorationPatch) { + } else if (dec.dec_type() == spv::Decoration::Patch) { has_patch = true; - } else if (dec.dec_type() == SpvDecorationPerTaskNV) { + } else if (dec.dec_type() == spv::Decoration::PerTaskNV) { has_per_task_nv = true; - } else if (dec.dec_type() == SpvDecorationPerVertexKHR) { + } else if (dec.dec_type() == spv::Decoration::PerVertexKHR) { if (!is_fragment) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << _.VkErrorID(6777) << "PerVertexKHR can only be applied to Fragment Execution " "Models"; } - if (type->opcode() != SpvOpTypeArray && - type->opcode() != SpvOpTypeRuntimeArray) { + if (type->opcode() != spv::Op::OpTypeArray && + type->opcode() != spv::Op::OpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << _.VkErrorID(6778) << "PerVertexKHR must be declared as arrays"; @@ -293,28 +297,28 @@ spv_result_t GetLocationsForVariable( // tessellation control, evaluation and geometry per-vertex inputs have a // layer of arraying that is not included in interface matching. bool is_arrayed = false; - switch (entry_point->GetOperandAs(0)) { - case SpvExecutionModelTessellationControl: + switch (entry_point->GetOperandAs(0)) { + case spv::ExecutionModel::TessellationControl: if (!has_patch) { is_arrayed = true; } break; - case SpvExecutionModelTessellationEvaluation: + case spv::ExecutionModel::TessellationEvaluation: if (!is_output && !has_patch) { is_arrayed = true; } break; - case SpvExecutionModelGeometry: + case spv::ExecutionModel::Geometry: if (!is_output) { is_arrayed = true; } break; - case SpvExecutionModelFragment: + case spv::ExecutionModel::Fragment: if (!is_output && has_per_vertex_khr) { is_arrayed = true; } break; - case SpvExecutionModelMeshNV: + case spv::ExecutionModel::MeshNV: if (is_output && !has_per_task_nv) { is_arrayed = true; } @@ -324,21 +328,21 @@ spv_result_t GetLocationsForVariable( } // Unpack arrayness. - if (is_arrayed && (type->opcode() == SpvOpTypeArray || - type->opcode() == SpvOpTypeRuntimeArray)) { + if (is_arrayed && (type->opcode() == spv::Op::OpTypeArray || + type->opcode() == spv::Op::OpTypeRuntimeArray)) { type_id = type->GetOperandAs(1); type = _.FindDef(type_id); } - if (type->opcode() == SpvOpTypeStruct) { + if (type->opcode() == spv::Op::OpTypeStruct) { // Don't check built-ins. - if (_.HasDecoration(type_id, SpvDecorationBuiltIn)) return SPV_SUCCESS; + if (_.HasDecoration(type_id, spv::Decoration::BuiltIn)) return SPV_SUCCESS; } // Only block-decorated structs don't need a location on the variable. - const bool is_block = _.HasDecoration(type_id, SpvDecorationBlock); + const bool is_block = _.HasDecoration(type_id, spv::Decoration::Block); if (!has_location && !is_block) { - const auto vuid = (type->opcode() == SpvOpTypeStruct) ? 4917 : 4916; + const auto vuid = (type->opcode() == spv::Op::OpTypeStruct) ? 4917 : 4916; return _.diag(SPV_ERROR_INVALID_DATA, variable) << _.VkErrorID(vuid) << "Variable must be decorated with a location"; } @@ -351,7 +355,7 @@ spv_result_t GetLocationsForVariable( uint32_t array_size = 1; // If the variable is still arrayed, mark the locations/components per // index. - if (type->opcode() == SpvOpTypeArray) { + if (type->opcode() == spv::Op::OpTypeArray) { // Determine the array size if possible and get the element type. std::tie(is_int, is_const, array_size) = _.EvalInt32IfConst(type->GetOperandAs(2)); @@ -399,7 +403,7 @@ spv_result_t GetLocationsForVariable( std::unordered_map member_locations; std::unordered_map member_components; for (auto& dec : _.id_decorations(type_id)) { - if (dec.dec_type() == SpvDecorationLocation) { + if (dec.dec_type() == spv::Decoration::Location) { auto where = member_locations.find(dec.struct_member_index()); if (where == member_locations.end()) { member_locations[dec.struct_member_index()] = dec.params()[0]; @@ -408,7 +412,7 @@ spv_result_t GetLocationsForVariable( << "Member index " << dec.struct_member_index() << " has conflicting location assignments"; } - } else if (dec.dec_type() == SpvDecorationComponent) { + } else if (dec.dec_type() == spv::Decoration::Component) { auto where = member_components.find(dec.struct_member_index()); if (where == member_components.end()) { member_components[dec.struct_member_index()] = dec.params()[0]; @@ -447,7 +451,7 @@ spv_result_t GetLocationsForVariable( continue; } - if (member->opcode() == SpvOpTypeArray && num_components >= 1 && + if (member->opcode() == spv::Op::OpTypeArray && num_components >= 1 && num_components < 4) { // When an array has an element that takes less than a location in // size, calculate the used locations in a strided manner. @@ -492,12 +496,12 @@ spv_result_t ValidateLocations(ValidationState_t& _, // TODO(dneto): SPV_NV_ray_tracing also uses locations on interface variables, // in other shader stages. Similarly, the *provisional* version of // SPV_KHR_ray_tracing did as well, but not the final version. - switch (entry_point->GetOperandAs(0)) { - case SpvExecutionModelVertex: - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: - case SpvExecutionModelGeometry: - case SpvExecutionModelFragment: + switch (entry_point->GetOperandAs(0)) { + case spv::ExecutionModel::Vertex: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::Fragment: break; default: return SPV_SUCCESS; @@ -511,9 +515,9 @@ spv_result_t ValidateLocations(ValidationState_t& _, for (uint32_t i = 3; i < entry_point->operands().size(); ++i) { auto interface_id = entry_point->GetOperandAs(i); auto interface_var = _.FindDef(interface_id); - auto storage_class = interface_var->GetOperandAs(2); - if (storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { + auto storage_class = interface_var->GetOperandAs(2); + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { continue; } if (!seen.insert(interface_id).second) { @@ -522,7 +526,7 @@ spv_result_t ValidateLocations(ValidationState_t& _, continue; } - auto locations = (storage_class == SpvStorageClassInput) + auto locations = (storage_class == spv::StorageClass::Input) ? &input_locations : &output_locations_index0; if (auto error = GetLocationsForVariable( @@ -547,12 +551,12 @@ spv_result_t ValidateInterfaces(ValidationState_t& _) { if (spvIsVulkanEnv(_.context()->target_env)) { for (auto& inst : _.ordered_instructions()) { - if (inst.opcode() == SpvOpEntryPoint) { + if (inst.opcode() == spv::Op::OpEntryPoint) { if (auto error = ValidateLocations(_, &inst)) { return error; } } - if (inst.opcode() == SpvOpTypeVoid) break; + if (inst.opcode() == spv::Op::OpTypeVoid) break; } } diff --git a/3rdparty/spirv-tools/source/val/validate_layout.cpp b/3rdparty/spirv-tools/source/val/validate_layout.cpp index 6f9513523..238dd9b2f 100644 --- a/3rdparty/spirv-tools/source/val/validate_layout.cpp +++ b/3rdparty/spirv-tools/source/val/validate_layout.cpp @@ -35,9 +35,9 @@ namespace { // is part of the current layout section. If it is not then the next sections is // checked. spv_result_t ModuleScopedInstructions(ValidationState_t& _, - const Instruction* inst, SpvOp opcode) { + const Instruction* inst, spv::Op opcode) { switch (opcode) { - case SpvOpExtInst: + case spv::Op::OpExtInst: if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { const uint32_t ext_inst_index = inst->word(4); bool local_debug_info = false; @@ -131,7 +131,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _, switch (_.current_layout_section()) { case kLayoutMemoryModel: - if (opcode != SpvOpMemoryModel) { + if (opcode != spv::Op::OpMemoryModel) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << spvOpcodeString(opcode) << " cannot appear before the memory model instruction"; @@ -154,7 +154,8 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _, // inside of another function. This stage ends when the first label is // encountered inside of a function. spv_result_t FunctionScopedInstructions(ValidationState_t& _, - const Instruction* inst, SpvOp opcode) { + const Instruction* inst, + spv::Op opcode) { // Make sure we advance into the function definitions when we hit // non-function declaration instructions. if (_.current_layout_section() == kLayoutFunctionDeclarations && @@ -171,12 +172,12 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, if (_.IsOpcodeInCurrentLayoutSection(opcode)) { switch (opcode) { - case SpvOpFunction: { + case spv::Op::OpFunction: { if (_.in_function_body()) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Cannot declare a function in a function body"; } - auto control_mask = inst->GetOperandAs(2); + auto control_mask = inst->GetOperandAs(2); if (auto error = _.RegisterFunction(inst->id(), inst->type_id(), control_mask, inst->GetOperandAs(3))) @@ -188,7 +189,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, } } break; - case SpvOpFunctionParameter: + case spv::Op::OpFunctionParameter: if (_.in_function_body() == false) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Function parameter instructions must be in a " @@ -204,7 +205,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, return error; break; - case SpvOpFunctionEnd: + case spv::Op::OpFunctionEnd: if (_.in_function_body() == false) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Function end instructions must be in a function body"; @@ -227,10 +228,10 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, if (auto error = _.RegisterFunctionEnd()) return error; break; - case SpvOpLine: - case SpvOpNoLine: + case spv::Op::OpLine: + case spv::Op::OpNoLine: break; - case SpvOpLabel: + case spv::Op::OpLabel: // If the label is encountered then the current function is a // definition so set the function to a declaration and update the // module section @@ -244,7 +245,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, } break; - case SpvOpExtInst: + case spv::Op::OpExtInst: if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { const uint32_t ext_inst_index = inst->word(4); bool local_debug_info = false; @@ -356,7 +357,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, // NOTE: This function does not handle CFG related validation // Performs logical layout validation. See Section 2.4 spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); switch (_.current_layout_section()) { case kLayoutCapabilities: diff --git a/3rdparty/spirv-tools/source/val/validate_logicals.cpp b/3rdparty/spirv-tools/source/val/validate_logicals.cpp index ec1e207be..dd66ce948 100644 --- a/3rdparty/spirv-tools/source/val/validate_logicals.cpp +++ b/3rdparty/spirv-tools/source/val/validate_logicals.cpp @@ -26,12 +26,12 @@ namespace val { // Validates correctness of logical instructions. spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpAny: - case SpvOpAll: { + case spv::Op::OpAny: + case spv::Op::OpAll: { if (!_.IsBoolScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar type as Result Type: " @@ -46,11 +46,11 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpIsNan: - case SpvOpIsInf: - case SpvOpIsFinite: - case SpvOpIsNormal: - case SpvOpSignBitSet: { + case spv::Op::OpIsNan: + case spv::Op::OpIsInf: + case spv::Op::OpIsFinite: + case spv::Op::OpIsNormal: + case spv::Op::OpSignBitSet: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -72,21 +72,21 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpFOrdEqual: - case SpvOpFUnordEqual: - case SpvOpFOrdNotEqual: - case SpvOpFUnordNotEqual: - case SpvOpFOrdLessThan: - case SpvOpFUnordLessThan: - case SpvOpFOrdGreaterThan: - case SpvOpFUnordGreaterThan: - case SpvOpFOrdLessThanEqual: - case SpvOpFUnordLessThanEqual: - case SpvOpFOrdGreaterThanEqual: - case SpvOpFUnordGreaterThanEqual: - case SpvOpLessOrGreater: - case SpvOpOrdered: - case SpvOpUnordered: { + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: + case spv::Op::OpLessOrGreater: + case spv::Op::OpOrdered: + case spv::Op::OpUnordered: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -113,10 +113,10 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpLogicalEqual: - case SpvOpLogicalNotEqual: - case SpvOpLogicalOr: - case SpvOpLogicalAnd: { + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -131,7 +131,7 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpLogicalNot: { + case spv::Op::OpLogicalNot: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -145,7 +145,7 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpSelect: { + case spv::Op::OpSelect: { uint32_t dimension = 1; { const Instruction* type_inst = _.FindDef(result_type); @@ -159,10 +159,10 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { << " type as Result Type: " << spvOpcodeString(opcode); }; - const SpvOp type_opcode = type_inst->opcode(); + const spv::Op type_opcode = type_inst->opcode(); switch (type_opcode) { - case SpvOpTypePointer: { - if (_.addressing_model() == SpvAddressingModelLogical && + case spv::Op::OpTypePointer: { + if (_.addressing_model() == spv::AddressingModel::Logical && !_.features().variable_pointers) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Using pointers with OpSelect requires capability " @@ -170,31 +170,31 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpTypeSampledImage: - case SpvOpTypeImage: - case SpvOpTypeSampler: { - if (!_.HasCapability(SpvCapabilityBindlessTextureNV)) + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: { + if (!_.HasCapability(spv::Capability::BindlessTextureNV)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Using image/sampler with OpSelect requires capability " << "BindlessTextureNV"; break; } - case SpvOpTypeVector: { + case spv::Op::OpTypeVector: { dimension = type_inst->word(3); break; } - case SpvOpTypeBool: - case SpvOpTypeInt: - case SpvOpTypeFloat: { + case spv::Op::OpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: { break; } // Not RuntimeArray because of other rules. - case SpvOpTypeArray: - case SpvOpTypeMatrix: - case SpvOpTypeStruct: { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeStruct: { if (!composites) return fail(); break; } @@ -235,16 +235,16 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { } } - case SpvOpIEqual: - case SpvOpINotEqual: - case SpvOpUGreaterThan: - case SpvOpUGreaterThanEqual: - case SpvOpULessThan: - case SpvOpULessThanEqual: - case SpvOpSGreaterThan: - case SpvOpSGreaterThanEqual: - case SpvOpSLessThan: - case SpvOpSLessThanEqual: { + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSGreaterThan: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpSLessThan: + case spv::Op::OpSLessThanEqual: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " diff --git a/3rdparty/spirv-tools/source/val/validate_memory.cpp b/3rdparty/spirv-tools/source/val/validate_memory.cpp index 09fd2b643..5f7358c68 100644 --- a/3rdparty/spirv-tools/source/val/validate_memory.cpp +++ b/3rdparty/spirv-tools/source/val/validate_memory.cpp @@ -39,13 +39,13 @@ bool HasConflictingMemberOffsets(const std::set&, const std::set&); bool IsAllowedTypeOrArrayOfSame(ValidationState_t& _, const Instruction* type, - std::initializer_list allowed) { + std::initializer_list allowed) { if (std::find(allowed.begin(), allowed.end(), type->opcode()) != allowed.end()) { return true; } - if (type->opcode() == SpvOpTypeArray || - type->opcode() == SpvOpTypeRuntimeArray) { + if (type->opcode() == spv::Op::OpTypeArray || + type->opcode() == spv::Op::OpTypeRuntimeArray) { auto elem_type = _.FindDef(type->word(2)); return std::find(allowed.begin(), allowed.end(), elem_type->opcode()) != allowed.end(); @@ -57,10 +57,10 @@ bool IsAllowedTypeOrArrayOfSame(ValidationState_t& _, const Instruction* type, // validator can tell, have the exact same data layout. bool AreLayoutCompatibleStructs(ValidationState_t& _, const Instruction* type1, const Instruction* type2) { - if (type1->opcode() != SpvOpTypeStruct) { + if (type1->opcode() != spv::Op::OpTypeStruct) { return false; } - if (type2->opcode() != SpvOpTypeStruct) { + if (type2->opcode() != spv::Op::OpTypeStruct) { return false; } @@ -74,9 +74,9 @@ bool AreLayoutCompatibleStructs(ValidationState_t& _, const Instruction* type1, // be OpTypeStruct instructions. bool HaveLayoutCompatibleMembers(ValidationState_t& _, const Instruction* type1, const Instruction* type2) { - assert(type1->opcode() == SpvOpTypeStruct && + assert(type1->opcode() == spv::Op::OpTypeStruct && "type1 must be an OpTypeStruct instruction."); - assert(type2->opcode() == SpvOpTypeStruct && + assert(type2->opcode() == spv::Op::OpTypeStruct && "type2 must be an OpTypeStruct instruction."); const auto& type1_operands = type1->operands(); const auto& type2_operands = type2->operands(); @@ -101,9 +101,9 @@ bool HaveLayoutCompatibleMembers(ValidationState_t& _, const Instruction* type1, // OpTypeStruct instructions. bool HaveSameLayoutDecorations(ValidationState_t& _, const Instruction* type1, const Instruction* type2) { - assert(type1->opcode() == SpvOpTypeStruct && + assert(type1->opcode() == spv::Op::OpTypeStruct && "type1 must be an OpTypeStruct instruction."); - assert(type2->opcode() == SpvOpTypeStruct && + assert(type2->opcode() == spv::Op::OpTypeStruct && "type2 must be an OpTypeStruct instruction."); const std::set& type1_decorations = _.id_decorations(type1->id()); const std::set& type2_decorations = _.id_decorations(type2->id()); @@ -130,11 +130,11 @@ bool HasConflictingMemberOffsets( // type1_decoration. Therefore, it cannot lead to a conflict. for (const Decoration& decoration : type1_decorations) { switch (decoration.dec_type()) { - case SpvDecorationOffset: { + case spv::Decoration::Offset: { // Since these affect the layout of the struct, they must be present // in both structs. auto compare = [&decoration](const Decoration& rhs) { - if (rhs.dec_type() != SpvDecorationOffset) return false; + if (rhs.dec_type() != spv::Decoration::Offset) return false; return decoration.struct_member_index() == rhs.struct_member_index(); }; @@ -163,7 +163,7 @@ bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage, bool skip_builtin) { if (skip_builtin) { for (const Decoration& decoration : _.id_decorations(storage->id())) { - if (decoration.dec_type() == SpvDecorationBuiltIn) return false; + if (decoration.dec_type() == spv::Decoration::BuiltIn) return false; } } @@ -172,16 +172,16 @@ bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage, Instruction* elem_type; switch (storage->opcode()) { - case SpvOpTypeBool: + case spv::Op::OpTypeBool: return true; - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: elem_type_id = storage->GetOperandAs(elem_type_index); elem_type = _.FindDef(elem_type_id); return ContainsInvalidBool(_, elem_type, skip_builtin); - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: for (size_t member_type_index = 1; member_type_index < storage->operands().size(); ++member_type_index) { @@ -203,14 +203,14 @@ bool ContainsCooperativeMatrix(ValidationState_t& _, Instruction* elem_type; switch (storage->opcode()) { - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixNV: return true; - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: elem_type_id = storage->GetOperandAs(elem_type_index); elem_type = _.FindDef(elem_type_id); return ContainsCooperativeMatrix(_, elem_type); - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: for (size_t member_type_index = 1; member_type_index < storage->operands().size(); ++member_type_index) { @@ -226,33 +226,33 @@ bool ContainsCooperativeMatrix(ValidationState_t& _, return false; } -std::pair GetStorageClass( +std::pair GetStorageClass( ValidationState_t& _, const Instruction* inst) { - SpvStorageClass dst_sc = SpvStorageClassMax; - SpvStorageClass src_sc = SpvStorageClassMax; + spv::StorageClass dst_sc = spv::StorageClass::Max; + spv::StorageClass src_sc = spv::StorageClass::Max; switch (inst->opcode()) { - case SpvOpCooperativeMatrixLoadNV: - case SpvOpLoad: { + case spv::Op::OpCooperativeMatrixLoadNV: + case spv::Op::OpLoad: { auto load_pointer = _.FindDef(inst->GetOperandAs(2)); auto load_pointer_type = _.FindDef(load_pointer->type_id()); - dst_sc = load_pointer_type->GetOperandAs(1); + dst_sc = load_pointer_type->GetOperandAs(1); break; } - case SpvOpCooperativeMatrixStoreNV: - case SpvOpStore: { + case spv::Op::OpCooperativeMatrixStoreNV: + case spv::Op::OpStore: { auto store_pointer = _.FindDef(inst->GetOperandAs(0)); auto store_pointer_type = _.FindDef(store_pointer->type_id()); - dst_sc = store_pointer_type->GetOperandAs(1); + dst_sc = store_pointer_type->GetOperandAs(1); break; } - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: { + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: { auto dst = _.FindDef(inst->GetOperandAs(0)); auto dst_type = _.FindDef(dst->type_id()); - dst_sc = dst_type->GetOperandAs(1); + dst_sc = dst_type->GetOperandAs(1); auto src = _.FindDef(inst->GetOperandAs(1)); auto src_type = _.FindDef(src->type_id()); - src_sc = src_type->GetOperandAs(1); + src_sc = src_type->GetOperandAs(1); break; } default: @@ -266,9 +266,9 @@ std::pair GetStorageClass( // argument and its implied operands. int MemoryAccessNumWords(uint32_t mask) { int result = 1; // Count the mask - if (mask & SpvMemoryAccessAlignedMask) ++result; - if (mask & SpvMemoryAccessMakePointerAvailableKHRMask) ++result; - if (mask & SpvMemoryAccessMakePointerVisibleKHRMask) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result; return result; } @@ -279,8 +279,8 @@ int MemoryAccessNumWords(uint32_t mask) { // OpCooperativeMatrixStoreNV. uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask, uint32_t mask_index) { - assert(mask & SpvMemoryAccessMakePointerAvailableKHRMask); - uint32_t this_bit = uint32_t(SpvMemoryAccessMakePointerAvailableKHRMask); + assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)); + uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR); uint32_t index = mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1))); return inst->GetOperandAs(index); @@ -291,8 +291,8 @@ uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask, // OpCooperativeMatrixStoreNV. uint32_t GetMakeVisibleScope(const Instruction* inst, uint32_t mask, uint32_t mask_index) { - assert(mask & SpvMemoryAccessMakePointerVisibleKHRMask); - uint32_t this_bit = uint32_t(SpvMemoryAccessMakePointerVisibleKHRMask); + assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)); + uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR); uint32_t index = mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1))); return inst->GetOperandAs(index); @@ -303,19 +303,19 @@ bool DoesStructContainRTA(const ValidationState_t& _, const Instruction* inst) { ++member_index) { const auto member_id = inst->GetOperandAs(member_index); const auto member_type = _.FindDef(member_id); - if (member_type->opcode() == SpvOpTypeRuntimeArray) return true; + if (member_type->opcode() == spv::Op::OpTypeRuntimeArray) return true; } return false; } spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, uint32_t index) { - SpvStorageClass dst_sc, src_sc; + spv::StorageClass dst_sc, src_sc; std::tie(dst_sc, src_sc) = GetStorageClass(_, inst); if (inst->operands().size() <= index) { // Cases where lack of some operand is invalid - if (src_sc == SpvStorageClassPhysicalStorageBuffer || - dst_sc == SpvStorageClassPhysicalStorageBuffer) { + if (src_sc == spv::StorageClass::PhysicalStorageBuffer || + dst_sc == spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4708) << "Memory accesses with PhysicalStorageBuffer must use Aligned."; @@ -324,14 +324,14 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, } const uint32_t mask = inst->GetOperandAs(index); - if (mask & SpvMemoryAccessMakePointerAvailableKHRMask) { - if (inst->opcode() == SpvOpLoad || - inst->opcode() == SpvOpCooperativeMatrixLoadNV) { + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { + if (inst->opcode() == spv::Op::OpLoad || + inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerAvailableKHR cannot be used with OpLoad."; } - if (!(mask & SpvMemoryAccessNonPrivatePointerKHRMask)) { + if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR must be specified if " "MakePointerAvailableKHR is specified."; @@ -343,14 +343,14 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, return error; } - if (mask & SpvMemoryAccessMakePointerVisibleKHRMask) { - if (inst->opcode() == SpvOpStore || - inst->opcode() == SpvOpCooperativeMatrixStoreNV) { + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { + if (inst->opcode() == spv::Op::OpStore || + inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerVisibleKHR cannot be used with OpStore."; } - if (!(mask & SpvMemoryAccessNonPrivatePointerKHRMask)) { + if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR must be specified if " << "MakePointerVisibleKHR is specified."; @@ -361,24 +361,27 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error; } - if (mask & SpvMemoryAccessNonPrivatePointerKHRMask) { - if (dst_sc != SpvStorageClassUniform && - dst_sc != SpvStorageClassWorkgroup && - dst_sc != SpvStorageClassCrossWorkgroup && - dst_sc != SpvStorageClassGeneric && dst_sc != SpvStorageClassImage && - dst_sc != SpvStorageClassStorageBuffer && - dst_sc != SpvStorageClassPhysicalStorageBuffer) { + if (mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR)) { + if (dst_sc != spv::StorageClass::Uniform && + dst_sc != spv::StorageClass::Workgroup && + dst_sc != spv::StorageClass::CrossWorkgroup && + dst_sc != spv::StorageClass::Generic && + dst_sc != spv::StorageClass::Image && + dst_sc != spv::StorageClass::StorageBuffer && + dst_sc != spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR requires a pointer in Uniform, " << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer " << "storage classes."; } - if (src_sc != SpvStorageClassMax && src_sc != SpvStorageClassUniform && - src_sc != SpvStorageClassWorkgroup && - src_sc != SpvStorageClassCrossWorkgroup && - src_sc != SpvStorageClassGeneric && src_sc != SpvStorageClassImage && - src_sc != SpvStorageClassStorageBuffer && - src_sc != SpvStorageClassPhysicalStorageBuffer) { + if (src_sc != spv::StorageClass::Max && + src_sc != spv::StorageClass::Uniform && + src_sc != spv::StorageClass::Workgroup && + src_sc != spv::StorageClass::CrossWorkgroup && + src_sc != spv::StorageClass::Generic && + src_sc != spv::StorageClass::Image && + src_sc != spv::StorageClass::StorageBuffer && + src_sc != spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR requires a pointer in Uniform, " << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer " @@ -386,9 +389,9 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, } } - if (!(mask & SpvMemoryAccessAlignedMask)) { - if (src_sc == SpvStorageClassPhysicalStorageBuffer || - dst_sc == SpvStorageClassPhysicalStorageBuffer) { + if (!(mask & uint32_t(spv::MemoryAccessMask::Aligned))) { + if (src_sc == spv::StorageClass::PhysicalStorageBuffer || + dst_sc == spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4708) << "Memory accesses with PhysicalStorageBuffer must use Aligned."; @@ -400,7 +403,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { auto result_type = _.FindDef(inst->type_id()); - if (!result_type || result_type->opcode() != SpvOpTypePointer) { + if (!result_type || result_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable Result Type " << _.getIdName(inst->type_id()) << " is not a pointer type."; @@ -416,9 +419,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { const auto initializer_id = inst->GetOperandAs(initializer_index); const auto initializer = _.FindDef(initializer_id); const auto is_module_scope_var = - initializer && (initializer->opcode() == SpvOpVariable) && - (initializer->GetOperandAs(storage_class_index) != - SpvStorageClassFunction); + initializer && (initializer->opcode() == spv::Op::OpVariable) && + (initializer->GetOperandAs(storage_class_index) != + spv::StorageClass::Function); const auto is_constant = initializer && spvOpcodeIsConstant(initializer->opcode()); if (!initializer || !(is_constant || is_module_scope_var)) { @@ -433,23 +436,25 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - auto storage_class = inst->GetOperandAs(storage_class_index); - if (storage_class != SpvStorageClassWorkgroup && - storage_class != SpvStorageClassCrossWorkgroup && - storage_class != SpvStorageClassPrivate && - storage_class != SpvStorageClassFunction && - storage_class != SpvStorageClassRayPayloadKHR && - storage_class != SpvStorageClassIncomingRayPayloadKHR && - storage_class != SpvStorageClassHitAttributeKHR && - storage_class != SpvStorageClassCallableDataKHR && - storage_class != SpvStorageClassIncomingCallableDataKHR && - storage_class != SpvStorageClassTaskPayloadWorkgroupEXT) { - bool storage_input_or_output = storage_class == SpvStorageClassInput || - storage_class == SpvStorageClassOutput; + auto storage_class = + inst->GetOperandAs(storage_class_index); + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::CrossWorkgroup && + storage_class != spv::StorageClass::Private && + storage_class != spv::StorageClass::Function && + storage_class != spv::StorageClass::RayPayloadKHR && + storage_class != spv::StorageClass::IncomingRayPayloadKHR && + storage_class != spv::StorageClass::HitAttributeKHR && + storage_class != spv::StorageClass::CallableDataKHR && + storage_class != spv::StorageClass::IncomingCallableDataKHR && + storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT && + storage_class != spv::StorageClass::HitObjectAttributeNV) { + bool storage_input_or_output = storage_class == spv::StorageClass::Input || + storage_class == spv::StorageClass::Output; bool builtin = false; if (storage_input_or_output) { for (const Decoration& decoration : _.id_decorations(inst->id())) { - if (decoration.dec_type() == SpvDecorationBuiltIn) { + if (decoration.dec_type() == spv::Decoration::BuiltIn) { builtin = true; break; } @@ -482,18 +487,18 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { << "Invalid storage class for target environment"; } - if (storage_class == SpvStorageClassGeneric) { + if (storage_class == spv::StorageClass::Generic) { return _.diag(SPV_ERROR_INVALID_BINARY, inst) << "OpVariable storage class cannot be Generic"; } - if (inst->function() && storage_class != SpvStorageClassFunction) { + if (inst->function() && storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Variables must have a function[7] storage class inside" " of a function"; } - if (!inst->function() && storage_class == SpvStorageClassFunction) { + if (!inst->function() && storage_class == spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Variables can not have a function[7] storage class " "outside of a function"; @@ -503,7 +508,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // storage class. const auto result_storage_class_index = 1; const auto result_storage_class = - result_type->GetOperandAs(result_storage_class_index); + result_type->GetOperandAs(result_storage_class_index); if (storage_class != result_storage_class) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "From SPIR-V spec, section 3.32.8 on OpVariable:\n" @@ -513,16 +518,16 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // Variable pointer related restrictions. const auto pointee = _.FindDef(result_type->word(3)); - if (_.addressing_model() == SpvAddressingModelLogical && + if (_.addressing_model() == spv::AddressingModel::Logical && !_.options()->relax_logical_pointer) { // VariablePointersStorageBuffer is implied by VariablePointers. - if (pointee->opcode() == SpvOpTypePointer) { - if (!_.HasCapability(SpvCapabilityVariablePointersStorageBuffer)) { + if (pointee->opcode() == spv::Op::OpTypePointer) { + if (!_.HasCapability(spv::Capability::VariablePointersStorageBuffer)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "In Logical addressing, variables may not allocate a pointer " << "type"; - } else if (storage_class != SpvStorageClassFunction && - storage_class != SpvStorageClassPrivate) { + } else if (storage_class != spv::StorageClass::Function && + storage_class != spv::StorageClass::Private) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "In Logical addressing with variable pointers, variables " << "that allocate pointers must be in Function or Private " @@ -534,8 +539,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { if (spvIsVulkanEnv(_.context()->target_env)) { // Vulkan Push Constant Interface section: Check type of PushConstant // variables. - if (storage_class == SpvStorageClassPushConstant) { - if (pointee->opcode() != SpvOpTypeStruct) { + if (storage_class == spv::StorageClass::PushConstant) { + if (pointee->opcode() != spv::Op::OpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6808) << "PushConstant OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -546,11 +551,12 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // Vulkan Descriptor Set Interface: Check type of UniformConstant and // Uniform variables. - if (storage_class == SpvStorageClassUniformConstant) { + if (storage_class == spv::StorageClass::UniformConstant) { if (!IsAllowedTypeOrArrayOfSame( _, pointee, - {SpvOpTypeImage, SpvOpTypeSampler, SpvOpTypeSampledImage, - SpvOpTypeAccelerationStructureKHR})) { + {spv::Op::OpTypeImage, spv::Op::OpTypeSampler, + spv::Op::OpTypeSampledImage, + spv::Op::OpTypeAccelerationStructureKHR})) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4655) << "UniformConstant OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -562,8 +568,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - if (storage_class == SpvStorageClassUniform) { - if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) { + if (storage_class == spv::StorageClass::Uniform) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6807) << "Uniform OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -575,8 +581,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - if (storage_class == SpvStorageClassStorageBuffer) { - if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) { + if (storage_class == spv::StorageClass::StorageBuffer) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6807) << "StorageBuffer OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -589,9 +595,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } // Check for invalid use of Invariant - if (storage_class != SpvStorageClassInput && - storage_class != SpvStorageClassOutput) { - if (_.HasDecoration(inst->id(), SpvDecorationInvariant)) { + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + if (_.HasDecoration(inst->id(), spv::Decoration::Invariant)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4677) << "Variable decorated with Invariant must only be identified " @@ -599,8 +605,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "environment."; } // Need to check if only the members in a struct are decorated - if (value_type && value_type->opcode() == SpvOpTypeStruct) { - if (_.HasDecoration(value_id, SpvDecorationInvariant)) { + if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) { + if (_.HasDecoration(value_id, spv::Decoration::Invariant)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4677) << "Variable struct member decorated with Invariant must only " @@ -612,10 +618,10 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // Initializers in Vulkan are only allowed in some storage clases if (inst->operands().size() > 3) { - if (storage_class == SpvStorageClassWorkgroup) { + if (storage_class == spv::StorageClass::Workgroup) { auto init_id = inst->GetOperandAs(3); auto init = _.FindDef(init_id); - if (init->opcode() != SpvOpConstantNull) { + if (init->opcode() != spv::Op::OpConstantNull) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4734) << "OpVariable, " << _.getIdName(inst->id()) @@ -623,9 +629,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "Workgroup " "storage class"; } - } else if (storage_class != SpvStorageClassOutput && - storage_class != SpvStorageClassPrivate && - storage_class != SpvStorageClassFunction) { + } else if (storage_class != spv::StorageClass::Output && + storage_class != spv::StorageClass::Private && + storage_class != spv::StorageClass::Function) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4651) << "OpVariable, " << _.getIdName(inst->id()) @@ -641,35 +647,40 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } if (inst->operands().size() > 3) { - if (storage_class == SpvStorageClassTaskPayloadWorkgroupEXT) { + if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable, " << _.getIdName(inst->id()) << ", initializer are not allowed for TaskPayloadWorkgroupEXT"; } - if (storage_class == SpvStorageClassInput) { + if (storage_class == spv::StorageClass::Input) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable, " << _.getIdName(inst->id()) << ", initializer are not allowed for Input"; } + if (storage_class == spv::StorageClass::HitObjectAttributeNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable, " << _.getIdName(inst->id()) + << ", initializer are not allowed for HitObjectAttributeNV"; + } } - if (storage_class == SpvStorageClassPhysicalStorageBuffer) { + if (storage_class == spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "PhysicalStorageBuffer must not be used with OpVariable."; } auto pointee_base = pointee; - while (pointee_base->opcode() == SpvOpTypeArray) { + while (pointee_base->opcode() == spv::Op::OpTypeArray) { pointee_base = _.FindDef(pointee_base->GetOperandAs(1u)); } - if (pointee_base->opcode() == SpvOpTypePointer) { - if (pointee_base->GetOperandAs(1u) == - SpvStorageClassPhysicalStorageBuffer) { + if (pointee_base->opcode() == spv::Op::OpTypePointer) { + if (pointee_base->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { // check for AliasedPointer/RestrictPointer bool foundAliased = - _.HasDecoration(inst->id(), SpvDecorationAliasedPointer); + _.HasDecoration(inst->id(), spv::Decoration::AliasedPointer); bool foundRestrict = - _.HasDecoration(inst->id(), SpvDecorationRestrictPointer); + _.HasDecoration(inst->id(), spv::Decoration::RestrictPointer); if (!foundAliased && !foundRestrict) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable " << inst->id() @@ -690,8 +701,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // OpTypeRuntimeArray should only ever be in a container like OpTypeStruct, // so should never appear as a bare variable. // Unless the module has the RuntimeDescriptorArrayEXT capability. - if (value_type && value_type->opcode() == SpvOpTypeRuntimeArray) { - if (!_.HasCapability(SpvCapabilityRuntimeDescriptorArrayEXT)) { + if (value_type && value_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (!_.HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "OpVariable, " << _.getIdName(inst->id()) @@ -702,9 +713,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } else { // A bare variable OpTypeRuntimeArray is allowed in this context, but // still need to check the storage class. - if (storage_class != SpvStorageClassStorageBuffer && - storage_class != SpvStorageClassUniform && - storage_class != SpvStorageClassUniformConstant) { + if (storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::Uniform && + storage_class != spv::StorageClass::UniformConstant) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "For Vulkan with RuntimeDescriptorArrayEXT, a variable " @@ -718,11 +729,11 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // must either have the storage class StorageBuffer and be decorated // with Block, or it must be in the Uniform storage class and be decorated // as BufferBlock. - if (value_type && value_type->opcode() == SpvOpTypeStruct) { + if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) { if (DoesStructContainRTA(_, value_type)) { - if (storage_class == SpvStorageClassStorageBuffer || - storage_class == SpvStorageClassPhysicalStorageBuffer) { - if (!_.HasDecoration(value_id, SpvDecorationBlock)) { + if (storage_class == spv::StorageClass::StorageBuffer || + storage_class == spv::StorageClass::PhysicalStorageBuffer) { + if (!_.HasDecoration(value_id, spv::Decoration::Block)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "For Vulkan, an OpTypeStruct variable containing an " @@ -730,8 +741,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { << "has storage class StorageBuffer or " "PhysicalStorageBuffer."; } - } else if (storage_class == SpvStorageClassUniform) { - if (!_.HasDecoration(value_id, SpvDecorationBufferBlock)) { + } else if (storage_class == spv::StorageClass::Uniform) { + if (!_.HasDecoration(value_id, spv::Decoration::BufferBlock)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "For Vulkan, an OpTypeStruct variable containing an " @@ -750,8 +761,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } // Cooperative matrix types can only be allocated in Function or Private - if ((storage_class != SpvStorageClassFunction && - storage_class != SpvStorageClassPrivate) && + if ((storage_class != spv::StorageClass::Function && + storage_class != spv::StorageClass::Private) && ContainsCooperativeMatrix(_, pointee)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cooperative matrix types (or types containing them) can only be " @@ -760,57 +771,59 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "parameters"; } - if (_.HasCapability(SpvCapabilityShader)) { + if (_.HasCapability(spv::Capability::Shader)) { // Don't allow variables containing 16-bit elements without the appropriate // capabilities. - if ((!_.HasCapability(SpvCapabilityInt16) && - _.ContainsSizedIntOrFloatType(value_id, SpvOpTypeInt, 16)) || - (!_.HasCapability(SpvCapabilityFloat16) && - _.ContainsSizedIntOrFloatType(value_id, SpvOpTypeFloat, 16))) { + if ((!_.HasCapability(spv::Capability::Int16) && + _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 16)) || + (!_.HasCapability(spv::Capability::Float16) && + _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeFloat, 16))) { auto underlying_type = value_type; - while (underlying_type->opcode() == SpvOpTypePointer) { - storage_class = underlying_type->GetOperandAs(1u); + while (underlying_type->opcode() == spv::Op::OpTypePointer) { + storage_class = underlying_type->GetOperandAs(1u); underlying_type = _.FindDef(underlying_type->GetOperandAs(2u)); } bool storage_class_ok = true; std::string sc_name = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class); + SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); switch (storage_class) { - case SpvStorageClassStorageBuffer: - case SpvStorageClassPhysicalStorageBuffer: - if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess)) { + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::PhysicalStorageBuffer: + if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess)) { storage_class_ok = false; } break; - case SpvStorageClassUniform: + case spv::StorageClass::Uniform: if (!_.HasCapability( - SpvCapabilityUniformAndStorageBuffer16BitAccess)) { - if (underlying_type->opcode() == SpvOpTypeArray || - underlying_type->opcode() == SpvOpTypeRuntimeArray) { + spv::Capability::UniformAndStorageBuffer16BitAccess)) { + if (underlying_type->opcode() == spv::Op::OpTypeArray || + underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { underlying_type = _.FindDef(underlying_type->GetOperandAs(1u)); } - if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess) || + if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess) || !_.HasDecoration(underlying_type->id(), - SpvDecorationBufferBlock)) { + spv::Decoration::BufferBlock)) { storage_class_ok = false; } } break; - case SpvStorageClassPushConstant: - if (!_.HasCapability(SpvCapabilityStoragePushConstant16)) { + case spv::StorageClass::PushConstant: + if (!_.HasCapability(spv::Capability::StoragePushConstant16)) { storage_class_ok = false; } break; - case SpvStorageClassInput: - case SpvStorageClassOutput: - if (!_.HasCapability(SpvCapabilityStorageInputOutput16)) { + case spv::StorageClass::Input: + case spv::StorageClass::Output: + if (!_.HasCapability(spv::Capability::StorageInputOutput16)) { storage_class_ok = false; } break; - case SpvStorageClassWorkgroup: - if (!_.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR)) { + case spv::StorageClass::Workgroup: + if (!_.HasCapability( + spv::Capability:: + WorkgroupMemoryExplicitLayout16BitAccessKHR)) { storage_class_ok = false; } break; @@ -827,46 +840,48 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } // Don't allow variables containing 8-bit elements without the appropriate // capabilities. - if (!_.HasCapability(SpvCapabilityInt8) && - _.ContainsSizedIntOrFloatType(value_id, SpvOpTypeInt, 8)) { + if (!_.HasCapability(spv::Capability::Int8) && + _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 8)) { auto underlying_type = value_type; - while (underlying_type->opcode() == SpvOpTypePointer) { - storage_class = underlying_type->GetOperandAs(1u); + while (underlying_type->opcode() == spv::Op::OpTypePointer) { + storage_class = underlying_type->GetOperandAs(1u); underlying_type = _.FindDef(underlying_type->GetOperandAs(2u)); } bool storage_class_ok = true; std::string sc_name = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class); + SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); switch (storage_class) { - case SpvStorageClassStorageBuffer: - case SpvStorageClassPhysicalStorageBuffer: - if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess)) { + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::PhysicalStorageBuffer: + if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess)) { storage_class_ok = false; } break; - case SpvStorageClassUniform: + case spv::StorageClass::Uniform: if (!_.HasCapability( - SpvCapabilityUniformAndStorageBuffer8BitAccess)) { - if (underlying_type->opcode() == SpvOpTypeArray || - underlying_type->opcode() == SpvOpTypeRuntimeArray) { + spv::Capability::UniformAndStorageBuffer8BitAccess)) { + if (underlying_type->opcode() == spv::Op::OpTypeArray || + underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { underlying_type = _.FindDef(underlying_type->GetOperandAs(1u)); } - if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess) || + if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess) || !_.HasDecoration(underlying_type->id(), - SpvDecorationBufferBlock)) { + spv::Decoration::BufferBlock)) { storage_class_ok = false; } } break; - case SpvStorageClassPushConstant: - if (!_.HasCapability(SpvCapabilityStoragePushConstant8)) { + case spv::StorageClass::PushConstant: + if (!_.HasCapability(spv::Capability::StoragePushConstant8)) { storage_class_ok = false; } break; - case SpvStorageClassWorkgroup: - if (!_.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR)) { + case spv::StorageClass::Workgroup: + if (!_.HasCapability( + spv::Capability:: + WorkgroupMemoryExplicitLayout8BitAccessKHR)) { storage_class_ok = false; } break; @@ -898,7 +913,7 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { const auto pointer_id = inst->GetOperandAs(pointer_index); const auto pointer = _.FindDef(pointer_id); if (!pointer || - ((_.addressing_model() == SpvAddressingModelLogical) && + ((_.addressing_model() == spv::AddressingModel::Logical) && ((!_.features().variable_pointers && !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || (_.features().variable_pointers && @@ -909,14 +924,14 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { } const auto pointer_type = _.FindDef(pointer->type_id()); - if (!pointer_type || pointer_type->opcode() != SpvOpTypePointer) { + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpLoad type for pointer " << _.getIdName(pointer_id) << " is not a pointer type."; } uint32_t pointee_data_type; - uint32_t storage_class; + spv::StorageClass storage_class; if (!_.GetPointerTypeInfo(pointer_type->id(), &pointee_data_type, &storage_class) || result_type->id() != pointee_data_type) { @@ -934,13 +949,13 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { if (auto error = CheckMemoryAccess(_, inst, 3)) return error; - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && - result_type->opcode() != SpvOpTypePointer) { - if (result_type->opcode() != SpvOpTypeInt && - result_type->opcode() != SpvOpTypeFloat && - result_type->opcode() != SpvOpTypeVector && - result_type->opcode() != SpvOpTypeMatrix) { + result_type->opcode() != spv::Op::OpTypePointer) { + if (result_type->opcode() != spv::Op::OpTypeInt && + result_type->opcode() != spv::Op::OpTypeFloat && + result_type->opcode() != spv::Op::OpTypeVector && + result_type->opcode() != spv::Op::OpTypeMatrix) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "8- or 16-bit loads must be a scalar, vector or matrix type"; } @@ -954,7 +969,7 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { const auto pointer_id = inst->GetOperandAs(pointer_index); const auto pointer = _.FindDef(pointer_id); if (!pointer || - (_.addressing_model() == SpvAddressingModelLogical && + (_.addressing_model() == spv::AddressingModel::Logical && ((!_.features().variable_pointers && !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || (_.features().variable_pointers && @@ -964,14 +979,14 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { << " is not a logical pointer."; } const auto pointer_type = _.FindDef(pointer->type_id()); - if (!pointer_type || pointer_type->opcode() != SpvOpTypePointer) { + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore type for pointer " << _.getIdName(pointer_id) << " is not a pointer type."; } const auto type_id = pointer_type->GetOperandAs(2); const auto type = _.FindDef(type_id); - if (!type || SpvOpTypeVoid == type->opcode()) { + if (!type || spv::Op::OpTypeVoid == type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << "s type is void."; @@ -980,29 +995,29 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { // validate storage class { uint32_t data_type; - uint32_t storage_class; + spv::StorageClass storage_class; if (!_.GetPointerTypeInfo(pointer_type->id(), &data_type, &storage_class)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << " is not pointer type"; } - if (storage_class == SpvStorageClassUniformConstant || - storage_class == SpvStorageClassInput || - storage_class == SpvStorageClassPushConstant) { + if (storage_class == spv::StorageClass::UniformConstant || + storage_class == spv::StorageClass::Input || + storage_class == spv::StorageClass::PushConstant) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << " storage class is read-only"; - } else if (storage_class == SpvStorageClassShaderRecordBufferKHR) { + } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "ShaderRecordBufferKHR Storage Class variables are read only"; - } else if (storage_class == SpvStorageClassHitAttributeKHR) { + } else if (storage_class == spv::StorageClass::HitAttributeKHR) { std::string errorVUID = _.VkErrorID(4703); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model == SpvExecutionModelAnyHitKHR || - model == SpvExecutionModelClosestHitKHR) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model == spv::ExecutionModel::AnyHitKHR || + model == spv::ExecutionModel::ClosestHitKHR) { if (message) { *message = errorVUID + @@ -1016,18 +1031,18 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env) && - storage_class == SpvStorageClassUniform) { + storage_class == spv::StorageClass::Uniform) { auto base_ptr = _.TracePointer(pointer); - if (base_ptr->opcode() == SpvOpVariable) { + if (base_ptr->opcode() == spv::Op::OpVariable) { // If it's not a variable a different check should catch the problem. auto base_type = _.FindDef(base_ptr->GetOperandAs(0)); // Get the pointed-to type. base_type = _.FindDef(base_type->GetOperandAs(2u)); - if (base_type->opcode() == SpvOpTypeArray || - base_type->opcode() == SpvOpTypeRuntimeArray) { + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { base_type = _.FindDef(base_type->GetOperandAs(1u)); } - if (_.HasDecoration(base_type->id(), SpvDecorationBlock)) { + if (_.HasDecoration(base_type->id(), spv::Decoration::Block)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6925) << "In the Vulkan environment, cannot store to Uniform Blocks"; @@ -1045,15 +1060,16 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { << " is not an object."; } const auto object_type = _.FindDef(object->type_id()); - if (!object_type || SpvOpTypeVoid == object_type->opcode()) { + if (!object_type || spv::Op::OpTypeVoid == object_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Object " << _.getIdName(object_id) << "s type is void."; } if (type->id() != object_type->id()) { - if (!_.options()->relax_struct_store || type->opcode() != SpvOpTypeStruct || - object_type->opcode() != SpvOpTypeStruct) { + if (!_.options()->relax_struct_store || + type->opcode() != spv::Op::OpTypeStruct || + object_type->opcode() != spv::Op::OpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << "s type does not match Object " @@ -1071,13 +1087,13 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { if (auto error = CheckMemoryAccess(_, inst, 2)) return error; - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && - object_type->opcode() != SpvOpTypePointer) { - if (object_type->opcode() != SpvOpTypeInt && - object_type->opcode() != SpvOpTypeFloat && - object_type->opcode() != SpvOpTypeVector && - object_type->opcode() != SpvOpTypeMatrix) { + object_type->opcode() != spv::Op::OpTypePointer) { + if (object_type->opcode() != spv::Op::OpTypeInt && + object_type->opcode() != spv::Op::OpTypeFloat && + object_type->opcode() != spv::Op::OpTypeVector && + object_type->opcode() != spv::Op::OpTypeMatrix) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "8- or 16-bit stores must be a scalar, vector or matrix type"; } @@ -1088,9 +1104,10 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateCopyMemoryMemoryAccess(ValidationState_t& _, const Instruction* inst) { - assert(inst->opcode() == SpvOpCopyMemory || - inst->opcode() == SpvOpCopyMemorySized); - const uint32_t first_access_index = inst->opcode() == SpvOpCopyMemory ? 2 : 3; + assert(inst->opcode() == spv::Op::OpCopyMemory || + inst->opcode() == spv::Op::OpCopyMemorySized); + const uint32_t first_access_index = + inst->opcode() == spv::Op::OpCopyMemory ? 2 : 3; if (inst->operands().size() > first_access_index) { if (auto error = CheckMemoryAccess(_, inst, first_access_index)) return error; @@ -1108,21 +1125,23 @@ spv_result_t ValidateCopyMemoryMemoryAccess(ValidationState_t& _, // make-visible. // - the second is the source (read) access and it can't have // make-available. - if (first_access & SpvMemoryAccessMakePointerVisibleKHRMask) { + if (first_access & + uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Target memory access must not include " "MakePointerVisibleKHR"; } const auto second_access = inst->GetOperandAs(second_access_index); - if (second_access & SpvMemoryAccessMakePointerAvailableKHRMask) { + if (second_access & + uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Source memory access must not include " "MakePointerAvailableKHR"; } } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(static_cast(inst->opcode())) + << spvOpcodeString(static_cast(inst->opcode())) << " with two memory access operands requires SPIR-V 1.4 or " "later"; } @@ -1152,7 +1171,7 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { const auto target_pointer_type = _.FindDef(target->type_id()); if (!target_pointer_type || - target_pointer_type->opcode() != SpvOpTypePointer) { + target_pointer_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Target operand " << _.getIdName(target_id) << " is not a pointer."; @@ -1160,16 +1179,16 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { const auto source_pointer_type = _.FindDef(source->type_id()); if (!source_pointer_type || - source_pointer_type->opcode() != SpvOpTypePointer) { + source_pointer_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Source operand " << _.getIdName(source_id) << " is not a pointer."; } - if (inst->opcode() == SpvOpCopyMemory) { + if (inst->opcode() == spv::Op::OpCopyMemory) { const auto target_type = _.FindDef(target_pointer_type->GetOperandAs(2)); - if (!target_type || target_type->opcode() == SpvOpTypeVoid) { + if (!target_type || target_type->opcode() == spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Target operand " << _.getIdName(target_id) << " cannot be a void pointer."; @@ -1177,7 +1196,7 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { const auto source_type = _.FindDef(source_pointer_type->GetOperandAs(2)); - if (!source_type || source_type->opcode() == SpvOpTypeVoid) { + if (!source_type || source_type->opcode() == spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Source operand " << _.getIdName(source_id) << " cannot be a void pointer."; @@ -1207,11 +1226,11 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { bool is_zero = true; switch (size->opcode()) { - case SpvOpConstantNull: + case spv::Op::OpConstantNull: return _.diag(SPV_ERROR_INVALID_ID, inst) << "Size operand " << _.getIdName(size_id) << " cannot be a constant zero."; - case SpvOpConstant: + case spv::Op::OpConstant: if (size_type->word(3) == 1 && size->word(size->words().size() - 1) & 0x80000000) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -1236,10 +1255,10 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { // Get past the pointers to avoid checking a pointer copy. auto sub_type = _.FindDef(target_pointer_type->GetOperandAs(2)); - while (sub_type->opcode() == SpvOpTypePointer) { + while (sub_type->opcode() == spv::Op::OpTypePointer) { sub_type = _.FindDef(sub_type->GetOperandAs(2)); } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(sub_type->id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cannot copy memory of objects containing 8- or 16-bit types"; @@ -1251,15 +1270,16 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateAccessChain(ValidationState_t& _, const Instruction* inst) { std::string instr_name = - "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); // The result type must be OpTypePointer. auto result_type = _.FindDef(inst->type_id()); - if (SpvOpTypePointer != result_type->opcode()) { + if (spv::Op::OpTypePointer != result_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The Result Type of " << instr_name << " " << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op" - << spvOpcodeString(static_cast(result_type->opcode())) << "."; + << spvOpcodeString(static_cast(result_type->opcode())) + << "."; } // Result type is a pointer. Find out what it's pointing to. @@ -1272,7 +1292,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, const auto base_id = inst->GetOperandAs(base_index); const auto base = _.FindDef(base_id); const auto base_type = _.FindDef(base->type_id()); - if (!base_type || SpvOpTypePointer != base_type->opcode()) { + if (!base_type || spv::Op::OpTypePointer != base_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The Base " << _.getIdName(base_id) << " in " << instr_name << " instruction must be a pointer."; @@ -1296,8 +1316,8 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, // The number of indexes passed to OpAccessChain may not exceed 255 // The instruction includes 4 words + N words (for N indexes) size_t num_indexes = inst->words().size() - 4; - if (inst->opcode() == SpvOpPtrAccessChain || - inst->opcode() == SpvOpInBoundsPtrAccessChain) { + if (inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { // In pointer access chains, the element operand is required, but not // counted as an index. --num_indexes; @@ -1317,8 +1337,8 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, // on. Once any non-composite type is reached, there must be no remaining // (unused) indexes. auto starting_index = 4; - if (inst->opcode() == SpvOpPtrAccessChain || - inst->opcode() == SpvOpInBoundsPtrAccessChain) { + if (inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { ++starting_index; } for (size_t i = starting_index; i < inst->words().size(); ++i) { @@ -1327,26 +1347,26 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, auto cur_word_instr = _.FindDef(cur_word); // The index must be a scalar integer type (See OpAccessChain in the Spec.) auto index_type = _.FindDef(cur_word_instr->type_id()); - if (!index_type || SpvOpTypeInt != index_type->opcode()) { + if (!index_type || spv::Op::OpTypeInt != index_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Indexes passed to " << instr_name << " must be of type integer."; } switch (type_pointee->opcode()) { - case SpvOpTypeMatrix: - case SpvOpTypeVector: - case SpvOpTypeCooperativeMatrixNV: - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: { - // In OpTypeMatrix, OpTypeVector, SpvOpTypeCooperativeMatrixNV, + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: { + // In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV, // OpTypeArray, and OpTypeRuntimeArray, word 2 is the Element Type. type_pointee = _.FindDef(type_pointee->word(2)); break; } - case SpvOpTypeStruct: { + case spv::Op::OpTypeStruct: { // In case of structures, there is an additional constraint on the // index: the index must be an OpConstant. - if (SpvOpConstant != cur_word_instr->opcode()) { + if (spv::Op::OpConstant != cur_word_instr->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) << "The passed to " << instr_name << " to index into a " @@ -1378,7 +1398,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, } default: { // Give an error. reached non-composite type while indexes still remain. - return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) + return _.diag(SPV_ERROR_INVALID_ID, inst) << instr_name << " reached non-composite type while indexes " "still remain to be traversed."; @@ -1390,11 +1410,12 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, if (type_pointee->id() != result_type_pointee->id()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << instr_name << " result type (Op" - << spvOpcodeString(static_cast(result_type_pointee->opcode())) + << spvOpcodeString( + static_cast(result_type_pointee->opcode())) << ") does not match the type that results from indexing into the " "base " " (Op" - << spvOpcodeString(static_cast(type_pointee->opcode())) + << spvOpcodeString(static_cast(type_pointee->opcode())) << ")."; } @@ -1403,7 +1424,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, spv_result_t ValidatePtrAccessChain(ValidationState_t& _, const Instruction* inst) { - if (_.addressing_model() == SpvAddressingModelLogical) { + if (_.addressing_model() == spv::AddressingModel::Logical) { if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Generating variable pointers requires capability " @@ -1417,30 +1438,31 @@ spv_result_t ValidatePtrAccessChain(ValidationState_t& _, const auto base_id = inst->GetOperandAs(2); const auto base = _.FindDef(base_id); const auto base_type = _.FindDef(base->type_id()); - const auto base_type_storage_class = base_type->word(2); + const auto base_type_storage_class = + base_type->GetOperandAs(1); - if (_.HasCapability(SpvCapabilityShader) && - (base_type_storage_class == SpvStorageClassUniform || - base_type_storage_class == SpvStorageClassStorageBuffer || - base_type_storage_class == SpvStorageClassPhysicalStorageBuffer || - base_type_storage_class == SpvStorageClassPushConstant || - (_.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR) && - base_type_storage_class == SpvStorageClassWorkgroup)) && - !_.HasDecoration(base_type->id(), SpvDecorationArrayStride)) { + if (_.HasCapability(spv::Capability::Shader) && + (base_type_storage_class == spv::StorageClass::Uniform || + base_type_storage_class == spv::StorageClass::StorageBuffer || + base_type_storage_class == spv::StorageClass::PhysicalStorageBuffer || + base_type_storage_class == spv::StorageClass::PushConstant || + (_.HasCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) && + base_type_storage_class == spv::StorageClass::Workgroup)) && + !_.HasDecoration(base_type->id(), spv::Decoration::ArrayStride)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "OpPtrAccessChain must have a Base whose type is decorated " "with ArrayStride"; } if (spvIsVulkanEnv(_.context()->target_env)) { - if (base_type_storage_class == SpvStorageClassWorkgroup) { - if (!_.HasCapability(SpvCapabilityVariablePointers)) { + if (base_type_storage_class == spv::StorageClass::Workgroup) { + if (!_.HasCapability(spv::Capability::VariablePointers)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(7651) << "OpPtrAccessChain Base operand pointing to Workgroup " "storage class must use VariablePointers capability"; } - } else if (base_type_storage_class == SpvStorageClassStorageBuffer) { + } else if (base_type_storage_class == spv::StorageClass::StorageBuffer) { if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(7652) @@ -1449,7 +1471,7 @@ spv_result_t ValidatePtrAccessChain(ValidationState_t& _, "VariablePointersStorageBuffer capability"; } } else if (base_type_storage_class != - SpvStorageClassPhysicalStorageBuffer) { + spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(7650) << "OpPtrAccessChain Base operand must point to Workgroup, " @@ -1463,11 +1485,11 @@ spv_result_t ValidatePtrAccessChain(ValidationState_t& _, spv_result_t ValidateArrayLength(ValidationState_t& state, const Instruction* inst) { std::string instr_name = - "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); // Result type must be a 32-bit unsigned int. auto result_type = state.FindDef(inst->type_id()); - if (result_type->opcode() != SpvOpTypeInt || + if (result_type->opcode() != spv::Op::OpTypeInt || result_type->GetOperandAs(1) != 32 || result_type->GetOperandAs(2) != 0) { return state.diag(SPV_ERROR_INVALID_ID, inst) @@ -1480,7 +1502,7 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, // last element is a runtime array. auto pointer = state.FindDef(inst->GetOperandAs(2)); auto pointer_type = state.FindDef(pointer->type_id()); - if (pointer_type->opcode() != SpvOpTypePointer) { + if (pointer_type->opcode() != spv::Op::OpTypePointer) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The Structure's type in " << instr_name << " " << state.getIdName(inst->id()) @@ -1488,7 +1510,7 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, } auto structure_type = state.FindDef(pointer_type->GetOperandAs(2)); - if (structure_type->opcode() != SpvOpTypeStruct) { + if (structure_type->opcode() != spv::Op::OpTypeStruct) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The Structure's type in " << instr_name << " " << state.getIdName(inst->id()) @@ -1498,7 +1520,7 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, auto num_of_members = structure_type->operands().size() - 1; auto last_member = state.FindDef(structure_type->GetOperandAs(num_of_members)); - if (last_member->opcode() != SpvOpTypeRuntimeArray) { + if (last_member->opcode() != spv::Op::OpTypeRuntimeArray) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The Structure's last member in " << instr_name << " " << state.getIdName(inst->id()) << " must be an OpTypeRuntimeArray."; @@ -1518,11 +1540,11 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state, const Instruction* inst) { std::string instr_name = - "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); // Result type must be a 32-bit unsigned int. auto result_type = state.FindDef(inst->type_id()); - if (result_type->opcode() != SpvOpTypeInt || + if (result_type->opcode() != spv::Op::OpTypeInt || result_type->GetOperandAs(1) != 32 || result_type->GetOperandAs(2) != 0) { return state.diag(SPV_ERROR_INVALID_ID, inst) @@ -1533,7 +1555,7 @@ spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state, auto type_id = inst->GetOperandAs(2); auto type = state.FindDef(type_id); - if (type->opcode() != SpvOpTypeCooperativeMatrixNV) { + if (type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The type in " << instr_name << " " << state.getIdName(type_id) << " must be OpTypeCooperativeMatrixNV."; @@ -1545,35 +1567,35 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, const Instruction* inst) { uint32_t type_id; const char* opname; - if (inst->opcode() == SpvOpCooperativeMatrixLoadNV) { + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { type_id = inst->type_id(); - opname = "SpvOpCooperativeMatrixLoadNV"; + opname = "spv::Op::OpCooperativeMatrixLoadNV"; } else { // get Object operand's type type_id = _.FindDef(inst->GetOperandAs(1))->type_id(); - opname = "SpvOpCooperativeMatrixStoreNV"; + opname = "spv::Op::OpCooperativeMatrixStoreNV"; } auto matrix_type = _.FindDef(type_id); - if (matrix_type->opcode() != SpvOpTypeCooperativeMatrixNV) { - if (inst->opcode() == SpvOpCooperativeMatrixLoadNV) { + if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "SpvOpCooperativeMatrixLoadNV Result Type " + << "spv::Op::OpCooperativeMatrixLoadNV Result Type " << _.getIdName(type_id) << " is not a cooperative matrix type."; } else { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "SpvOpCooperativeMatrixStoreNV Object type " + << "spv::Op::OpCooperativeMatrixStoreNV Object type " << _.getIdName(type_id) << " is not a cooperative matrix type."; } } const auto pointer_index = - (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 2u : 0u; + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 2u : 0u; const auto pointer_id = inst->GetOperandAs(pointer_index); const auto pointer = _.FindDef(pointer_id); if (!pointer || - ((_.addressing_model() == SpvAddressingModelLogical) && + ((_.addressing_model() == spv::AddressingModel::Logical) && ((!_.features().variable_pointers && !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || (_.features().variable_pointers && @@ -1585,7 +1607,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, const auto pointer_type_id = pointer->type_id(); const auto pointer_type = _.FindDef(pointer_type_id); - if (!pointer_type || pointer_type->opcode() != SpvOpTypePointer) { + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opname << " type for pointer " << _.getIdName(pointer_id) << " is not a pointer type."; @@ -1593,11 +1615,11 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, const auto storage_class_index = 1u; const auto storage_class = - pointer_type->GetOperandAs(storage_class_index); + pointer_type->GetOperandAs(storage_class_index); - if (storage_class != SpvStorageClassWorkgroup && - storage_class != SpvStorageClassStorageBuffer && - storage_class != SpvStorageClassPhysicalStorageBuffer) { + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opname << " storage class for pointer type " << _.getIdName(pointer_type_id) @@ -1614,7 +1636,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, } const auto stride_index = - (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 3u : 2u; + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 3u : 2u; const auto stride_id = inst->GetOperandAs(stride_index); const auto stride = _.FindDef(stride_id); if (!stride || !_.IsIntScalarType(stride->type_id())) { @@ -1624,7 +1646,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, } const auto colmajor_index = - (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 4u : 3u; + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 4u : 3u; const auto colmajor_id = inst->GetOperandAs(colmajor_index); const auto colmajor = _.FindDef(colmajor_id); if (!colmajor || !_.IsBoolScalarType(colmajor->type_id()) || @@ -1636,7 +1658,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, } const auto memory_access_index = - (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 5u : 4u; + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 5u : 4u; if (inst->operands().size() > memory_access_index) { if (auto error = CheckMemoryAccess(_, inst, memory_access_index)) return error; @@ -1647,7 +1669,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, spv_result_t ValidatePtrComparison(ValidationState_t& _, const Instruction* inst) { - if (_.addressing_model() == SpvAddressingModelLogical && + if (_.addressing_model() == spv::AddressingModel::Logical && !_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Instruction cannot for logical addressing model be used without " @@ -1655,13 +1677,13 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _, } const auto result_type = _.FindDef(inst->type_id()); - if (inst->opcode() == SpvOpPtrDiff) { - if (!result_type || result_type->opcode() != SpvOpTypeInt) { + if (inst->opcode() == spv::Op::OpPtrDiff) { + if (!result_type || result_type->opcode() != spv::Op::OpTypeInt) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result Type must be an integer scalar"; } } else { - if (!result_type || result_type->opcode() != SpvOpTypeBool) { + if (!result_type || result_type->opcode() != spv::Op::OpTypeBool) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result Type must be OpTypeBool"; } @@ -1674,25 +1696,26 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _, << "The types of Operand 1 and Operand 2 must match"; } const auto op1_type = _.FindDef(op1->type_id()); - if (!op1_type || op1_type->opcode() != SpvOpTypePointer) { + if (!op1_type || op1_type->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Operand type must be a pointer"; } - SpvStorageClass sc = op1_type->GetOperandAs(1u); - if (_.addressing_model() == SpvAddressingModelLogical) { - if (sc != SpvStorageClassWorkgroup && sc != SpvStorageClassStorageBuffer) { + spv::StorageClass sc = op1_type->GetOperandAs(1u); + if (_.addressing_model() == spv::AddressingModel::Logical) { + if (sc != spv::StorageClass::Workgroup && + sc != spv::StorageClass::StorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Invalid pointer storage class"; } - if (sc == SpvStorageClassWorkgroup && - !_.HasCapability(SpvCapabilityVariablePointers)) { + if (sc == spv::StorageClass::Workgroup && + !_.HasCapability(spv::Capability::VariablePointers)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Workgroup storage class pointer requires VariablePointers " "capability to be specified"; } - } else if (sc == SpvStorageClassPhysicalStorageBuffer) { + } else if (sc == spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cannot use a pointer in the PhysicalStorageBuffer storage class"; } @@ -1704,45 +1727,45 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _, spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpVariable: + case spv::Op::OpVariable: if (auto error = ValidateVariable(_, inst)) return error; break; - case SpvOpLoad: + case spv::Op::OpLoad: if (auto error = ValidateLoad(_, inst)) return error; break; - case SpvOpStore: + case spv::Op::OpStore: if (auto error = ValidateStore(_, inst)) return error; break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: if (auto error = ValidateCopyMemory(_, inst)) return error; break; - case SpvOpPtrAccessChain: + case spv::Op::OpPtrAccessChain: if (auto error = ValidatePtrAccessChain(_, inst)) return error; break; - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpInBoundsPtrAccessChain: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: if (auto error = ValidateAccessChain(_, inst)) return error; break; - case SpvOpArrayLength: + case spv::Op::OpArrayLength: if (auto error = ValidateArrayLength(_, inst)) return error; break; - case SpvOpCooperativeMatrixLoadNV: - case SpvOpCooperativeMatrixStoreNV: + case spv::Op::OpCooperativeMatrixLoadNV: + case spv::Op::OpCooperativeMatrixStoreNV: if (auto error = ValidateCooperativeMatrixLoadStoreNV(_, inst)) return error; break; - case SpvOpCooperativeMatrixLengthNV: + case spv::Op::OpCooperativeMatrixLengthNV: if (auto error = ValidateCooperativeMatrixLengthNV(_, inst)) return error; break; - case SpvOpPtrEqual: - case SpvOpPtrNotEqual: - case SpvOpPtrDiff: + case spv::Op::OpPtrEqual: + case spv::Op::OpPtrNotEqual: + case spv::Op::OpPtrDiff: if (auto error = ValidatePtrComparison(_, inst)) return error; break; - case SpvOpImageTexelPointer: - case SpvOpGenericPtrMemSemantics: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpGenericPtrMemSemantics: default: break; } diff --git a/3rdparty/spirv-tools/source/val/validate_memory_semantics.cpp b/3rdparty/spirv-tools/source/val/validate_memory_semantics.cpp index d9189313a..748b23861 100644 --- a/3rdparty/spirv-tools/source/val/validate_memory_semantics.cpp +++ b/3rdparty/spirv-tools/source/val/validate_memory_semantics.cpp @@ -27,7 +27,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, const Instruction* inst, uint32_t operand_index, uint32_t memory_scope) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const auto id = inst->GetOperandAs(operand_index); bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; @@ -40,15 +40,15 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } if (!is_const_int32) { - if (_.HasCapability(SpvCapabilityShader) && - !_.HasCapability(SpvCapabilityCooperativeMatrixNV)) { + if (_.HasCapability(spv::Capability::Shader) && + !_.HasCapability(spv::Capability::CooperativeMatrixNV)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory Semantics ids must be OpConstant when Shader " "capability is present"; } - if (_.HasCapability(SpvCapabilityShader) && - _.HasCapability(SpvCapabilityCooperativeMatrixNV) && + if (_.HasCapability(spv::Capability::Shader) && + _.HasCapability(spv::Capability::CooperativeMatrixNV) && !spvOpcodeIsConstant(_.GetIdOpcode(id))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory Semantics must be a constant instruction when " @@ -58,9 +58,10 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits( - value & (SpvMemorySemanticsAcquireMask | SpvMemorySemanticsReleaseMask | - SpvMemorySemanticsAcquireReleaseMask | - SpvMemorySemanticsSequentiallyConsistentMask)); + value & uint32_t(spv::MemorySemanticsMask::Acquire | + spv::MemorySemanticsMask::Release | + spv::MemorySemanticsMask::AcquireRelease | + spv::MemorySemanticsMask::SequentiallyConsistent)); if (num_memory_order_set_bits > 1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -71,40 +72,40 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, "SequentiallyConsistent"; } - if (_.memory_model() == SpvMemoryModelVulkanKHR && - value & SpvMemorySemanticsSequentiallyConsistentMask) { + if (_.memory_model() == spv::MemoryModel::VulkanKHR && + value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "SequentiallyConsistent memory " "semantics cannot be used with " "the VulkanKHR memory model."; } - if (value & SpvMemorySemanticsMakeAvailableKHRMask && - !_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { + if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics MakeAvailableKHR requires capability " << "VulkanMemoryModelKHR"; } - if (value & SpvMemorySemanticsMakeVisibleKHRMask && - !_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { + if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics MakeVisibleKHR requires capability " << "VulkanMemoryModelKHR"; } - if (value & SpvMemorySemanticsOutputMemoryKHRMask && - !_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { + if (value & uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics OutputMemoryKHR requires capability " << "VulkanMemoryModelKHR"; } - if (value & SpvMemorySemanticsVolatileMask) { - if (!_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { + if (value & uint32_t(spv::MemorySemanticsMask::Volatile)) { + if (!_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics Volatile requires capability " @@ -118,26 +119,27 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } } - if (value & SpvMemorySemanticsUniformMemoryMask && - !_.HasCapability(SpvCapabilityShader)) { + if (value & uint32_t(spv::MemorySemanticsMask::UniformMemory) && + !_.HasCapability(spv::Capability::Shader)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics UniformMemory requires capability Shader"; } - // Checking for SpvCapabilityAtomicStorage is intentionally not done here. See - // https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning why. + // Checking for spv::Capability::AtomicStorage is intentionally not done here. + // See https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning + // why. - if (value & (SpvMemorySemanticsMakeAvailableKHRMask | - SpvMemorySemanticsMakeVisibleKHRMask)) { + if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR | + spv::MemorySemanticsMask::MakeVisibleKHR)) { const bool includes_storage_class = - value & (SpvMemorySemanticsUniformMemoryMask | - SpvMemorySemanticsSubgroupMemoryMask | - SpvMemorySemanticsWorkgroupMemoryMask | - SpvMemorySemanticsCrossWorkgroupMemoryMask | - SpvMemorySemanticsAtomicCounterMemoryMask | - SpvMemorySemanticsImageMemoryMask | - SpvMemorySemanticsOutputMemoryKHRMask); + value & uint32_t(spv::MemorySemanticsMask::UniformMemory | + spv::MemorySemanticsMask::SubgroupMemory | + spv::MemorySemanticsMask::WorkgroupMemory | + spv::MemorySemanticsMask::CrossWorkgroupMemory | + spv::MemorySemanticsMask::AtomicCounterMemory | + spv::MemorySemanticsMask::ImageMemory | + spv::MemorySemanticsMask::OutputMemoryKHR); if (!includes_storage_class) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -146,18 +148,18 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } } - if (value & SpvMemorySemanticsMakeVisibleKHRMask && - !(value & (SpvMemorySemanticsAcquireMask | - SpvMemorySemanticsAcquireReleaseMask))) { + if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) && + !(value & uint32_t(spv::MemorySemanticsMask::Acquire | + spv::MemorySemanticsMask::AcquireRelease))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": MakeVisibleKHR Memory Semantics also requires either Acquire " "or AcquireRelease Memory Semantics"; } - if (value & SpvMemorySemanticsMakeAvailableKHRMask && - !(value & (SpvMemorySemanticsReleaseMask | - SpvMemorySemanticsAcquireReleaseMask))) { + if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) && + !(value & uint32_t(spv::MemorySemanticsMask::Release | + spv::MemorySemanticsMask::AcquireRelease))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": MakeAvailableKHR Memory Semantics also requires either " @@ -166,12 +168,12 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, if (spvIsVulkanEnv(_.context()->target_env)) { const bool includes_storage_class = - value & (SpvMemorySemanticsUniformMemoryMask | - SpvMemorySemanticsWorkgroupMemoryMask | - SpvMemorySemanticsImageMemoryMask | - SpvMemorySemanticsOutputMemoryKHRMask); + value & uint32_t(spv::MemorySemanticsMask::UniformMemory | + spv::MemorySemanticsMask::WorkgroupMemory | + spv::MemorySemanticsMask::ImageMemory | + spv::MemorySemanticsMask::OutputMemoryKHR); - if (opcode == SpvOpMemoryBarrier && !num_memory_order_set_bits) { + if (opcode == spv::Op::OpMemoryBarrier && !num_memory_order_set_bits) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4732) << spvOpcodeString(opcode) << ": Vulkan specification requires Memory Semantics to have " @@ -179,13 +181,15 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, "of the following bits set: Acquire, Release, " "AcquireRelease " "or SequentiallyConsistent"; - } else if (opcode != SpvOpMemoryBarrier && num_memory_order_set_bits) { + } else if (opcode != spv::Op::OpMemoryBarrier && + num_memory_order_set_bits) { // should leave only atomics and control barriers for Vulkan env bool memory_is_int32 = false, memory_is_const_int32 = false; uint32_t memory_value = 0; std::tie(memory_is_int32, memory_is_const_int32, memory_value) = _.EvalInt32IfConst(memory_scope); - if (memory_is_int32 && memory_value == SpvScopeInvocation) { + if (memory_is_int32 && + spv::Scope(memory_value) == spv::Scope::Invocation) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4641) << spvOpcodeString(opcode) << ": Vulkan specification requires Memory Semantics to be None " @@ -193,7 +197,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } } - if (opcode == SpvOpMemoryBarrier && !includes_storage_class) { + if (opcode == spv::Op::OpMemoryBarrier && !includes_storage_class) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4733) << spvOpcodeString(opcode) << ": expected Memory Semantics to include a Vulkan-supported " @@ -202,7 +206,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, #if 0 // TODO(atgoo@github.com): this check fails Vulkan CTS, reenable once fixed. - if (opcode == SpvOpControlBarrier && value && !includes_storage_class) { + if (opcode == spv::Op::OpControlBarrier && value && !includes_storage_class) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Memory Semantics to include a Vulkan-supported " @@ -211,18 +215,18 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, #endif } - if (opcode == SpvOpAtomicFlagClear && - (value & SpvMemorySemanticsAcquireMask || - value & SpvMemorySemanticsAcquireReleaseMask)) { + if (opcode == spv::Op::OpAtomicFlagClear && + (value & uint32_t(spv::MemorySemanticsMask::Acquire) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory Semantics Acquire and AcquireRelease cannot be used " "with " << spvOpcodeString(opcode); } - if (opcode == SpvOpAtomicCompareExchange && operand_index == 5 && - (value & SpvMemorySemanticsReleaseMask || - value & SpvMemorySemanticsAcquireReleaseMask)) { + if (opcode == spv::Op::OpAtomicCompareExchange && operand_index == 5 && + (value & uint32_t(spv::MemorySemanticsMask::Release) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics Release and AcquireRelease cannot be " @@ -231,20 +235,20 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } if (spvIsVulkanEnv(_.context()->target_env)) { - if (opcode == SpvOpAtomicLoad && - (value & SpvMemorySemanticsReleaseMask || - value & SpvMemorySemanticsAcquireReleaseMask || - value & SpvMemorySemanticsSequentiallyConsistentMask)) { + if (opcode == spv::Op::OpAtomicLoad && + (value & uint32_t(spv::MemorySemanticsMask::Release) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) || + value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4731) << "Vulkan spec disallows OpAtomicLoad with Memory Semantics " "Release, AcquireRelease and SequentiallyConsistent"; } - if (opcode == SpvOpAtomicStore && - (value & SpvMemorySemanticsAcquireMask || - value & SpvMemorySemanticsAcquireReleaseMask || - value & SpvMemorySemanticsSequentiallyConsistentMask)) { + if (opcode == spv::Op::OpAtomicStore && + (value & uint32_t(spv::MemorySemanticsMask::Acquire) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) || + value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4730) << "Vulkan spec disallows OpAtomicStore with Memory Semantics " diff --git a/3rdparty/spirv-tools/source/val/validate_mesh_shading.cpp b/3rdparty/spirv-tools/source/val/validate_mesh_shading.cpp index a7f072672..e569e251c 100644 --- a/3rdparty/spirv-tools/source/val/validate_mesh_shading.cpp +++ b/3rdparty/spirv-tools/source/val/validate_mesh_shading.cpp @@ -23,13 +23,13 @@ namespace spvtools { namespace val { spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); switch (opcode) { - case SpvOpEmitMeshTasksEXT: { + case spv::Op::OpEmitMeshTasksEXT: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelTaskEXT) { + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TaskEXT) { if (message) { *message = "OpEmitMeshTasksEXT requires TaskEXT execution model"; @@ -62,12 +62,12 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { if (inst->operands().size() == 4) { const auto payload = _.FindDef(inst->GetOperandAs(3)); - if (payload->opcode() != SpvOpVariable) { + if (payload->opcode() != spv::Op::OpVariable) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload must be the result of a OpVariable"; } - if (SpvStorageClass(payload->GetOperandAs(2)) != - SpvStorageClassTaskPayloadWorkgroupEXT) { + if (payload->GetOperandAs(2) != + spv::StorageClass::TaskPayloadWorkgroupEXT) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload OpVariable must have a storage class of " "TaskPayloadWorkgroupEXT"; @@ -76,11 +76,11 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpSetMeshOutputsEXT: { + case spv::Op::OpSetMeshOutputsEXT: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelMeshEXT) { + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::MeshEXT) { if (message) { *message = "OpSetMeshOutputsEXT requires MeshEXT execution model"; @@ -107,7 +107,7 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpWritePackedPrimitiveIndices4x8NV: { + case spv::Op::OpWritePackedPrimitiveIndices4x8NV: { // No validation rules (for the moment). break; } diff --git a/3rdparty/spirv-tools/source/val/validate_misc.cpp b/3rdparty/spirv-tools/source/val/validate_misc.cpp index 5acc21eaa..d71fd2d26 100644 --- a/3rdparty/spirv-tools/source/val/validate_misc.cpp +++ b/3rdparty/spirv-tools/source/val/validate_misc.cpp @@ -30,7 +30,7 @@ spv_result_t ValidateUndef(ValidationState_t& _, const Instruction* inst) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cannot create undefined values with void type"; } - if (_.HasCapability(SpvCapabilityShader) && + if (_.HasCapability(spv::Capability::Shader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && !_.IsPointerType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -50,7 +50,8 @@ spv_result_t ValidateShaderClock(ValidationState_t& _, bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); - if (is_const_int32 && value != SpvScopeSubgroup && value != SpvScopeDevice) { + if (is_const_int32 && spv::Scope(value) != spv::Scope::Subgroup && + spv::Scope(value) != spv::Scope::Device) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4652) << "Scope must be Subgroup or Device"; } @@ -104,18 +105,18 @@ spv_result_t ValidateExpect(ValidationState_t& _, const Instruction* inst) { spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpUndef: + case spv::Op::OpUndef: if (auto error = ValidateUndef(_, inst)) return error; break; default: break; } switch (inst->opcode()) { - case SpvOpBeginInvocationInterlockEXT: - case SpvOpEndInvocationInterlockEXT: + case spv::Op::OpBeginInvocationInterlockEXT: + case spv::Op::OpEndInvocationInterlockEXT: _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT " "require Fragment execution model"); @@ -126,14 +127,14 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { const auto* execution_modes = state.GetExecutionModes(entry_point->id()); - auto find_interlock = [](const SpvExecutionMode& mode) { + auto find_interlock = [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModePixelInterlockOrderedEXT: - case SpvExecutionModePixelInterlockUnorderedEXT: - case SpvExecutionModeSampleInterlockOrderedEXT: - case SpvExecutionModeSampleInterlockUnorderedEXT: - case SpvExecutionModeShadingRateInterlockOrderedEXT: - case SpvExecutionModeShadingRateInterlockUnorderedEXT: + case spv::ExecutionMode::PixelInterlockOrderedEXT: + case spv::ExecutionMode::PixelInterlockUnorderedEXT: + case spv::ExecutionMode::SampleInterlockOrderedEXT: + case spv::ExecutionMode::SampleInterlockUnorderedEXT: + case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: + case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: return true; default: return false; @@ -156,18 +157,18 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { return true; }); break; - case SpvOpDemoteToHelperInvocationEXT: + case spv::Op::OpDemoteToHelperInvocationEXT: _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, "OpDemoteToHelperInvocationEXT requires Fragment execution " "model"); break; - case SpvOpIsHelperInvocationEXT: { + case spv::Op::OpIsHelperInvocationEXT: { const uint32_t result_type = inst->type_id(); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, + spv::ExecutionModel::Fragment, "OpIsHelperInvocationEXT requires Fragment execution model"); if (!_.IsBoolScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -175,17 +176,17 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { << spvOpcodeString(inst->opcode()); break; } - case SpvOpReadClockKHR: + case spv::Op::OpReadClockKHR: if (auto error = ValidateShaderClock(_, inst)) { return error; } break; - case SpvOpAssumeTrueKHR: + case spv::Op::OpAssumeTrueKHR: if (auto error = ValidateAssumeTrue(_, inst)) { return error; } break; - case SpvOpExpectKHR: + case spv::Op::OpExpectKHR: if (auto error = ValidateExpect(_, inst)) { return error; } diff --git a/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp b/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp index 672192b9c..dfa46466f 100644 --- a/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp +++ b/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp @@ -27,16 +27,16 @@ namespace { spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { const auto entry_point_id = inst->GetOperandAs(1); auto entry_point = _.FindDef(entry_point_id); - if (!entry_point || SpvOpFunction != entry_point->opcode()) { + if (!entry_point || spv::Op::OpFunction != entry_point->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpEntryPoint Entry Point " << _.getIdName(entry_point_id) << " is not a function."; } // Only check the shader execution models - const SpvExecutionModel execution_model = - inst->GetOperandAs(0); - if (execution_model != SpvExecutionModelKernel) { + const spv::ExecutionModel execution_model = + inst->GetOperandAs(0); + if (execution_model != spv::ExecutionModel::Kernel) { const auto entry_point_type_id = entry_point->GetOperandAs(3); const auto entry_point_type = _.FindDef(entry_point_type_id); if (!entry_point_type || 3 != entry_point_type->words().size()) { @@ -48,7 +48,7 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } auto return_type = _.FindDef(entry_point->type_id()); - if (!return_type || SpvOpTypeVoid != return_type->opcode()) { + if (!return_type || spv::Op::OpTypeVoid != return_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4633) << "OpEntryPoint Entry Point " << _.getIdName(entry_point_id) @@ -56,31 +56,31 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } const auto* execution_modes = _.GetExecutionModes(entry_point_id); - if (_.HasCapability(SpvCapabilityShader)) { + if (_.HasCapability(spv::Capability::Shader)) { switch (execution_model) { - case SpvExecutionModelFragment: + case spv::ExecutionModel::Fragment: if (execution_modes && - execution_modes->count(SpvExecutionModeOriginUpperLeft) && - execution_modes->count(SpvExecutionModeOriginLowerLeft)) { + execution_modes->count(spv::ExecutionMode::OriginUpperLeft) && + execution_modes->count(spv::ExecutionMode::OriginLowerLeft)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Fragment execution model entry points can only specify " "one of OriginUpperLeft or OriginLowerLeft execution " "modes."; } if (!execution_modes || - (!execution_modes->count(SpvExecutionModeOriginUpperLeft) && - !execution_modes->count(SpvExecutionModeOriginLowerLeft))) { + (!execution_modes->count(spv::ExecutionMode::OriginUpperLeft) && + !execution_modes->count(spv::ExecutionMode::OriginLowerLeft))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Fragment execution model entry points require either an " "OriginUpperLeft or OriginLowerLeft execution mode."; } if (execution_modes && 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeDepthGreater: - case SpvExecutionModeDepthLess: - case SpvExecutionModeDepthUnchanged: + case spv::ExecutionMode::DepthGreater: + case spv::ExecutionMode::DepthLess: + case spv::ExecutionMode::DepthUnchanged: return true; default: return false; @@ -94,14 +94,15 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (execution_modes && 1 < std::count_if( execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModePixelInterlockOrderedEXT: - case SpvExecutionModePixelInterlockUnorderedEXT: - case SpvExecutionModeSampleInterlockOrderedEXT: - case SpvExecutionModeSampleInterlockUnorderedEXT: - case SpvExecutionModeShadingRateInterlockOrderedEXT: - case SpvExecutionModeShadingRateInterlockUnorderedEXT: + case spv::ExecutionMode::PixelInterlockOrderedEXT: + case spv::ExecutionMode::PixelInterlockUnorderedEXT: + case spv::ExecutionMode::SampleInterlockOrderedEXT: + case spv::ExecutionMode::SampleInterlockUnorderedEXT: + case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: + case spv::ExecutionMode:: + ShadingRateInterlockUnorderedEXT: return true; default: return false; @@ -114,11 +115,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (execution_modes && 1 < std::count_if( execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeStencilRefUnchangedFrontAMD: - case SpvExecutionModeStencilRefLessFrontAMD: - case SpvExecutionModeStencilRefGreaterFrontAMD: + case spv::ExecutionMode::StencilRefUnchangedFrontAMD: + case spv::ExecutionMode::StencilRefLessFrontAMD: + case spv::ExecutionMode::StencilRefGreaterFrontAMD: return true; default: return false; @@ -133,11 +134,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (execution_modes && 1 < std::count_if( execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeStencilRefUnchangedBackAMD: - case SpvExecutionModeStencilRefLessBackAMD: - case SpvExecutionModeStencilRefGreaterBackAMD: + case spv::ExecutionMode::StencilRefUnchangedBackAMD: + case spv::ExecutionMode::StencilRefLessBackAMD: + case spv::ExecutionMode::StencilRefGreaterBackAMD: return true; default: return false; @@ -150,20 +151,21 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "execution modes."; } break; - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: if (execution_modes && - 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { - switch (mode) { - case SpvExecutionModeSpacingEqual: - case SpvExecutionModeSpacingFractionalEven: - case SpvExecutionModeSpacingFractionalOdd: - return true; - default: - return false; - } - })) { + 1 < std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::SpacingEqual: + case spv::ExecutionMode::SpacingFractionalEven: + case spv::ExecutionMode::SpacingFractionalOdd: + return true; + default: + return false; + } + })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Tessellation execution model entry points can specify at " "most one of SpacingEqual, SpacingFractionalOdd or " @@ -171,11 +173,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } if (execution_modes && 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeTriangles: - case SpvExecutionModeQuads: - case SpvExecutionModeIsolines: + case spv::ExecutionMode::Triangles: + case spv::ExecutionMode::Quads: + case spv::ExecutionMode::Isolines: return true; default: return false; @@ -187,10 +189,10 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } if (execution_modes && 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeVertexOrderCw: - case SpvExecutionModeVertexOrderCcw: + case spv::ExecutionMode::VertexOrderCw: + case spv::ExecutionMode::VertexOrderCcw: return true; default: return false; @@ -202,21 +204,22 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "modes."; } break; - case SpvExecutionModelGeometry: + case spv::ExecutionModel::Geometry: if (!execution_modes || - 1 != std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { - switch (mode) { - case SpvExecutionModeInputPoints: - case SpvExecutionModeInputLines: - case SpvExecutionModeInputLinesAdjacency: - case SpvExecutionModeTriangles: - case SpvExecutionModeInputTrianglesAdjacency: - return true; - default: - return false; - } - })) { + 1 != std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::InputPoints: + case spv::ExecutionMode::InputLines: + case spv::ExecutionMode::InputLinesAdjacency: + case spv::ExecutionMode::Triangles: + case spv::ExecutionMode::InputTrianglesAdjacency: + return true; + default: + return false; + } + })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Geometry execution model entry points must specify " "exactly one of InputPoints, InputLines, " @@ -225,11 +228,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } if (!execution_modes || 1 != std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeOutputPoints: - case SpvExecutionModeOutputLineStrip: - case SpvExecutionModeOutputTriangleStrip: + case spv::ExecutionMode::OutputPoints: + case spv::ExecutionMode::OutputLineStrip: + case spv::ExecutionMode::OutputTriangleStrip: return true; default: return false; @@ -241,14 +244,14 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "OutputTriangleStrip execution modes."; } break; - case SpvExecutionModelMeshEXT: + case spv::ExecutionModel::MeshEXT: if (!execution_modes || 1 != std::count_if(execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeOutputPoints: - case SpvExecutionModeOutputLinesEXT: - case SpvExecutionModeOutputTrianglesEXT: + case spv::ExecutionMode::OutputPoints: + case spv::ExecutionMode::OutputLinesEXT: + case spv::ExecutionMode::OutputTrianglesEXT: return true; default: return false; @@ -260,10 +263,10 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "OutputTrianglesEXT Execution Modes."; } else if (2 != std::count_if( execution_modes->begin(), execution_modes->end(), - [](const SpvExecutionMode& mode) { + [](const spv::ExecutionMode& mode) { switch (mode) { - case SpvExecutionModeOutputPrimitivesEXT: - case SpvExecutionModeOutputVertices: + case spv::ExecutionMode::OutputPrimitivesEXT: + case spv::ExecutionMode::OutputVertices: return true; default: return false; @@ -281,23 +284,25 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (spvIsVulkanEnv(_.context()->target_env)) { switch (execution_model) { - case SpvExecutionModelGLCompute: + case spv::ExecutionModel::GLCompute: if (!execution_modes || - !execution_modes->count(SpvExecutionModeLocalSize)) { + !execution_modes->count(spv::ExecutionMode::LocalSize)) { bool ok = false; for (auto& i : _.ordered_instructions()) { - if (i.opcode() == SpvOpDecorate) { + if (i.opcode() == spv::Op::OpDecorate) { if (i.operands().size() > 2) { - if (i.GetOperandAs(1) == SpvDecorationBuiltIn && - i.GetOperandAs(2) == SpvBuiltInWorkgroupSize) { + if (i.GetOperandAs(1) == + spv::Decoration::BuiltIn && + i.GetOperandAs(2) == + spv::BuiltIn::WorkgroupSize) { ok = true; break; } } } - if (i.opcode() == SpvOpExecutionModeId) { - const auto mode = i.GetOperandAs(1); - if (mode == SpvExecutionModeLocalSizeId) { + if (i.opcode() == spv::Op::OpExecutionModeId) { + const auto mode = i.GetOperandAs(1); + if (mode == spv::ExecutionMode::LocalSizeId) { ok = true; break; } @@ -333,15 +338,15 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "operand of an OpEntryPoint."; } - const auto mode = inst->GetOperandAs(1); - if (inst->opcode() == SpvOpExecutionModeId) { + const auto mode = inst->GetOperandAs(1); + if (inst->opcode() == spv::Op::OpExecutionModeId) { size_t operand_count = inst->operands().size(); for (size_t i = 2; i < operand_count; ++i) { const auto operand_id = inst->GetOperandAs(2); const auto* operand_inst = _.FindDef(operand_id); - if (mode == SpvExecutionModeSubgroupsPerWorkgroupId || - mode == SpvExecutionModeLocalSizeHintId || - mode == SpvExecutionModeLocalSizeId) { + if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId || + mode == spv::ExecutionMode::LocalSizeHintId || + mode == spv::ExecutionMode::LocalSizeId) { if (!spvOpcodeIsConstant(operand_inst->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "For OpExecutionModeId all Extra Operand ids must be " @@ -355,9 +360,9 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "operands."; } } - } else if (mode == SpvExecutionModeSubgroupsPerWorkgroupId || - mode == SpvExecutionModeLocalSizeHintId || - mode == SpvExecutionModeLocalSizeId) { + } else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId || + mode == spv::ExecutionMode::LocalSizeHintId || + mode == spv::ExecutionMode::LocalSizeId) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "OpExecutionMode is only valid when the Mode operand is an " "execution mode that takes no Extra Operands, or takes Extra " @@ -366,39 +371,39 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, const auto* models = _.GetExecutionModels(entry_point_id); switch (mode) { - case SpvExecutionModeInvocations: - case SpvExecutionModeInputPoints: - case SpvExecutionModeInputLines: - case SpvExecutionModeInputLinesAdjacency: - case SpvExecutionModeInputTrianglesAdjacency: - case SpvExecutionModeOutputLineStrip: - case SpvExecutionModeOutputTriangleStrip: + case spv::ExecutionMode::Invocations: + case spv::ExecutionMode::InputPoints: + case spv::ExecutionMode::InputLines: + case spv::ExecutionMode::InputLinesAdjacency: + case spv::ExecutionMode::InputTrianglesAdjacency: + case spv::ExecutionMode::OutputLineStrip: + case spv::ExecutionMode::OutputTriangleStrip: if (!std::all_of(models->begin(), models->end(), - [](const SpvExecutionModel& model) { - return model == SpvExecutionModelGeometry; + [](const spv::ExecutionModel& model) { + return model == spv::ExecutionModel::Geometry; })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Geometry execution " "model."; } break; - case SpvExecutionModeOutputPoints: - if (!std::all_of(models->begin(), models->end(), - [&_](const SpvExecutionModel& model) { - switch (model) { - case SpvExecutionModelGeometry: - return true; - case SpvExecutionModelMeshNV: - return _.HasCapability(SpvCapabilityMeshShadingNV); - case SpvExecutionModelMeshEXT: - return _.HasCapability( - SpvCapabilityMeshShadingEXT); - default: - return false; - } - })) { - if (_.HasCapability(SpvCapabilityMeshShadingNV) || - _.HasCapability(SpvCapabilityMeshShadingEXT)) { + case spv::ExecutionMode::OutputPoints: + if (!std::all_of( + models->begin(), models->end(), + [&_](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Geometry: + return true; + case spv::ExecutionModel::MeshNV: + return _.HasCapability(spv::Capability::MeshShadingNV); + case spv::ExecutionModel::MeshEXT: + return _.HasCapability(spv::Capability::MeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(spv::Capability::MeshShadingNV) || + _.HasCapability(spv::Capability::MeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Geometry " "MeshNV or MeshEXT execution model."; @@ -410,32 +415,32 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } } break; - case SpvExecutionModeSpacingEqual: - case SpvExecutionModeSpacingFractionalEven: - case SpvExecutionModeSpacingFractionalOdd: - case SpvExecutionModeVertexOrderCw: - case SpvExecutionModeVertexOrderCcw: - case SpvExecutionModePointMode: - case SpvExecutionModeQuads: - case SpvExecutionModeIsolines: + case spv::ExecutionMode::SpacingEqual: + case spv::ExecutionMode::SpacingFractionalEven: + case spv::ExecutionMode::SpacingFractionalOdd: + case spv::ExecutionMode::VertexOrderCw: + case spv::ExecutionMode::VertexOrderCcw: + case spv::ExecutionMode::PointMode: + case spv::ExecutionMode::Quads: + case spv::ExecutionMode::Isolines: if (!std::all_of( models->begin(), models->end(), - [](const SpvExecutionModel& model) { - return (model == SpvExecutionModelTessellationControl) || - (model == SpvExecutionModelTessellationEvaluation); + [](const spv::ExecutionModel& model) { + return (model == spv::ExecutionModel::TessellationControl) || + (model == spv::ExecutionModel::TessellationEvaluation); })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a tessellation " "execution model."; } break; - case SpvExecutionModeTriangles: + case spv::ExecutionMode::Triangles: if (!std::all_of(models->begin(), models->end(), - [](const SpvExecutionModel& model) { + [](const spv::ExecutionModel& model) { switch (model) { - case SpvExecutionModelGeometry: - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: return true; default: return false; @@ -446,25 +451,25 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "tessellation execution model."; } break; - case SpvExecutionModeOutputVertices: - if (!std::all_of(models->begin(), models->end(), - [&_](const SpvExecutionModel& model) { - switch (model) { - case SpvExecutionModelGeometry: - case SpvExecutionModelTessellationControl: - case SpvExecutionModelTessellationEvaluation: - return true; - case SpvExecutionModelMeshNV: - return _.HasCapability(SpvCapabilityMeshShadingNV); - case SpvExecutionModelMeshEXT: - return _.HasCapability( - SpvCapabilityMeshShadingEXT); - default: - return false; - } - })) { - if (_.HasCapability(SpvCapabilityMeshShadingNV) || - _.HasCapability(SpvCapabilityMeshShadingEXT)) { + case spv::ExecutionMode::OutputVertices: + if (!std::all_of( + models->begin(), models->end(), + [&_](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + return true; + case spv::ExecutionModel::MeshNV: + return _.HasCapability(spv::Capability::MeshShadingNV); + case spv::ExecutionModel::MeshEXT: + return _.HasCapability(spv::Capability::MeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(spv::Capability::MeshShadingNV) || + _.HasCapability(spv::Capability::MeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Geometry, " "tessellation, MeshNV or MeshEXT execution model."; @@ -475,13 +480,13 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } } break; - case SpvExecutionModeOutputLinesEXT: - case SpvExecutionModeOutputTrianglesEXT: - case SpvExecutionModeOutputPrimitivesEXT: + case spv::ExecutionMode::OutputLinesEXT: + case spv::ExecutionMode::OutputTrianglesEXT: + case spv::ExecutionMode::OutputPrimitivesEXT: if (!std::all_of(models->begin(), models->end(), - [](const SpvExecutionModel& model) { - return (model == SpvExecutionModelMeshEXT || - model == SpvExecutionModelMeshNV); + [](const spv::ExecutionModel& model) { + return (model == spv::ExecutionModel::MeshEXT || + model == spv::ExecutionModel::MeshNV); })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the MeshEXT or MeshNV " @@ -489,74 +494,74 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "model."; } break; - case SpvExecutionModePixelCenterInteger: - case SpvExecutionModeOriginUpperLeft: - case SpvExecutionModeOriginLowerLeft: - case SpvExecutionModeEarlyFragmentTests: - case SpvExecutionModeDepthReplacing: - case SpvExecutionModeDepthGreater: - case SpvExecutionModeDepthLess: - case SpvExecutionModeDepthUnchanged: - case SpvExecutionModePixelInterlockOrderedEXT: - case SpvExecutionModePixelInterlockUnorderedEXT: - case SpvExecutionModeSampleInterlockOrderedEXT: - case SpvExecutionModeSampleInterlockUnorderedEXT: - case SpvExecutionModeShadingRateInterlockOrderedEXT: - case SpvExecutionModeShadingRateInterlockUnorderedEXT: - case SpvExecutionModeEarlyAndLateFragmentTestsAMD: - case SpvExecutionModeStencilRefUnchangedFrontAMD: - case SpvExecutionModeStencilRefGreaterFrontAMD: - case SpvExecutionModeStencilRefLessFrontAMD: - case SpvExecutionModeStencilRefUnchangedBackAMD: - case SpvExecutionModeStencilRefGreaterBackAMD: - case SpvExecutionModeStencilRefLessBackAMD: + case spv::ExecutionMode::PixelCenterInteger: + case spv::ExecutionMode::OriginUpperLeft: + case spv::ExecutionMode::OriginLowerLeft: + case spv::ExecutionMode::EarlyFragmentTests: + case spv::ExecutionMode::DepthReplacing: + case spv::ExecutionMode::DepthGreater: + case spv::ExecutionMode::DepthLess: + case spv::ExecutionMode::DepthUnchanged: + case spv::ExecutionMode::PixelInterlockOrderedEXT: + case spv::ExecutionMode::PixelInterlockUnorderedEXT: + case spv::ExecutionMode::SampleInterlockOrderedEXT: + case spv::ExecutionMode::SampleInterlockUnorderedEXT: + case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: + case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: + case spv::ExecutionMode::EarlyAndLateFragmentTestsAMD: + case spv::ExecutionMode::StencilRefUnchangedFrontAMD: + case spv::ExecutionMode::StencilRefGreaterFrontAMD: + case spv::ExecutionMode::StencilRefLessFrontAMD: + case spv::ExecutionMode::StencilRefUnchangedBackAMD: + case spv::ExecutionMode::StencilRefGreaterBackAMD: + case spv::ExecutionMode::StencilRefLessBackAMD: if (!std::all_of(models->begin(), models->end(), - [](const SpvExecutionModel& model) { - return model == SpvExecutionModelFragment; + [](const spv::ExecutionModel& model) { + return model == spv::ExecutionModel::Fragment; })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Fragment execution " "model."; } break; - case SpvExecutionModeLocalSizeHint: - case SpvExecutionModeVecTypeHint: - case SpvExecutionModeContractionOff: - case SpvExecutionModeLocalSizeHintId: + case spv::ExecutionMode::LocalSizeHint: + case spv::ExecutionMode::VecTypeHint: + case spv::ExecutionMode::ContractionOff: + case spv::ExecutionMode::LocalSizeHintId: if (!std::all_of(models->begin(), models->end(), - [](const SpvExecutionModel& model) { - return model == SpvExecutionModelKernel; + [](const spv::ExecutionModel& model) { + return model == spv::ExecutionModel::Kernel; })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Kernel execution " "model."; } break; - case SpvExecutionModeLocalSize: - case SpvExecutionModeLocalSizeId: - if (mode == SpvExecutionModeLocalSizeId && !_.IsLocalSizeIdAllowed()) + case spv::ExecutionMode::LocalSize: + case spv::ExecutionMode::LocalSizeId: + if (mode == spv::ExecutionMode::LocalSizeId && !_.IsLocalSizeIdAllowed()) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "LocalSizeId mode is not allowed by the current environment."; - if (!std::all_of(models->begin(), models->end(), - [&_](const SpvExecutionModel& model) { - switch (model) { - case SpvExecutionModelKernel: - case SpvExecutionModelGLCompute: - return true; - case SpvExecutionModelTaskNV: - case SpvExecutionModelMeshNV: - return _.HasCapability(SpvCapabilityMeshShadingNV); - case SpvExecutionModelTaskEXT: - case SpvExecutionModelMeshEXT: - return _.HasCapability( - SpvCapabilityMeshShadingEXT); - default: - return false; - } - })) { - if (_.HasCapability(SpvCapabilityMeshShadingNV) || - _.HasCapability(SpvCapabilityMeshShadingEXT)) { + if (!std::all_of( + models->begin(), models->end(), + [&_](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Kernel: + case spv::ExecutionModel::GLCompute: + return true; + case spv::ExecutionModel::TaskNV: + case spv::ExecutionModel::MeshNV: + return _.HasCapability(spv::Capability::MeshShadingNV); + case spv::ExecutionModel::TaskEXT: + case spv::ExecutionModel::MeshEXT: + return _.HasCapability(spv::Capability::MeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(spv::Capability::MeshShadingNV) || + _.HasCapability(spv::Capability::MeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Kernel, GLCompute, " "MeshNV, MeshEXT, TaskNV or TaskEXT execution model."; @@ -572,13 +577,13 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } if (spvIsVulkanEnv(_.context()->target_env)) { - if (mode == SpvExecutionModeOriginLowerLeft) { + if (mode == spv::ExecutionMode::OriginLowerLeft) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4653) << "In the Vulkan environment, the OriginLowerLeft execution mode " "must not be used."; } - if (mode == SpvExecutionModePixelCenterInteger) { + if (mode == spv::ExecutionMode::PixelCenterInteger) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4654) << "In the Vulkan environment, the PixelCenterInteger execution " @@ -593,29 +598,30 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _, const Instruction* inst) { // Already produced an error if multiple memory model instructions are // present. - if (_.memory_model() != SpvMemoryModelVulkanKHR && - _.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { + if (_.memory_model() != spv::MemoryModel::VulkanKHR && + _.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "VulkanMemoryModelKHR capability must only be specified if " "the VulkanKHR memory model is used."; } if (spvIsOpenCLEnv(_.context()->target_env)) { - if ((_.addressing_model() != SpvAddressingModelPhysical32) && - (_.addressing_model() != SpvAddressingModelPhysical64)) { + if ((_.addressing_model() != spv::AddressingModel::Physical32) && + (_.addressing_model() != spv::AddressingModel::Physical64)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Addressing model must be Physical32 or Physical64 " << "in the OpenCL environment."; } - if (_.memory_model() != SpvMemoryModelOpenCL) { + if (_.memory_model() != spv::MemoryModel::OpenCL) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory model must be OpenCL in the OpenCL environment."; } } if (spvIsVulkanEnv(_.context()->target_env)) { - if ((_.addressing_model() != SpvAddressingModelLogical) && - (_.addressing_model() != SpvAddressingModelPhysicalStorageBuffer64)) { + if ((_.addressing_model() != spv::AddressingModel::Logical) && + (_.addressing_model() != + spv::AddressingModel::PhysicalStorageBuffer64)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4635) << "Addressing model must be Logical or PhysicalStorageBuffer64 " @@ -629,14 +635,14 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _, spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case SpvOpEntryPoint: + case spv::Op::OpEntryPoint: if (auto error = ValidateEntryPoint(_, inst)) return error; break; - case SpvOpExecutionMode: - case SpvOpExecutionModeId: + case spv::Op::OpExecutionMode: + case spv::Op::OpExecutionModeId: if (auto error = ValidateExecutionMode(_, inst)) return error; break; - case SpvOpMemoryModel: + case spv::Op::OpMemoryModel: if (auto error = ValidateMemoryModel(_, inst)) return error; break; default: diff --git a/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp b/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp index 6d4f8a284..5c5e9bd8b 100644 --- a/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp +++ b/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp @@ -48,11 +48,11 @@ spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _, "of integer type scalar"; } - const auto group = inst->GetOperandAs(3); + const auto group = inst->GetOperandAs(3); if (spvIsVulkanEnv(_.context()->target_env)) { - if ((group != SpvGroupOperationReduce) && - (group != SpvGroupOperationInclusiveScan) && - (group != SpvGroupOperationExclusiveScan)) { + if ((group != spv::GroupOperation::Reduce) && + (group != spv::GroupOperation::InclusiveScan) && + (group != spv::GroupOperation::ExclusiveScan)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4685) << "In Vulkan: The OpGroupNonUniformBallotBitCount group " @@ -120,7 +120,7 @@ spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _, // Validates correctness of non-uniform group instructions. spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); if (spvOpcodeIsNonUniformGroupOperation(opcode)) { const uint32_t execution_scope = inst->word(3); @@ -130,9 +130,9 @@ spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) { } switch (opcode) { - case SpvOpGroupNonUniformBallotBitCount: + case spv::Op::OpGroupNonUniformBallotBitCount: return ValidateGroupNonUniformBallotBitCount(_, inst); - case SpvOpGroupNonUniformRotateKHR: + case spv::Op::OpGroupNonUniformRotateKHR: return ValidateGroupNonUniformRotateKHR(_, inst); default: break; diff --git a/3rdparty/spirv-tools/source/val/validate_primitives.cpp b/3rdparty/spirv-tools/source/val/validate_primitives.cpp index 7d11f2e7a..5e598c3ae 100644 --- a/3rdparty/spirv-tools/source/val/validate_primitives.cpp +++ b/3rdparty/spirv-tools/source/val/validate_primitives.cpp @@ -28,16 +28,16 @@ namespace val { // Validates correctness of primitive instructions. spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); switch (opcode) { - case SpvOpEmitVertex: - case SpvOpEndPrimitive: - case SpvOpEmitStreamVertex: - case SpvOpEndStreamPrimitive: + case spv::Op::OpEmitVertex: + case spv::Op::OpEndPrimitive: + case spv::Op::OpEmitStreamVertex: + case spv::Op::OpEndStreamPrimitive: _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelGeometry, + spv::ExecutionModel::Geometry, std::string(spvOpcodeString(opcode)) + " instructions require Geometry execution model"); break; @@ -46,8 +46,8 @@ spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { } switch (opcode) { - case SpvOpEmitStreamVertex: - case SpvOpEndStreamPrimitive: { + case spv::Op::OpEmitStreamVertex: + case spv::Op::OpEndStreamPrimitive: { const uint32_t stream_id = inst->word(1); const uint32_t stream_type = _.GetTypeId(stream_id); if (!_.IsIntScalarType(stream_type)) { @@ -56,7 +56,7 @@ spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { << ": expected Stream to be int scalar"; } - const SpvOp stream_opcode = _.GetIdOpcode(stream_id); + const spv::Op stream_opcode = _.GetIdOpcode(stream_id); if (!spvOpcodeIsConstant(stream_opcode)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) diff --git a/3rdparty/spirv-tools/source/val/validate_ray_query.cpp b/3rdparty/spirv-tools/source/val/validate_ray_query.cpp index b553449d0..9b67fc922 100644 --- a/3rdparty/spirv-tools/source/val/validate_ray_query.cpp +++ b/3rdparty/spirv-tools/source/val/validate_ray_query.cpp @@ -29,19 +29,19 @@ spv_result_t ValidateRayQueryPointer(ValidationState_t& _, const uint32_t ray_query_id = inst->GetOperandAs(ray_query_index); auto variable = _.FindDef(ray_query_id); const auto var_opcode = variable->opcode(); - if (!variable || - (var_opcode != SpvOpVariable && var_opcode != SpvOpFunctionParameter && - var_opcode != SpvOpAccessChain)) { + if (!variable || (var_opcode != spv::Op::OpVariable && + var_opcode != spv::Op::OpFunctionParameter && + var_opcode != spv::Op::OpAccessChain)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Ray Query must be a memory object declaration"; } auto pointer = _.FindDef(variable->GetOperandAs(0)); - if (!pointer || pointer->opcode() != SpvOpTypePointer) { + if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Ray Query must be a pointer"; } auto type = _.FindDef(pointer->GetOperandAs(2)); - if (!type || type->opcode() != SpvOpTypeRayQueryKHR) { + if (!type || type->opcode() != spv::Op::OpTypeRayQueryKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Ray Query must be a pointer to OpTypeRayQueryKHR"; } @@ -54,7 +54,7 @@ spv_result_t ValidateIntersectionId(ValidationState_t& _, const uint32_t intersection_id = inst->GetOperandAs(intersection_index); const uint32_t intersection_type = _.GetTypeId(intersection_id); - const SpvOp intersection_opcode = _.GetIdOpcode(intersection_id); + const spv::Op intersection_opcode = _.GetIdOpcode(intersection_id); if (!_.IsIntScalarType(intersection_type) || _.GetBitWidth(intersection_type) != 32 || !spvOpcodeIsConstant(intersection_opcode)) { @@ -68,15 +68,15 @@ spv_result_t ValidateIntersectionId(ValidationState_t& _, } // namespace spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpRayQueryInitializeKHR: { + case spv::Op::OpRayQueryInitializeKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; if (_.GetIdOpcode(_.GetOperandTypeId(inst, 1)) != - SpvOpTypeAccelerationStructureKHR) { + spv::Op::OpTypeAccelerationStructureKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Acceleration Structure to be of type " "OpTypeAccelerationStructureKHR"; @@ -123,13 +123,13 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpRayQueryTerminateKHR: - case SpvOpRayQueryConfirmIntersectionKHR: { + case spv::Op::OpRayQueryTerminateKHR: + case spv::Op::OpRayQueryConfirmIntersectionKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; break; } - case SpvOpRayQueryGenerateIntersectionKHR: { + case spv::Op::OpRayQueryGenerateIntersectionKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; const uint32_t hit_t_id = _.GetOperandTypeId(inst, 1); @@ -141,9 +141,9 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpRayQueryGetIntersectionFrontFaceKHR: - case SpvOpRayQueryProceedKHR: - case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: { + case spv::Op::OpRayQueryGetIntersectionFrontFaceKHR: + case spv::Op::OpRayQueryProceedKHR: + case spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsBoolScalarType(result_type)) { @@ -151,15 +151,15 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { << "expected Result Type to be bool scalar type"; } - if (opcode == SpvOpRayQueryGetIntersectionFrontFaceKHR) { + if (opcode == spv::Op::OpRayQueryGetIntersectionFrontFaceKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case SpvOpRayQueryGetIntersectionTKHR: - case SpvOpRayQueryGetRayTMinKHR: { + case spv::Op::OpRayQueryGetIntersectionTKHR: + case spv::Op::OpRayQueryGetRayTMinKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsFloatScalarType(result_type) || @@ -168,20 +168,21 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { << "expected Result Type to be 32-bit float scalar type"; } - if (opcode == SpvOpRayQueryGetIntersectionTKHR) { + if (opcode == spv::Op::OpRayQueryGetIntersectionTKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case SpvOpRayQueryGetIntersectionTypeKHR: - case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: - case SpvOpRayQueryGetIntersectionInstanceIdKHR: - case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: - case SpvOpRayQueryGetIntersectionGeometryIndexKHR: - case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: - case SpvOpRayQueryGetRayFlagsKHR: { + case spv::Op::OpRayQueryGetIntersectionTypeKHR: + case spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: + case spv::Op::OpRayQueryGetIntersectionInstanceIdKHR: + case spv::Op:: + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: + case spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR: + case spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: + case spv::Op::OpRayQueryGetRayFlagsKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsIntScalarType(result_type) || _.GetBitWidth(result_type) != 32) { @@ -189,17 +190,17 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { << "expected Result Type to be 32-bit int scalar type"; } - if (opcode != SpvOpRayQueryGetRayFlagsKHR) { + if (opcode != spv::Op::OpRayQueryGetRayFlagsKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: - case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: - case SpvOpRayQueryGetWorldRayDirectionKHR: - case SpvOpRayQueryGetWorldRayOriginKHR: { + case spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: + case spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR: + case spv::Op::OpRayQueryGetWorldRayDirectionKHR: + case spv::Op::OpRayQueryGetWorldRayOriginKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsFloatVectorType(result_type) || @@ -210,15 +211,15 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { "vector type"; } - if (opcode == SpvOpRayQueryGetIntersectionObjectRayDirectionKHR || - opcode == SpvOpRayQueryGetIntersectionObjectRayOriginKHR) { + if (opcode == spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR || + opcode == spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case SpvOpRayQueryGetIntersectionBarycentricsKHR: { + case spv::Op::OpRayQueryGetIntersectionBarycentricsKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (auto error = ValidateIntersectionId(_, inst, 3)) return error; @@ -233,8 +234,8 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpRayQueryGetIntersectionObjectToWorldKHR: - case SpvOpRayQueryGetIntersectionWorldToObjectKHR: { + case spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR: + case spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (auto error = ValidateIntersectionId(_, inst, 3)) return error; diff --git a/3rdparty/spirv-tools/source/val/validate_ray_tracing.cpp b/3rdparty/spirv-tools/source/val/validate_ray_tracing.cpp index 5b5c8da1e..f74e9d4b9 100644 --- a/3rdparty/spirv-tools/source/val/validate_ray_tracing.cpp +++ b/3rdparty/spirv-tools/source/val/validate_ray_tracing.cpp @@ -23,17 +23,17 @@ namespace spvtools { namespace val { spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case SpvOpTraceRayKHR: { + case spv::Op::OpTraceRayKHR: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelRayGenerationKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelMissKHR) { + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { if (message) { *message = "OpTraceRayKHR requires RayGenerationKHR, " @@ -45,7 +45,7 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { }); if (_.GetIdOpcode(_.GetOperandTypeId(inst, 0)) != - SpvOpTypeAccelerationStructureKHR) { + spv::Op::OpTypeAccelerationStructureKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Acceleration Structure to be of type " "OpTypeAccelerationStructureKHR"; @@ -109,13 +109,13 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { } const Instruction* payload = _.FindDef(inst->GetOperandAs(10)); - if (payload->opcode() != SpvOpVariable) { + if (payload->opcode() != spv::Op::OpVariable) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload must be the result of a OpVariable"; - } else if (payload->GetOperandAs(2) != - SpvStorageClassRayPayloadKHR && - payload->GetOperandAs(2) != - SpvStorageClassIncomingRayPayloadKHR) { + } else if (payload->GetOperandAs(2) != + spv::StorageClass::RayPayloadKHR && + payload->GetOperandAs(2) != + spv::StorageClass::IncomingRayPayloadKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload must have storage class RayPayloadKHR or " "IncomingRayPayloadKHR"; @@ -123,11 +123,11 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpReportIntersectionKHR: { + case spv::Op::OpReportIntersectionKHR: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelIntersectionKHR) { + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::IntersectionKHR) { if (message) { *message = "OpReportIntersectionKHR requires IntersectionKHR " @@ -158,14 +158,14 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { break; } - case SpvOpExecuteCallableKHR: { + case spv::Op::OpExecuteCallableKHR: { _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([](SpvExecutionModel model, + ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, std::string* message) { - if (model != SpvExecutionModelRayGenerationKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelMissKHR && - model != SpvExecutionModelCallableKHR) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR && + model != spv::ExecutionModel::CallableKHR) { if (message) { *message = "OpExecuteCallableKHR requires RayGenerationKHR, " @@ -184,13 +184,13 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { } const auto callable_data = _.FindDef(inst->GetOperandAs(1)); - if (callable_data->opcode() != SpvOpVariable) { + if (callable_data->opcode() != spv::Op::OpVariable) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Callable Data must be the result of a OpVariable"; - } else if (callable_data->GetOperandAs(2) != - SpvStorageClassCallableDataKHR && - callable_data->GetOperandAs(2) != - SpvStorageClassIncomingCallableDataKHR) { + } else if (callable_data->GetOperandAs(2) != + spv::StorageClass::CallableDataKHR && + callable_data->GetOperandAs(2) != + spv::StorageClass::IncomingCallableDataKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Callable Data must have storage class CallableDataKHR or " "IncomingCallableDataKHR"; diff --git a/3rdparty/spirv-tools/source/val/validate_ray_tracing_reorder.cpp b/3rdparty/spirv-tools/source/val/validate_ray_tracing_reorder.cpp new file mode 100644 index 000000000..cb190f91e --- /dev/null +++ b/3rdparty/spirv-tools/source/val/validate_ray_tracing_reorder.cpp @@ -0,0 +1,625 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates ray tracing instructions from SPV_NV_shader_execution_reorder + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +#include + +namespace spvtools { +namespace val { + +static const uint32_t KRayParamInvalidId = std::numeric_limits::max(); + +spv_result_t ValidateHitObjectPointer(ValidationState_t& _, + const Instruction* inst, + uint32_t hit_object_index) { + const uint32_t hit_object_id = inst->GetOperandAs(hit_object_index); + auto variable = _.FindDef(hit_object_id); + const auto var_opcode = variable->opcode(); + if (!variable || (var_opcode != spv::Op::OpVariable && + var_opcode != spv::Op::OpFunctionParameter && + var_opcode != spv::Op::OpAccessChain)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object must be a memory object declaration"; + } + auto pointer = _.FindDef(variable->GetOperandAs(0)); + if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object must be a pointer"; + } + auto type = _.FindDef(pointer->GetOperandAs(2)); + if (!type || type->opcode() != spv::Op::OpTypeHitObjectNV) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Type must be OpTypeHitObjectNV"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateHitObjectInstructionCommonParameters( + ValidationState_t& _, const Instruction* inst, + uint32_t acceleration_struct_index, uint32_t instance_id_index, + uint32_t primtive_id_index, uint32_t geometry_index, + uint32_t ray_flags_index, uint32_t cull_mask_index, uint32_t hit_kind_index, + uint32_t sbt_index, uint32_t sbt_offset_index, uint32_t sbt_stride_index, + uint32_t sbt_record_offset_index, uint32_t sbt_record_stride_index, + uint32_t miss_index, uint32_t ray_origin_index, uint32_t ray_tmin_index, + uint32_t ray_direction_index, uint32_t ray_tmax_index, + uint32_t payload_index, uint32_t hit_object_attr_index) { + auto isValidId = [](uint32_t spvid) { return spvid < KRayParamInvalidId; }; + if (isValidId(acceleration_struct_index) && + _.GetIdOpcode(_.GetOperandTypeId(inst, acceleration_struct_index)) != + spv::Op::OpTypeAccelerationStructureKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Acceleration Structure to be of type " + "OpTypeAccelerationStructureKHR"; + } + + if (isValidId(instance_id_index)) { + const uint32_t instance_id = _.GetOperandTypeId(inst, instance_id_index); + if (!_.IsIntScalarType(instance_id) || _.GetBitWidth(instance_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Instance Id must be a 32-bit int scalar"; + } + } + + if (isValidId(primtive_id_index)) { + const uint32_t primitive_id = _.GetOperandTypeId(inst, primtive_id_index); + if (!_.IsIntScalarType(primitive_id) || _.GetBitWidth(primitive_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Primitive Id must be a 32-bit int scalar"; + } + } + + if (isValidId(geometry_index)) { + const uint32_t geometry_index_id = _.GetOperandTypeId(inst, geometry_index); + if (!_.IsIntScalarType(geometry_index_id) || + _.GetBitWidth(geometry_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Geometry Index must be a 32-bit int scalar"; + } + } + + if (isValidId(miss_index)) { + const uint32_t miss_index_id = _.GetOperandTypeId(inst, miss_index); + if (!_.IsUnsignedIntScalarType(miss_index_id) || + _.GetBitWidth(miss_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Miss Index must be a 32-bit int scalar"; + } + } + + if (isValidId(cull_mask_index)) { + const uint32_t cull_mask_id = _.GetOperandTypeId(inst, cull_mask_index); + if (!_.IsUnsignedIntScalarType(cull_mask_id) || + _.GetBitWidth(cull_mask_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cull mask must be a 32-bit int scalar"; + } + } + + if (isValidId(sbt_index)) { + const uint32_t sbt_index_id = _.GetOperandTypeId(inst, sbt_index); + if (!_.IsUnsignedIntScalarType(sbt_index_id) || + _.GetBitWidth(sbt_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Index must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_offset_index)) { + const uint32_t sbt_offset_id = _.GetOperandTypeId(inst, sbt_offset_index); + if (!_.IsUnsignedIntScalarType(sbt_offset_id) || + _.GetBitWidth(sbt_offset_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Offset must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_stride_index)) { + const uint32_t sbt_stride_index_id = + _.GetOperandTypeId(inst, sbt_stride_index); + if (!_.IsUnsignedIntScalarType(sbt_stride_index_id) || + _.GetBitWidth(sbt_stride_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Stride must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_record_offset_index)) { + const uint32_t sbt_record_offset_index_id = + _.GetOperandTypeId(inst, sbt_record_offset_index); + if (!_.IsUnsignedIntScalarType(sbt_record_offset_index_id) || + _.GetBitWidth(sbt_record_offset_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT record offset must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_record_stride_index)) { + const uint32_t sbt_record_stride_index_id = + _.GetOperandTypeId(inst, sbt_record_stride_index); + if (!_.IsUnsignedIntScalarType(sbt_record_stride_index_id) || + _.GetBitWidth(sbt_record_stride_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT record stride must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(ray_origin_index)) { + const uint32_t ray_origin_id = _.GetOperandTypeId(inst, ray_origin_index); + if (!_.IsFloatVectorType(ray_origin_id) || + _.GetDimension(ray_origin_id) != 3 || + _.GetBitWidth(ray_origin_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Origin must be a 32-bit float 3-component vector"; + } + } + + if (isValidId(ray_tmin_index)) { + const uint32_t ray_tmin_id = _.GetOperandTypeId(inst, ray_tmin_index); + if (!_.IsFloatScalarType(ray_tmin_id) || _.GetBitWidth(ray_tmin_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMin must be a 32-bit float scalar"; + } + } + + if (isValidId(ray_direction_index)) { + const uint32_t ray_direction_id = + _.GetOperandTypeId(inst, ray_direction_index); + if (!_.IsFloatVectorType(ray_direction_id) || + _.GetDimension(ray_direction_id) != 3 || + _.GetBitWidth(ray_direction_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Direction must be a 32-bit float 3-component vector"; + } + } + + if (isValidId(ray_tmax_index)) { + const uint32_t ray_tmax_id = _.GetOperandTypeId(inst, ray_tmax_index); + if (!_.IsFloatScalarType(ray_tmax_id) || _.GetBitWidth(ray_tmax_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMax must be a 32-bit float scalar"; + } + } + + if (isValidId(ray_flags_index)) { + const uint32_t ray_flags_id = _.GetOperandTypeId(inst, ray_flags_index); + if (!_.IsIntScalarType(ray_flags_id) || _.GetBitWidth(ray_flags_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Flags must be a 32-bit int scalar"; + } + } + + if (isValidId(payload_index)) { + const uint32_t payload_id = inst->GetOperandAs(payload_index); + auto variable = _.FindDef(payload_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + (variable->GetOperandAs(2) != + spv::StorageClass::RayPayloadKHR && + variable->GetOperandAs(2) != + spv::StorageClass::IncomingRayPayloadKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "payload must be a OpVariable of storage " + "class RayPayloadKHR or IncomingRayPayloadKHR"; + } + } + + if (isValidId(hit_kind_index)) { + const uint32_t hit_kind_id = _.GetOperandTypeId(inst, hit_kind_index); + if (!_.IsUnsignedIntScalarType(hit_kind_id) || + _.GetBitWidth(hit_kind_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Kind must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(hit_object_attr_index)) { + const uint32_t hit_object_attr_id = + inst->GetOperandAs(hit_object_attr_index); + auto variable = _.FindDef(hit_object_attr_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + (variable->GetOperandAs(2)) != + spv::StorageClass::HitObjectAttributeNV) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object Attributes id must be a OpVariable of storage " + "class HitObjectAttributeNV"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + auto RegisterOpcodeForValidModel = [](ValidationState_t& vs, + const Instruction* rtinst) { + std::string opcode_name = spvOpcodeString(rtinst->opcode()); + vs.function(rtinst->function()->id()) + ->RegisterExecutionModelLimitation( + [opcode_name](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = opcode_name + + " requires RayGenerationKHR, ClosestHitKHR and " + "MissKHR execution models"; + } + return false; + } + return true; + }); + return; + }; + + switch (opcode) { + case spv::Op::OpHitObjectIsMissNV: + case spv::Op::OpHitObjectIsHitNV: + case spv::Op::OpHitObjectIsEmptyNV: { + RegisterOpcodeForValidModel(_, inst); + if (!_.IsBoolScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be bool scalar type"; + } + + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + break; + } + + case spv::Op::OpHitObjectGetShaderRecordBufferHandleNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsIntVectorType(result_type) || + (_.GetDimension(result_type) != 2) || + (_.GetBitWidth(result_type) != 32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit integer type 2-component vector as Result " + "Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetHitKindNV: + case spv::Op::OpHitObjectGetPrimitiveIndexNV: + case spv::Op::OpHitObjectGetGeometryIndexNV: + case spv::Op::OpHitObjectGetInstanceIdNV: + case spv::Op::OpHitObjectGetInstanceCustomIndexNV: + case spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsIntScalarType(result_type) || !_.GetBitWidth(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit integer type scalar as Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetCurrentTimeNV: + case spv::Op::OpHitObjectGetRayTMaxNV: + case spv::Op::OpHitObjectGetRayTMinNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsFloatScalarType(result_type) || _.GetBitWidth(result_type) != 32) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit floating-point type scalar as Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetObjectToWorldNV: + case spv::Op::OpHitObjectGetWorldToObjectNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + uint32_t num_rows = 0; + uint32_t num_cols = 0; + uint32_t col_type = 0; + uint32_t component_type = 0; + + if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type, + &component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected matrix type as Result Type: " + << spvOpcodeString(opcode); + } + + if (num_cols != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type matrix to have a Column Count of 4" + << spvOpcodeString(opcode); + } + + if (!_.IsFloatScalarType(component_type) || + _.GetBitWidth(result_type) != 32 || num_rows != 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type matrix to have a Column Type of " + "3-component 32-bit float vectors: " + << spvOpcodeString(opcode); + } + break; + } + + case spv::Op::OpHitObjectGetObjectRayOriginNV: + case spv::Op::OpHitObjectGetObjectRayDirectionNV: + case spv::Op::OpHitObjectGetWorldRayDirectionNV: + case spv::Op::OpHitObjectGetWorldRayOriginNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsFloatVectorType(result_type) || + (_.GetDimension(result_type) != 3) || + (_.GetBitWidth(result_type) != 32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit floating-point type 3-component vector as " + "Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetAttributesNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + const uint32_t hit_object_attr_id = inst->GetOperandAs(1); + auto variable = _.FindDef(hit_object_attr_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + variable->GetOperandAs(2) != + spv::StorageClass::HitObjectAttributeNV) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object Attributes id must be a OpVariable of storage " + "class HitObjectAttributeNV"; + } + break; + } + + case spv::Op::OpHitObjectExecuteShaderNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + const uint32_t hit_object_attr_id = inst->GetOperandAs(1); + auto variable = _.FindDef(hit_object_attr_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + (variable->GetOperandAs(2)) != + spv::StorageClass::RayPayloadKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object Attributes id must be a OpVariable of storage " + "class RayPayloadKHR"; + } + break; + } + + case spv::Op::OpHitObjectRecordEmptyNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + break; + } + + case spv::Op::OpHitObjectRecordMissNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + const uint32_t miss_index = _.GetOperandTypeId(inst, 1); + if (!_.IsUnsignedIntScalarType(miss_index) || + _.GetBitWidth(miss_index) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Miss Index must be a 32-bit int scalar"; + } + + const uint32_t ray_origin = _.GetOperandTypeId(inst, 2); + if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 || + _.GetBitWidth(ray_origin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Origin must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmin = _.GetOperandTypeId(inst, 3); + if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMin must be a 32-bit float scalar"; + } + + const uint32_t ray_direction = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatVectorType(ray_direction) || + _.GetDimension(ray_direction) != 3 || + _.GetBitWidth(ray_direction) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Direction must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmax = _.GetOperandTypeId(inst, 5); + if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMax must be a 32-bit float scalar"; + } + break; + } + + case spv::Op::OpHitObjectRecordHitWithIndexNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */, + 3 /* Primtive Id */, 4 /* Geometry Index */, + KRayParamInvalidId /* Ray Flags */, + KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/, + 6 /* SBT index */, KRayParamInvalidId /* SBT Offset */, + KRayParamInvalidId /* SBT Stride */, + KRayParamInvalidId /* SBT Record Offset */, + KRayParamInvalidId /* SBT Record Stride */, + KRayParamInvalidId /* Miss Index */, 7 /* Ray Origin */, + 8 /* Ray TMin */, 9 /* Ray Direction */, 10 /* Ray TMax */, + KRayParamInvalidId /* Payload */, 11 /* Hit Object Attribute */)) + return error; + + break; + } + + case spv::Op::OpHitObjectRecordHitNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */, + 3 /* Primtive Id */, 4 /* Geometry Index */, + KRayParamInvalidId /* Ray Flags */, + KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/, + KRayParamInvalidId /* SBT index */, + KRayParamInvalidId /* SBT Offset */, + KRayParamInvalidId /* SBT Stride */, 6 /* SBT Record Offset */, + 7 /* SBT Record Stride */, KRayParamInvalidId /* Miss Index */, + 8 /* Ray Origin */, 9 /* Ray TMin */, 10 /* Ray Direction */, + 11 /* Ray TMax */, KRayParamInvalidId /* Payload */, + 12 /* Hit Object Attribute */)) + return error; + + break; + } + + case spv::Op::OpHitObjectTraceRayMotionNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, + KRayParamInvalidId /* Instance Id */, + KRayParamInvalidId /* Primtive Id */, + KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */, + 3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/, + KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */, + 5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */, + KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */, + 7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */, + 10 /* Ray TMax */, 12 /* Payload */, + KRayParamInvalidId /* Hit Object Attribute */)) + return error; + // Current Time + const uint32_t current_time_id = _.GetOperandTypeId(inst, 11); + if (!_.IsFloatScalarType(current_time_id) || + _.GetBitWidth(current_time_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Current Times must be a 32-bit float scalar type"; + } + + break; + } + + case spv::Op::OpHitObjectTraceRayNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, + KRayParamInvalidId /* Instance Id */, + KRayParamInvalidId /* Primtive Id */, + KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */, + 3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/, + KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */, + 5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */, + KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */, + 7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */, + 10 /* Ray TMax */, 11 /* Payload */, + KRayParamInvalidId /* Hit Object Attribute */)) + return error; + break; + } + + case spv::Op::OpReorderThreadWithHitObjectNV: { + std::string opcode_name = spvOpcodeString(inst->opcode()); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [opcode_name](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR) { + if (message) { + *message = opcode_name + + " requires RayGenerationKHR execution model"; + } + return false; + } + return true; + }); + + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (inst->operands().size() > 1) { + if (inst->operands().size() != 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hint and Bits are optional together i.e " + << " Either both Hint and Bits should be provided or neither."; + } + + // Validate the optional opreands Hint and Bits + const uint32_t hint_id = _.GetOperandTypeId(inst, 1); + if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hint must be a 32-bit int scalar"; + } + const uint32_t bits_id = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "bits must be a 32-bit int scalar"; + } + } + break; + } + + case spv::Op::OpReorderThreadWithHintNV: { + std::string opcode_name = spvOpcodeString(inst->opcode()); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [opcode_name](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR) { + if (message) { + *message = opcode_name + + " requires RayGenerationKHR execution model"; + } + return false; + } + return true; + }); + + const uint32_t hint_id = _.GetOperandTypeId(inst, 0); + if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hint must be a 32-bit int scalar"; + } + + const uint32_t bits_id = _.GetOperandTypeId(inst, 1); + if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "bits must be a 32-bit int scalar"; + } + } + + default: + break; + } + return SPV_SUCCESS; +} +} // namespace val +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/val/validate_scopes.cpp b/3rdparty/spirv-tools/source/val/validate_scopes.cpp index e9781802c..fa1dad9ec 100644 --- a/3rdparty/spirv-tools/source/val/validate_scopes.cpp +++ b/3rdparty/spirv-tools/source/val/validate_scopes.cpp @@ -25,16 +25,16 @@ namespace val { bool IsValidScope(uint32_t scope) { // Deliberately avoid a default case so we have to update the list when the // scopes list changes. - switch (static_cast(scope)) { - case SpvScopeCrossDevice: - case SpvScopeDevice: - case SpvScopeWorkgroup: - case SpvScopeSubgroup: - case SpvScopeInvocation: - case SpvScopeQueueFamilyKHR: - case SpvScopeShaderCallKHR: + switch (static_cast(scope)) { + case spv::Scope::CrossDevice: + case spv::Scope::Device: + case spv::Scope::Workgroup: + case spv::Scope::Subgroup: + case spv::Scope::Invocation: + case spv::Scope::QueueFamilyKHR: + case spv::Scope::ShaderCallKHR: return true; - case SpvScopeMax: + case spv::Scope::Max: break; } return false; @@ -42,7 +42,7 @@ bool IsValidScope(uint32_t scope) { spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, uint32_t scope) { - SpvOp opcode = inst->opcode(); + spv::Op opcode = inst->opcode(); bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); @@ -53,14 +53,14 @@ spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, } if (!is_const_int32) { - if (_.HasCapability(SpvCapabilityShader) && - !_.HasCapability(SpvCapabilityCooperativeMatrixNV)) { + if (_.HasCapability(spv::Capability::Shader) && + !_.HasCapability(spv::Capability::CooperativeMatrixNV)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Scope ids must be OpConstant when Shader capability is " << "present"; } - if (_.HasCapability(SpvCapabilityShader) && - _.HasCapability(SpvCapabilityCooperativeMatrixNV) && + if (_.HasCapability(spv::Capability::Shader) && + _.HasCapability(spv::Capability::CooperativeMatrixNV) && !spvOpcodeIsConstant(_.GetIdOpcode(scope))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Scope ids must be constant or specialization constant when " @@ -78,10 +78,10 @@ spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateExecutionScope(ValidationState_t& _, const Instruction* inst, uint32_t scope) { - SpvOp opcode = inst->opcode(); + spv::Op opcode = inst->opcode(); bool is_int32 = false, is_const_int32 = false; - uint32_t value = 0; - std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); + uint32_t tmp_value = 0; + std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); if (auto error = ValidateScope(_, inst, scope)) { return error; @@ -91,13 +91,15 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, return SPV_SUCCESS; } + spv::Scope value = spv::Scope(tmp_value); + // Vulkan specific rules if (spvIsVulkanEnv(_.context()->target_env)) { // Vulkan 1.1 specific rules if (_.context()->target_env != SPV_ENV_VULKAN_1_0) { // Scope for Non Uniform Group Operations must be limited to Subgroup if (spvOpcodeIsNonUniformGroupOperation(opcode) && - value != SpvScopeSubgroup) { + value != spv::Scope::Subgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4642) << spvOpcodeString(opcode) << ": in Vulkan environment Execution scope is limited to " @@ -107,21 +109,21 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, // OpControlBarrier must only use Subgroup execution scope for a subset of // execution models. - if (opcode == SpvOpControlBarrier && value != SpvScopeSubgroup) { + if (opcode == spv::Op::OpControlBarrier && value != spv::Scope::Subgroup) { std::string errorVUID = _.VkErrorID(4682); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation([errorVUID]( - SpvExecutionModel model, + spv::ExecutionModel model, std::string* message) { - if (model == SpvExecutionModelFragment || - model == SpvExecutionModelVertex || - model == SpvExecutionModelGeometry || - model == SpvExecutionModelTessellationEvaluation || - model == SpvExecutionModelRayGenerationKHR || - model == SpvExecutionModelIntersectionKHR || - model == SpvExecutionModelAnyHitKHR || - model == SpvExecutionModelClosestHitKHR || - model == SpvExecutionModelMissKHR) { + if (model == spv::ExecutionModel::Fragment || + model == spv::ExecutionModel::Vertex || + model == spv::ExecutionModel::Geometry || + model == spv::ExecutionModel::TessellationEvaluation || + model == spv::ExecutionModel::RayGenerationKHR || + model == spv::ExecutionModel::IntersectionKHR || + model == spv::ExecutionModel::AnyHitKHR || + model == spv::ExecutionModel::ClosestHitKHR || + model == spv::ExecutionModel::MissKHR) { if (message) { *message = errorVUID + @@ -137,17 +139,17 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, } // Only subset of execution models support Workgroup. - if (value == SpvScopeWorkgroup) { + if (value == spv::Scope::Workgroup) { std::string errorVUID = _.VkErrorID(4637); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelTaskNV && - model != SpvExecutionModelMeshNV && - model != SpvExecutionModelTaskEXT && - model != SpvExecutionModelMeshEXT && - model != SpvExecutionModelTessellationControl && - model != SpvExecutionModelGLCompute) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV && + model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT && + model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::GLCompute) { if (message) { *message = errorVUID + @@ -163,7 +165,7 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, // Vulkan generic rules // Scope for execution must be limited to Workgroup or Subgroup - if (value != SpvScopeWorkgroup && value != SpvScopeSubgroup) { + if (value != spv::Scope::Workgroup && value != spv::Scope::Subgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4636) << spvOpcodeString(opcode) << ": in Vulkan environment Execution Scope is limited to " @@ -177,7 +179,7 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, // Scope for execution must be limited to Workgroup or Subgroup for // non-uniform operations if (spvOpcodeIsNonUniformGroupOperation(opcode) && - value != SpvScopeSubgroup && value != SpvScopeWorkgroup) { + value != spv::Scope::Subgroup && value != spv::Scope::Workgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Execution scope is limited to Subgroup or Workgroup"; @@ -188,10 +190,10 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, uint32_t scope) { - const SpvOp opcode = inst->opcode(); + const spv::Op opcode = inst->opcode(); bool is_int32 = false, is_const_int32 = false; - uint32_t value = 0; - std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); + uint32_t tmp_value = 0; + std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); if (auto error = ValidateScope(_, inst, scope)) { return error; @@ -201,8 +203,10 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, return SPV_SUCCESS; } - if (value == SpvScopeQueueFamilyKHR) { - if (_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { + spv::Scope value = spv::Scope(tmp_value); + + if (value == spv::Scope::QueueFamilyKHR) { + if (_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { return SPV_SUCCESS; } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -212,9 +216,9 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, } } - if (value == SpvScopeDevice && - _.HasCapability(SpvCapabilityVulkanMemoryModelKHR) && - !_.HasCapability(SpvCapabilityVulkanMemoryModelDeviceScopeKHR)) { + if (value == spv::Scope::Device && + _.HasCapability(spv::Capability::VulkanMemoryModelKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelDeviceScopeKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Use of device scope with VulkanKHR memory model requires the " << "VulkanMemoryModelDeviceScopeKHR capability"; @@ -222,18 +226,19 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, // Vulkan Specific rules if (spvIsVulkanEnv(_.context()->target_env)) { - if (value != SpvScopeDevice && value != SpvScopeWorkgroup && - value != SpvScopeSubgroup && value != SpvScopeInvocation && - value != SpvScopeShaderCallKHR && value != SpvScopeQueueFamily) { + if (value != spv::Scope::Device && value != spv::Scope::Workgroup && + value != spv::Scope::Subgroup && value != spv::Scope::Invocation && + value != spv::Scope::ShaderCallKHR && + value != spv::Scope::QueueFamily) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4638) << spvOpcodeString(opcode) << ": in Vulkan environment Memory Scope is limited to Device, " "QueueFamily, Workgroup, ShaderCallKHR, Subgroup, or " "Invocation"; } else if (_.context()->target_env == SPV_ENV_VULKAN_1_0 && - value == SpvScopeSubgroup && - !_.HasCapability(SpvCapabilitySubgroupBallotKHR) && - !_.HasCapability(SpvCapabilitySubgroupVoteKHR)) { + value == spv::Scope::Subgroup && + !_.HasCapability(spv::Capability::SubgroupBallotKHR) && + !_.HasCapability(spv::Capability::SubgroupVoteKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(6997) << spvOpcodeString(opcode) << ": in Vulkan 1.0 environment Memory Scope is can not be " @@ -241,17 +246,17 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, "declared"; } - if (value == SpvScopeShaderCallKHR) { + if (value == spv::Scope::ShaderCallKHR) { std::string errorVUID = _.VkErrorID(4640); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelRayGenerationKHR && - model != SpvExecutionModelIntersectionKHR && - model != SpvExecutionModelAnyHitKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelMissKHR && - model != SpvExecutionModelCallableKHR) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::IntersectionKHR && + model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR && + model != spv::ExecutionModel::CallableKHR) { if (message) { *message = errorVUID + @@ -264,17 +269,17 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, }); } - if (value == SpvScopeWorkgroup) { + if (value == spv::Scope::Workgroup) { std::string errorVUID = _.VkErrorID(7321); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelGLCompute && - model != SpvExecutionModelTessellationControl && - model != SpvExecutionModelTaskNV && - model != SpvExecutionModelMeshNV && - model != SpvExecutionModelTaskEXT && - model != SpvExecutionModelMeshEXT) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::GLCompute && + model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV && + model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT) { if (message) { *message = errorVUID + "Workgroup Memory Scope is limited to MeshNV, " @@ -286,12 +291,12 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, return true; }); - if (_.memory_model() == SpvMemoryModelGLSL450) { + if (_.memory_model() == spv::MemoryModel::GLSL450) { errorVUID = _.VkErrorID(7320); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model == SpvExecutionModelTessellationControl) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model == spv::ExecutionModel::TessellationControl) { if (message) { *message = errorVUID + diff --git a/3rdparty/spirv-tools/source/val/validate_small_type_uses.cpp b/3rdparty/spirv-tools/source/val/validate_small_type_uses.cpp index 9db82e7c7..69f61ee4f 100644 --- a/3rdparty/spirv-tools/source/val/validate_small_type_uses.cpp +++ b/3rdparty/spirv-tools/source/val/validate_small_type_uses.cpp @@ -22,7 +22,7 @@ namespace val { spv_result_t ValidateSmallTypeUses(ValidationState_t& _, const Instruction* inst) { - if (!_.HasCapability(SpvCapabilityShader) || inst->type_id() == 0 || + if (!_.HasCapability(spv::Capability::Shader) || inst->type_id() == 0 || !_.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return SPV_SUCCESS; } @@ -36,13 +36,13 @@ spv_result_t ValidateSmallTypeUses(ValidationState_t& _, for (auto use : inst->uses()) { const auto* user = use.first; switch (user->opcode()) { - case SpvOpDecorate: - case SpvOpDecorateId: - case SpvOpCopyObject: - case SpvOpStore: - case SpvOpFConvert: - case SpvOpUConvert: - case SpvOpSConvert: + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpCopyObject: + case spv::Op::OpStore: + case spv::Op::OpFConvert: + case spv::Op::OpUConvert: + case spv::Op::OpSConvert: break; default: return _.diag(SPV_ERROR_INVALID_ID, user) diff --git a/3rdparty/spirv-tools/source/val/validate_type.cpp b/3rdparty/spirv-tools/source/val/validate_type.cpp index 6b0881cf8..e7adab80f 100644 --- a/3rdparty/spirv-tools/source/val/validate_type.cpp +++ b/3rdparty/spirv-tools/source/val/validate_type.cpp @@ -19,7 +19,6 @@ #include "source/val/instruction.h" #include "source/val/validate.h" #include "source/val/validation_state.h" -#include "spirv/unified1/spirv.h" namespace spvtools { namespace val { @@ -50,8 +49,8 @@ spv_result_t ValidateUniqueness(ValidationState_t& _, const Instruction* inst) { return SPV_SUCCESS; const auto opcode = inst->opcode(); - if (opcode != SpvOpTypeArray && opcode != SpvOpTypeRuntimeArray && - opcode != SpvOpTypeStruct && opcode != SpvOpTypePointer && + if (opcode != spv::Op::OpTypeArray && opcode != spv::Op::OpTypeRuntimeArray && + opcode != spv::Op::OpTypeStruct && opcode != spv::Op::OpTypePointer && !_.RegisterUniqueTypeDeclaration(inst)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Duplicate non-aggregate type declarations are not allowed. " @@ -84,7 +83,7 @@ spv_result_t ValidateTypeInt(ValidationState_t& _, const Instruction* inst) { << "Using a 16-bit integer type requires the Int16 capability," " or an extension that explicitly enables 16-bit integers."; } else if (num_bits == 64) { - if (_.HasCapability(SpvCapabilityInt64)) { + if (_.HasCapability(spv::Capability::Int64)) { return SPV_SUCCESS; } return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -105,7 +104,8 @@ spv_result_t ValidateTypeInt(ValidationState_t& _, const Instruction* inst) { // SPIR-V Spec 2.16.3: Validation Rules for Kernel Capabilities: The // Signedness in OpTypeInt must always be 0. - if (SpvOpTypeInt == inst->opcode() && _.HasCapability(SpvCapabilityKernel) && + if (spv::Op::OpTypeInt == inst->opcode() && + _.HasCapability(spv::Capability::Kernel) && inst->GetOperandAs(2) != 0u) { return _.diag(SPV_ERROR_INVALID_BINARY, inst) << "The Signedness in OpTypeInt " @@ -135,7 +135,7 @@ spv_result_t ValidateTypeFloat(ValidationState_t& _, const Instruction* inst) { " or an extension that explicitly enables 16-bit floating point."; } if (num_bits == 64) { - if (_.HasCapability(SpvCapabilityFloat64)) { + if (_.HasCapability(spv::Capability::Float64)) { return SPV_SUCCESS; } return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -163,7 +163,7 @@ spv_result_t ValidateTypeVector(ValidationState_t& _, const Instruction* inst) { if (num_components == 2 || num_components == 3 || num_components == 4) { return SPV_SUCCESS; } else if (num_components == 8 || num_components == 16) { - if (_.HasCapability(SpvCapabilityVector16)) { + if (_.HasCapability(spv::Capability::Vector16)) { return SPV_SUCCESS; } return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -183,7 +183,7 @@ spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) { const auto column_type_index = 1; const auto column_type_id = inst->GetOperandAs(column_type_index); const auto column_type = _.FindDef(column_type_id); - if (!column_type || SpvOpTypeVector != column_type->opcode()) { + if (!column_type || spv::Op::OpTypeVector != column_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Columns in a matrix must be of type vector."; } @@ -192,7 +192,7 @@ spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) { // Operand 1 is the of the type of data in the vector. const auto comp_type_id = column_type->GetOperandAs(1); auto comp_type_instruction = _.FindDef(comp_type_id); - if (comp_type_instruction->opcode() != SpvOpTypeFloat) { + if (comp_type_instruction->opcode() != spv::Op::OpTypeFloat) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Matrix types can only be " "parameterized with " "floating-point types."; @@ -219,14 +219,14 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { << " is not a type."; } - if (element_type->opcode() == SpvOpTypeVoid) { + if (element_type->opcode() == spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Element Type " << _.getIdName(element_type_id) << " is a void type."; } if (spvIsVulkanEnv(_.context()->target_env) && - element_type->opcode() == SpvOpTypeRuntimeArray) { + element_type->opcode() == spv::Op::OpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "OpTypeArray Element Type " << _.getIdName(element_type_id) << " is not valid in " @@ -246,15 +246,15 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { const auto const_inst = length->words(); const auto const_result_type_index = 1; const auto const_result_type = _.FindDef(const_inst[const_result_type_index]); - if (!const_result_type || SpvOpTypeInt != const_result_type->opcode()) { + if (!const_result_type || spv::Op::OpTypeInt != const_result_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Length " << _.getIdName(length_id) << " is not a constant integer type."; } switch (length->opcode()) { - case SpvOpSpecConstant: - case SpvOpConstant: { + case spv::Op::OpSpecConstant: + case spv::Op::OpConstant: { auto& type_words = const_result_type->words(); const bool is_signed = type_words[3] > 0; const uint32_t width = type_words[2]; @@ -265,11 +265,11 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { << " default value must be at least 1: found " << ivalue; } } break; - case SpvOpConstantNull: + case spv::Op::OpConstantNull: return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Length " << _.getIdName(length_id) << " default value must be at least 1."; - case SpvOpSpecConstantOp: + case spv::Op::OpSpecConstantOp: // Assume it's OK, rather than try to evaluate the operation. break; default: @@ -289,14 +289,14 @@ spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _, << " is not a type."; } - if (element_type->opcode() == SpvOpTypeVoid) { + if (element_type->opcode() == spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeRuntimeArray Element Type " << _.getIdName(element_id) << " is a void type."; } if (spvIsVulkanEnv(_.context()->target_env) && - element_type->opcode() == SpvOpTypeRuntimeArray) { + element_type->opcode() == spv::Op::OpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "OpTypeRuntimeArray Element Type " << _.getIdName(element_id) << " is not valid in " @@ -322,11 +322,11 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { << "OpTypeStruct Member Type " << _.getIdName(member_type_id) << " is not a type."; } - if (member_type->opcode() == SpvOpTypeVoid) { + if (member_type->opcode() == spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Structures cannot contain a void type."; } - if (SpvOpTypeStruct == member_type->opcode() && + if (spv::Op::OpTypeStruct == member_type->opcode() && _.IsStructTypeWithBuiltInMember(member_type_id)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Structure " << _.getIdName(member_type_id) @@ -339,7 +339,7 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env) && - member_type->opcode() == SpvOpTypeRuntimeArray) { + member_type->opcode() == spv::Op::OpTypeRuntimeArray) { const bool is_last_member = member_type_index == inst->operands().size() - 1; if (!is_last_member) { @@ -357,9 +357,10 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) { auto member = inst->word(word_i); auto memberTypeInstr = _.FindDef(member); - if (memberTypeInstr && SpvOpTypeStruct == memberTypeInstr->opcode()) { - if (_.HasDecoration(memberTypeInstr->id(), SpvDecorationBlock) || - _.HasDecoration(memberTypeInstr->id(), SpvDecorationBufferBlock) || + if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) { + if (_.HasDecoration(memberTypeInstr->id(), spv::Decoration::Block) || + _.HasDecoration(memberTypeInstr->id(), + spv::Decoration::BufferBlock) || _.GetHasNestedBlockOrBufferBlockStruct(memberTypeInstr->id())) has_nested_blockOrBufferBlock_struct = true; } @@ -368,8 +369,8 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { _.SetHasNestedBlockOrBufferBlockStruct(inst->id(), has_nested_blockOrBufferBlock_struct); if (_.GetHasNestedBlockOrBufferBlockStruct(inst->id()) && - (_.HasDecoration(inst->id(), SpvDecorationBufferBlock) || - _.HasDecoration(inst->id(), SpvDecorationBlock))) { + (_.HasDecoration(inst->id(), spv::Decoration::BufferBlock) || + _.HasDecoration(inst->id(), spv::Decoration::Block))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "rules: A Block or BufferBlock cannot be nested within another " "Block or BufferBlock. "; @@ -377,7 +378,7 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { std::unordered_set built_in_members; for (auto decoration : _.id_decorations(struct_id)) { - if (decoration.dec_type() == SpvDecorationBuiltIn && + if (decoration.dec_type() == spv::Decoration::BuiltIn && decoration.struct_member_index() != Decoration::kInvalidMember) { built_in_members.insert(decoration.struct_member_index()); } @@ -398,9 +399,9 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { const auto isOpaqueType = [&_](const Instruction* opaque_inst) { auto opcode = opaque_inst->opcode(); - if (_.HasCapability(SpvCapabilityBindlessTextureNV) && - (opcode == SpvOpTypeImage || opcode == SpvOpTypeSampler || - opcode == SpvOpTypeSampledImage)) { + if (_.HasCapability(spv::Capability::BindlessTextureNV) && + (opcode == spv::Op::OpTypeImage || opcode == spv::Op::OpTypeSampler || + opcode == spv::Op::OpTypeSampledImage)) { return false; } else if (spvOpcodeIsBaseOpaqueType(opcode)) { return true; @@ -430,15 +431,15 @@ spv_result_t ValidateTypePointer(ValidationState_t& _, << " is not a type."; } // See if this points to a storage image. - const auto storage_class = inst->GetOperandAs(1); - if (storage_class == SpvStorageClassUniformConstant) { + const auto storage_class = inst->GetOperandAs(1); + if (storage_class == spv::StorageClass::UniformConstant) { // Unpack an optional level of arraying. - if (type->opcode() == SpvOpTypeArray || - type->opcode() == SpvOpTypeRuntimeArray) { + if (type->opcode() == spv::Op::OpTypeArray || + type->opcode() == spv::Op::OpTypeRuntimeArray) { type_id = type->GetOperandAs(1); type = _.FindDef(type_id); } - if (type->opcode() == SpvOpTypeImage) { + if (type->opcode() == spv::Op::OpTypeImage) { const auto sampled = type->GetOperandAs(6); // 2 indicates this image is known to be be used without a sampler, i.e. // a storage image. @@ -475,7 +476,7 @@ spv_result_t ValidateTypeFunction(ValidationState_t& _, << " is not a type."; } - if (param_type->opcode() == SpvOpTypeVoid) { + if (param_type->opcode() == spv::Op::OpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeFunction Parameter Type " << _.getIdName(param_id) << " cannot be OpTypeVoid."; @@ -495,8 +496,9 @@ spv_result_t ValidateTypeFunction(ValidationState_t& _, // decoration instruction. for (auto& pair : inst->uses()) { const auto* use = pair.first; - if (use->opcode() != SpvOpFunction && !spvOpcodeIsDebug(use->opcode()) && - !use->IsNonSemantic() && !spvOpcodeIsDecoration(use->opcode())) { + if (use->opcode() != spv::Op::OpFunction && + !spvOpcodeIsDebug(use->opcode()) && !use->IsNonSemantic() && + !spvOpcodeIsDecoration(use->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, use) << "Invalid use of function type result id " << _.getIdName(inst->id()) << "."; @@ -510,13 +512,13 @@ spv_result_t ValidateTypeForwardPointer(ValidationState_t& _, const Instruction* inst) { const auto pointer_type_id = inst->GetOperandAs(0); const auto pointer_type_inst = _.FindDef(pointer_type_id); - if (pointer_type_inst->opcode() != SpvOpTypePointer) { + if (pointer_type_inst->opcode() != spv::Op::OpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Pointer type in OpTypeForwardPointer is not a pointer type."; } - const auto storage_class = inst->GetOperandAs(1); - if (storage_class != pointer_type_inst->GetOperandAs(1)) { + const auto storage_class = inst->GetOperandAs(1); + if (storage_class != pointer_type_inst->GetOperandAs(1)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Storage class in OpTypeForwardPointer does not match the " << "pointer definition."; @@ -524,13 +526,13 @@ spv_result_t ValidateTypeForwardPointer(ValidationState_t& _, const auto pointee_type_id = pointer_type_inst->GetOperandAs(2); const auto pointee_type = _.FindDef(pointee_type_id); - if (!pointee_type || pointee_type->opcode() != SpvOpTypeStruct) { + if (!pointee_type || pointee_type->opcode() != spv::Op::OpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Forward pointers must point to a structure"; } if (spvIsVulkanEnv(_.context()->target_env)) { - if (storage_class != SpvStorageClassPhysicalStorageBuffer) { + if (storage_class != spv::StorageClass::PhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4711) << "In Vulkan, OpTypeForwardPointer must have " @@ -547,8 +549,8 @@ spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _, const auto component_type_id = inst->GetOperandAs(component_type_index); const auto component_type = _.FindDef(component_type_id); - if (!component_type || (SpvOpTypeFloat != component_type->opcode() && - SpvOpTypeInt != component_type->opcode())) { + if (!component_type || (spv::Op::OpTypeFloat != component_type->opcode() && + spv::Op::OpTypeInt != component_type->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeCooperativeMatrixNV Component Type " << _.getIdName(component_type_id) @@ -591,44 +593,44 @@ spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _, spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) { if (!spvOpcodeGeneratesType(inst->opcode()) && - inst->opcode() != SpvOpTypeForwardPointer) { + inst->opcode() != spv::Op::OpTypeForwardPointer) { return SPV_SUCCESS; } if (auto error = ValidateUniqueness(_, inst)) return error; switch (inst->opcode()) { - case SpvOpTypeInt: + case spv::Op::OpTypeInt: if (auto error = ValidateTypeInt(_, inst)) return error; break; - case SpvOpTypeFloat: + case spv::Op::OpTypeFloat: if (auto error = ValidateTypeFloat(_, inst)) return error; break; - case SpvOpTypeVector: + case spv::Op::OpTypeVector: if (auto error = ValidateTypeVector(_, inst)) return error; break; - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: if (auto error = ValidateTypeMatrix(_, inst)) return error; break; - case SpvOpTypeArray: + case spv::Op::OpTypeArray: if (auto error = ValidateTypeArray(_, inst)) return error; break; - case SpvOpTypeRuntimeArray: + case spv::Op::OpTypeRuntimeArray: if (auto error = ValidateTypeRuntimeArray(_, inst)) return error; break; - case SpvOpTypeStruct: + case spv::Op::OpTypeStruct: if (auto error = ValidateTypeStruct(_, inst)) return error; break; - case SpvOpTypePointer: + case spv::Op::OpTypePointer: if (auto error = ValidateTypePointer(_, inst)) return error; break; - case SpvOpTypeFunction: + case spv::Op::OpTypeFunction: if (auto error = ValidateTypeFunction(_, inst)) return error; break; - case SpvOpTypeForwardPointer: + case spv::Op::OpTypeForwardPointer: if (auto error = ValidateTypeForwardPointer(_, inst)) return error; break; - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixNV: if (auto error = ValidateTypeCooperativeMatrixNV(_, inst)) return error; break; default: diff --git a/3rdparty/spirv-tools/source/val/validation_state.cpp b/3rdparty/spirv-tools/source/val/validation_state.cpp index 64a0a1a37..c95eec366 100644 --- a/3rdparty/spirv-tools/source/val/validation_state.cpp +++ b/3rdparty/spirv-tools/source/val/validation_state.cpp @@ -31,66 +31,66 @@ namespace val { namespace { ModuleLayoutSection InstructionLayoutSection( - ModuleLayoutSection current_section, SpvOp op) { + ModuleLayoutSection current_section, spv::Op op) { // See Section 2.4 if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op)) return kLayoutTypes; switch (op) { - case SpvOpCapability: + case spv::Op::OpCapability: return kLayoutCapabilities; - case SpvOpExtension: + case spv::Op::OpExtension: return kLayoutExtensions; - case SpvOpExtInstImport: + case spv::Op::OpExtInstImport: return kLayoutExtInstImport; - case SpvOpMemoryModel: + case spv::Op::OpMemoryModel: return kLayoutMemoryModel; - case SpvOpEntryPoint: + case spv::Op::OpEntryPoint: return kLayoutEntryPoint; - case SpvOpExecutionMode: - case SpvOpExecutionModeId: + case spv::Op::OpExecutionMode: + case spv::Op::OpExecutionModeId: return kLayoutExecutionMode; - case SpvOpSourceContinued: - case SpvOpSource: - case SpvOpSourceExtension: - case SpvOpString: + case spv::Op::OpSourceContinued: + case spv::Op::OpSource: + case spv::Op::OpSourceExtension: + case spv::Op::OpString: return kLayoutDebug1; - case SpvOpName: - case SpvOpMemberName: + case spv::Op::OpName: + case spv::Op::OpMemberName: return kLayoutDebug2; - case SpvOpModuleProcessed: + case spv::Op::OpModuleProcessed: return kLayoutDebug3; - case SpvOpDecorate: - case SpvOpMemberDecorate: - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: - case SpvOpDecorationGroup: - case SpvOpDecorateId: - case SpvOpDecorateStringGOOGLE: - case SpvOpMemberDecorateStringGOOGLE: + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + case spv::Op::OpDecorationGroup: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: return kLayoutAnnotations; - case SpvOpTypeForwardPointer: + case spv::Op::OpTypeForwardPointer: return kLayoutTypes; - case SpvOpVariable: + case spv::Op::OpVariable: if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; - case SpvOpExtInst: - // SpvOpExtInst is only allowed in types section for certain extended - // instruction sets. This will be checked separately. + case spv::Op::OpExtInst: + // spv::Op::OpExtInst is only allowed in types section for certain + // extended instruction sets. This will be checked separately. if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; - case SpvOpLine: - case SpvOpNoLine: - case SpvOpUndef: + case spv::Op::OpLine: + case spv::Op::OpNoLine: + case spv::Op::OpUndef: if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; - case SpvOpFunction: - case SpvOpFunctionParameter: - case SpvOpFunctionEnd: + case spv::Op::OpFunction: + case spv::Op::OpFunctionParameter: + case spv::Op::OpFunctionEnd: if (current_section == kLayoutFunctionDeclarations) return kLayoutFunctionDeclarations; return kLayoutFunctionDefinitions; - case SpvOpSamplerImageAddressingModeNV: + case spv::Op::OpSamplerImageAddressingModeNV: return kLayoutSamplerImageAddressMode; default: break; @@ -98,7 +98,7 @@ ModuleLayoutSection InstructionLayoutSection( return kLayoutFunctionDefinitions; } -bool IsInstructionInLayoutSection(ModuleLayoutSection layout, SpvOp op) { +bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) { return layout == InstructionLayoutSection(layout, op); } @@ -106,7 +106,9 @@ bool IsInstructionInLayoutSection(ModuleLayoutSection layout, SpvOp op) { spv_result_t CountInstructions(void* user_data, const spv_parsed_instruction_t* inst) { ValidationState_t& _ = *(reinterpret_cast(user_data)); - if (inst->opcode == SpvOpFunction) _.increment_total_functions(); + if (spv::Op(inst->opcode) == spv::Op::OpFunction) { + _.increment_total_functions(); + } _.increment_total_instructions(); return SPV_SUCCESS; @@ -160,8 +162,8 @@ ValidationState_t::ValidationState_t(const spv_const_context ctx, struct_nesting_depth_(), struct_has_nested_blockorbufferblock_struct_(), grammar_(ctx), - addressing_model_(SpvAddressingModelMax), - memory_model_(SpvMemoryModelMax), + addressing_model_(spv::AddressingModel::Max), + memory_model_(spv::MemoryModel::Max), pointer_size_and_alignment_(0), sampler_image_addressing_mode_(0), in_function_(false), @@ -290,13 +292,13 @@ void ValidationState_t::ProgressToNextLayoutSectionOrder() { } } -bool ValidationState_t::IsOpcodeInPreviousLayoutSection(SpvOp op) { +bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op) { ModuleLayoutSection section = InstructionLayoutSection(current_layout_section_, op); return section < current_layout_section_; } -bool ValidationState_t::IsOpcodeInCurrentLayoutSection(SpvOp op) { +bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op) { return IsInstructionInLayoutSection(current_layout_section_, op); } @@ -353,7 +355,7 @@ bool ValidationState_t::in_block() const { module_functions_.back().current_block() != nullptr; } -void ValidationState_t::RegisterCapability(SpvCapability cap) { +void ValidationState_t::RegisterCapability(spv::Capability cap) { // Avoid redundant work. Otherwise the recursion could induce work // quadrdatic in the capability dependency depth. (Ok, not much, but // it's something.) @@ -361,51 +363,51 @@ void ValidationState_t::RegisterCapability(SpvCapability cap) { module_capabilities_.Add(cap); spv_operand_desc desc; - if (SPV_SUCCESS == - grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) { + if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + uint32_t(cap), &desc)) { CapabilitySet(desc->numCapabilities, desc->capabilities) - .ForEach([this](SpvCapability c) { RegisterCapability(c); }); + .ForEach([this](spv::Capability c) { RegisterCapability(c); }); } switch (cap) { - case SpvCapabilityKernel: + case spv::Capability::Kernel: features_.group_ops_reduce_and_scans = true; break; - case SpvCapabilityInt8: + case spv::Capability::Int8: features_.use_int8_type = true; features_.declare_int8_type = true; break; - case SpvCapabilityStorageBuffer8BitAccess: - case SpvCapabilityUniformAndStorageBuffer8BitAccess: - case SpvCapabilityStoragePushConstant8: - case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: + case spv::Capability::StorageBuffer8BitAccess: + case spv::Capability::UniformAndStorageBuffer8BitAccess: + case spv::Capability::StoragePushConstant8: + case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: features_.declare_int8_type = true; break; - case SpvCapabilityInt16: + case spv::Capability::Int16: features_.declare_int16_type = true; break; - case SpvCapabilityFloat16: - case SpvCapabilityFloat16Buffer: + case spv::Capability::Float16: + case spv::Capability::Float16Buffer: features_.declare_float16_type = true; break; - case SpvCapabilityStorageUniformBufferBlock16: - case SpvCapabilityStorageUniform16: - case SpvCapabilityStoragePushConstant16: - case SpvCapabilityStorageInputOutput16: - case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: + case spv::Capability::StorageUniformBufferBlock16: + case spv::Capability::StorageUniform16: + case spv::Capability::StoragePushConstant16: + case spv::Capability::StorageInputOutput16: + case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: features_.declare_int16_type = true; features_.declare_float16_type = true; features_.free_fp_rounding_mode = true; break; - case SpvCapabilityVariablePointers: - case SpvCapabilityVariablePointersStorageBuffer: + case spv::Capability::VariablePointers: + case spv::Capability::VariablePointersStorageBuffer: features_.variable_pointers = true; break; default: // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses - // capability SpvCapabilityRayTracingNV. - // SpvCapabilityRayTracingProvisionalKHR would need the same treatment. - // One of the differences going from SPV_KHR_ray_tracing from + // capability spv::Capability::RayTracingNV. + // spv::Capability::RayTracingProvisionalKHR would need the same + // treatment. One of the differences going from SPV_KHR_ray_tracing from // provisional to final spec was the provisional spec uses Locations // for variables in certain storage classes, just like the // SPV_NV_ray_tracing extension. So it mimics the NVIDIA extension. @@ -454,30 +456,32 @@ bool ValidationState_t::HasAnyOfExtensions( return module_extensions_.HasAnyOf(extensions); } -void ValidationState_t::set_addressing_model(SpvAddressingModel am) { +void ValidationState_t::set_addressing_model(spv::AddressingModel am) { addressing_model_ = am; switch (am) { - case SpvAddressingModelPhysical32: + case spv::AddressingModel::Physical32: pointer_size_and_alignment_ = 4; break; default: // fall through - case SpvAddressingModelPhysical64: - case SpvAddressingModelPhysicalStorageBuffer64: + case spv::AddressingModel::Physical64: + case spv::AddressingModel::PhysicalStorageBuffer64: pointer_size_and_alignment_ = 8; break; } } -SpvAddressingModel ValidationState_t::addressing_model() const { +spv::AddressingModel ValidationState_t::addressing_model() const { return addressing_model_; } -void ValidationState_t::set_memory_model(SpvMemoryModel mm) { +void ValidationState_t::set_memory_model(spv::MemoryModel mm) { memory_model_ = mm; } -SpvMemoryModel ValidationState_t::memory_model() const { return memory_model_; } +spv::MemoryModel ValidationState_t::memory_model() const { + return memory_model_; +} void ValidationState_t::set_samplerimage_variable_address_mode( uint32_t bit_width) { @@ -489,8 +493,8 @@ uint32_t ValidationState_t::samplerimage_variable_address_mode() const { } spv_result_t ValidationState_t::RegisterFunction( - uint32_t id, uint32_t ret_type_id, SpvFunctionControlMask function_control, - uint32_t function_type_id) { + uint32_t id, uint32_t ret_type_id, + spv::FunctionControlMask function_control, uint32_t function_type_id) { assert(in_function_body() == false && "RegisterFunction can only be called when parsing the binary outside " "of another function"); @@ -526,24 +530,24 @@ Instruction* ValidationState_t::AddOrderedInstruction( // Improves diagnostic messages by collecting names of IDs void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) { switch (inst->opcode()) { - case SpvOpName: { + case spv::Op::OpName: { const auto target = inst->GetOperandAs(0); const std::string str = inst->GetOperandAs(1); AssignNameToId(target, str); break; } - case SpvOpMemberName: { + case spv::Op::OpMemberName: { const auto target = inst->GetOperandAs(0); const std::string str = inst->GetOperandAs(2); AssignNameToId(target, str); break; } - case SpvOpSourceContinued: - case SpvOpSource: - case SpvOpSourceExtension: - case SpvOpString: - case SpvOpLine: - case SpvOpNoLine: + case spv::Op::OpSourceContinued: + case spv::Op::OpSource: + case spv::Op::OpSourceExtension: + case spv::Op::OpString: + case spv::Op::OpLine: + case spv::Op::OpNoLine: default: break; } @@ -567,7 +571,7 @@ void ValidationState_t::RegisterInstruction(Instruction* inst) { // should be recorded. The validator will ensure that all usages of an // OpTypeSampledImage and its definition are in the same basic block. if ((SPV_OPERAND_TYPE_ID == operand.type) && - (SpvOpSampledImage == operand_inst->opcode())) { + (spv::Op::OpSampledImage == operand_inst->opcode())) { RegisterSampledImageConsumer(operand_word, inst); } @@ -577,12 +581,12 @@ void ValidationState_t::RegisterInstruction(Instruction* inst) { // Instead just need to register storage class usage for consumers in a // function block. if (inst->function()) { - if (operand_inst->opcode() == SpvOpTypePointer) { + if (operand_inst->opcode() == spv::Op::OpTypePointer) { RegisterStorageClassConsumer( - operand_inst->GetOperandAs(1), inst); - } else if (operand_inst->opcode() == SpvOpVariable) { + operand_inst->GetOperandAs(1), inst); + } else if (operand_inst->opcode() == spv::Op::OpVariable) { RegisterStorageClassConsumer( - operand_inst->GetOperandAs(2), inst); + operand_inst->GetOperandAs(2), inst); } } } @@ -605,21 +609,21 @@ void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id, } void ValidationState_t::RegisterStorageClassConsumer( - SpvStorageClass storage_class, Instruction* consumer) { + spv::StorageClass storage_class, Instruction* consumer) { if (spvIsVulkanEnv(context()->target_env)) { - if (storage_class == SpvStorageClassOutput) { + if (storage_class == spv::StorageClass::Output) { std::string errorVUID = VkErrorID(4644); function(consumer->function()->id()) ->RegisterExecutionModelLimitation([errorVUID]( - SpvExecutionModel model, + spv::ExecutionModel model, std::string* message) { - if (model == SpvExecutionModelGLCompute || - model == SpvExecutionModelRayGenerationKHR || - model == SpvExecutionModelIntersectionKHR || - model == SpvExecutionModelAnyHitKHR || - model == SpvExecutionModelClosestHitKHR || - model == SpvExecutionModelMissKHR || - model == SpvExecutionModelCallableKHR) { + if (model == spv::ExecutionModel::GLCompute || + model == spv::ExecutionModel::RayGenerationKHR || + model == spv::ExecutionModel::IntersectionKHR || + model == spv::ExecutionModel::AnyHitKHR || + model == spv::ExecutionModel::ClosestHitKHR || + model == spv::ExecutionModel::MissKHR || + model == spv::ExecutionModel::CallableKHR) { if (message) { *message = errorVUID + @@ -634,17 +638,17 @@ void ValidationState_t::RegisterStorageClassConsumer( }); } - if (storage_class == SpvStorageClassWorkgroup) { + if (storage_class == spv::StorageClass::Workgroup) { std::string errorVUID = VkErrorID(4645); function(consumer->function()->id()) ->RegisterExecutionModelLimitation([errorVUID]( - SpvExecutionModel model, + spv::ExecutionModel model, std::string* message) { - if (model != SpvExecutionModelGLCompute && - model != SpvExecutionModelTaskNV && - model != SpvExecutionModelMeshNV && - model != SpvExecutionModelTaskEXT && - model != SpvExecutionModelMeshEXT) { + if (model != spv::ExecutionModel::GLCompute && + model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV && + model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT) { if (message) { *message = errorVUID + @@ -658,15 +662,16 @@ void ValidationState_t::RegisterStorageClassConsumer( } } - if (storage_class == SpvStorageClassCallableDataKHR) { + if (storage_class == spv::StorageClass::CallableDataKHR) { std::string errorVUID = VkErrorID(4704); function(consumer->function()->id()) - ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model, - std::string* message) { - if (model != SpvExecutionModelRayGenerationKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelCallableKHR && - model != SpvExecutionModelMissKHR) { + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::CallableKHR && + model != spv::ExecutionModel::MissKHR) { if (message) { *message = errorVUID + "CallableDataKHR Storage Class is limited to " @@ -677,12 +682,13 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == SpvStorageClassIncomingCallableDataKHR) { + } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) { std::string errorVUID = VkErrorID(4705); function(consumer->function()->id()) - ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model, - std::string* message) { - if (model != SpvExecutionModelCallableKHR) { + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::CallableKHR) { if (message) { *message = errorVUID + "IncomingCallableDataKHR Storage Class is limited to " @@ -692,14 +698,15 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == SpvStorageClassRayPayloadKHR) { + } else if (storage_class == spv::StorageClass::RayPayloadKHR) { std::string errorVUID = VkErrorID(4698); function(consumer->function()->id()) - ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model, - std::string* message) { - if (model != SpvExecutionModelRayGenerationKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelMissKHR) { + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { if (message) { *message = errorVUID + @@ -710,14 +717,14 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == SpvStorageClassHitAttributeKHR) { + } else if (storage_class == spv::StorageClass::HitAttributeKHR) { std::string errorVUID = VkErrorID(4701); function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelIntersectionKHR && - model != SpvExecutionModelAnyHitKHR && - model != SpvExecutionModelClosestHitKHR) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::IntersectionKHR && + model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR) { if (message) { *message = errorVUID + "HitAttributeKHR Storage Class is limited to " @@ -728,14 +735,14 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == SpvStorageClassIncomingRayPayloadKHR) { + } else if (storage_class == spv::StorageClass::IncomingRayPayloadKHR) { std::string errorVUID = VkErrorID(4699); function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelAnyHitKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelMissKHR) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { if (message) { *message = errorVUID + @@ -746,17 +753,17 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == SpvStorageClassShaderRecordBufferKHR) { + } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { std::string errorVUID = VkErrorID(7119); function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelRayGenerationKHR && - model != SpvExecutionModelIntersectionKHR && - model != SpvExecutionModelAnyHitKHR && - model != SpvExecutionModelClosestHitKHR && - model != SpvExecutionModelCallableKHR && - model != SpvExecutionModelMissKHR) { + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::IntersectionKHR && + model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::CallableKHR && + model != spv::ExecutionModel::MissKHR) { if (message) { *message = errorVUID + @@ -768,12 +775,12 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == SpvStorageClassTaskPayloadWorkgroupEXT) { + } else if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelTaskEXT && - model != SpvExecutionModelMeshEXT) { + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT) { if (message) { *message = "TaskPayloadWorkgroupEXT Storage Class is limited to " @@ -783,6 +790,22 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); + } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) { + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + "HitObjectAttributeNV Storage Class is limited to " + "RayGenerationKHR, ClosestHitKHR or MissKHR execution model"; + } + return false; + } + return true; + }); } } @@ -814,9 +837,9 @@ uint32_t ValidationState_t::GetTypeId(uint32_t id) const { return inst ? inst->type_id() : 0; } -SpvOp ValidationState_t::GetIdOpcode(uint32_t id) const { +spv::Op ValidationState_t::GetIdOpcode(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst ? inst->opcode() : SpvOpNop; + return inst ? inst->opcode() : spv::Op::OpNop; } uint32_t ValidationState_t::GetComponentType(uint32_t id) const { @@ -824,18 +847,18 @@ uint32_t ValidationState_t::GetComponentType(uint32_t id) const { assert(inst); switch (inst->opcode()) { - case SpvOpTypeFloat: - case SpvOpTypeInt: - case SpvOpTypeBool: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeBool: return id; - case SpvOpTypeVector: + case spv::Op::OpTypeVector: return inst->word(2); - case SpvOpTypeMatrix: + case spv::Op::OpTypeMatrix: return GetComponentType(inst->word(2)); - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixNV: return inst->word(2); default: @@ -853,16 +876,16 @@ uint32_t ValidationState_t::GetDimension(uint32_t id) const { assert(inst); switch (inst->opcode()) { - case SpvOpTypeFloat: - case SpvOpTypeInt: - case SpvOpTypeBool: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeBool: return 1; - case SpvOpTypeVector: - case SpvOpTypeMatrix: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: return inst->word(3); - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixNV: // Actual dimension isn't known, return 0 return 0; @@ -881,10 +904,11 @@ uint32_t ValidationState_t::GetBitWidth(uint32_t id) const { const Instruction* inst = FindDef(component_type_id); assert(inst); - if (inst->opcode() == SpvOpTypeFloat || inst->opcode() == SpvOpTypeInt) + if (inst->opcode() == spv::Op::OpTypeFloat || + inst->opcode() == spv::Op::OpTypeInt) return inst->word(2); - if (inst->opcode() == SpvOpTypeBool) return 1; + if (inst->opcode() == spv::Op::OpTypeBool) return 1; assert(0); return 0; @@ -892,12 +916,12 @@ uint32_t ValidationState_t::GetBitWidth(uint32_t id) const { bool ValidationState_t::IsVoidType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeVoid; + return inst && inst->opcode() == spv::Op::OpTypeVoid; } bool ValidationState_t::IsFloatScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeFloat; + return inst && inst->opcode() == spv::Op::OpTypeFloat; } bool ValidationState_t::IsFloatVectorType(uint32_t id) const { @@ -906,7 +930,7 @@ bool ValidationState_t::IsFloatVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsFloatScalarType(GetComponentType(id)); } @@ -919,11 +943,11 @@ bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeFloat) { + if (inst->opcode() == spv::Op::OpTypeFloat) { return true; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsFloatScalarType(GetComponentType(id)); } @@ -932,7 +956,7 @@ bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const { bool ValidationState_t::IsIntScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeInt; + return inst && inst->opcode() == spv::Op::OpTypeInt; } bool ValidationState_t::IsIntVectorType(uint32_t id) const { @@ -941,7 +965,7 @@ bool ValidationState_t::IsIntVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsIntScalarType(GetComponentType(id)); } @@ -954,11 +978,11 @@ bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeInt) { + if (inst->opcode() == spv::Op::OpTypeInt) { return true; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsIntScalarType(GetComponentType(id)); } @@ -967,7 +991,7 @@ bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const { bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeInt && inst->word(3) == 0; + return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 0; } bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { @@ -976,7 +1000,7 @@ bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsUnsignedIntScalarType(GetComponentType(id)); } @@ -985,7 +1009,7 @@ bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeInt && inst->word(3) == 1; + return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 1; } bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { @@ -994,7 +1018,7 @@ bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsSignedIntScalarType(GetComponentType(id)); } @@ -1003,7 +1027,7 @@ bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { bool ValidationState_t::IsBoolScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeBool; + return inst && inst->opcode() == spv::Op::OpTypeBool; } bool ValidationState_t::IsBoolVectorType(uint32_t id) const { @@ -1012,7 +1036,7 @@ bool ValidationState_t::IsBoolVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsBoolScalarType(GetComponentType(id)); } @@ -1025,11 +1049,11 @@ bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeBool) { + if (inst->opcode() == spv::Op::OpTypeBool) { return true; } - if (inst->opcode() == SpvOpTypeVector) { + if (inst->opcode() == spv::Op::OpTypeVector) { return IsBoolScalarType(GetComponentType(id)); } @@ -1042,7 +1066,7 @@ bool ValidationState_t::IsFloatMatrixType(uint32_t id) const { return false; } - if (inst->opcode() == SpvOpTypeMatrix) { + if (inst->opcode() == spv::Op::OpTypeMatrix) { return IsFloatScalarType(GetComponentType(id)); } @@ -1057,13 +1081,13 @@ bool ValidationState_t::GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, const Instruction* mat_inst = FindDef(id); assert(mat_inst); - if (mat_inst->opcode() != SpvOpTypeMatrix) return false; + if (mat_inst->opcode() != spv::Op::OpTypeMatrix) return false; const uint32_t vec_type = mat_inst->word(2); const Instruction* vec_inst = FindDef(vec_type); assert(vec_inst); - if (vec_inst->opcode() != SpvOpTypeVector) { + if (vec_inst->opcode() != spv::Op::OpTypeVector) { assert(0); return false; } @@ -1083,7 +1107,7 @@ bool ValidationState_t::GetStructMemberTypes( const Instruction* inst = FindDef(struct_type_id); assert(inst); - if (inst->opcode() != SpvOpTypeStruct) return false; + if (inst->opcode() != spv::Op::OpTypeStruct) return false; *member_types = std::vector(inst->words().cbegin() + 2, inst->words().cend()); @@ -1095,30 +1119,31 @@ bool ValidationState_t::GetStructMemberTypes( bool ValidationState_t::IsPointerType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypePointer; + return inst && inst->opcode() == spv::Op::OpTypePointer; } -bool ValidationState_t::GetPointerTypeInfo(uint32_t id, uint32_t* data_type, - uint32_t* storage_class) const { +bool ValidationState_t::GetPointerTypeInfo( + uint32_t id, uint32_t* data_type, spv::StorageClass* storage_class) const { + *storage_class = spv::StorageClass::Max; if (!id) return false; const Instruction* inst = FindDef(id); assert(inst); - if (inst->opcode() != SpvOpTypePointer) return false; + if (inst->opcode() != spv::Op::OpTypePointer) return false; - *storage_class = inst->word(2); + *storage_class = spv::StorageClass(inst->word(2)); *data_type = inst->word(3); return true; } bool ValidationState_t::IsAccelerationStructureType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeAccelerationStructureKHR; + return inst && inst->opcode() == spv::Op::OpTypeAccelerationStructureKHR; } bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == SpvOpTypeCooperativeMatrixNV; + return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV; } bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const { @@ -1148,8 +1173,8 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( const auto m1_type = FindDef(m1); const auto m2_type = FindDef(m2); - if (m1_type->opcode() != SpvOpTypeCooperativeMatrixNV || - m2_type->opcode() != SpvOpTypeCooperativeMatrixNV) { + if (m1_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV || + m2_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { return diag(SPV_ERROR_INVALID_DATA, inst) << "Expected cooperative matrix types"; } @@ -1214,7 +1239,8 @@ bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const { return false; } - if (inst->opcode() != SpvOpConstant && inst->opcode() != SpvOpSpecConstant) + if (inst->opcode() != spv::Op::OpConstant && + inst->opcode() != spv::Op::OpSpecConstant) return false; if (!IsIntScalarType(inst->type_id())) return false; @@ -1246,7 +1272,7 @@ std::tuple ValidationState_t::EvalInt32IfConst( return std::make_tuple(true, false, 0); } - if (inst->opcode() == SpvOpConstantNull) { + if (inst->opcode() == spv::Op::OpConstantNull) { return std::make_tuple(true, true, 0); } @@ -1380,7 +1406,7 @@ bool ValidationState_t::LogicallyMatch(const Instruction* lhs, } } - if (lhs->opcode() == SpvOpTypeArray) { + if (lhs->opcode() == spv::Op::OpTypeArray) { // Size operands must match. if (lhs->GetOperandAs(2u) != rhs->GetOperandAs(2u)) { return false; @@ -1399,7 +1425,7 @@ bool ValidationState_t::LogicallyMatch(const Instruction* lhs, return false; } return LogicallyMatch(lhs_ele, rhs_ele, check_decorations); - } else if (lhs->opcode() == SpvOpTypeStruct) { + } else if (lhs->opcode() == spv::Op::OpTypeStruct) { // Number of elements must match. if (lhs->operands().size() != rhs->operands().size()) { return false; @@ -1437,11 +1463,11 @@ bool ValidationState_t::LogicallyMatch(const Instruction* lhs, const Instruction* ValidationState_t::TracePointer( const Instruction* inst) const { auto base_ptr = inst; - while (base_ptr->opcode() == SpvOpAccessChain || - base_ptr->opcode() == SpvOpInBoundsAccessChain || - base_ptr->opcode() == SpvOpPtrAccessChain || - base_ptr->opcode() == SpvOpInBoundsPtrAccessChain || - base_ptr->opcode() == SpvOpCopyObject) { + while (base_ptr->opcode() == spv::Op::OpAccessChain || + base_ptr->opcode() == spv::Op::OpInBoundsAccessChain || + base_ptr->opcode() == spv::Op::OpPtrAccessChain || + base_ptr->opcode() == spv::Op::OpInBoundsPtrAccessChain || + base_ptr->opcode() == spv::Op::OpCopyObject) { base_ptr = FindDef(base_ptr->GetOperandAs(2u)); } return base_ptr; @@ -1456,25 +1482,25 @@ bool ValidationState_t::ContainsType( if (f(inst)) return true; switch (inst->opcode()) { - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeImage: - case SpvOpTypeSampledImage: - case SpvOpTypeCooperativeMatrixNV: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeCooperativeMatrixNV: return ContainsType(inst->GetOperandAs(1u), f, traverse_all_types); - case SpvOpTypePointer: + case spv::Op::OpTypePointer: if (IsForwardPointer(id)) return false; if (traverse_all_types) { return ContainsType(inst->GetOperandAs(2u), f, traverse_all_types); } break; - case SpvOpTypeFunction: - case SpvOpTypeStruct: - if (inst->opcode() == SpvOpTypeFunction && !traverse_all_types) { + case spv::Op::OpTypeFunction: + case spv::Op::OpTypeStruct: + if (inst->opcode() == spv::Op::OpTypeFunction && !traverse_all_types) { return false; } for (uint32_t i = 1; i < inst->operands().size(); ++i) { @@ -1491,9 +1517,9 @@ bool ValidationState_t::ContainsType( return false; } -bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type, +bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, uint32_t width) const { - if (type != SpvOpTypeInt && type != SpvOpTypeFloat) return false; + if (type != spv::Op::OpTypeInt && type != spv::Op::OpTypeFloat) return false; const auto f = [type, width](const Instruction* inst) { if (inst->opcode() == type) { @@ -1505,12 +1531,12 @@ bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type, } bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { - if ((!HasCapability(SpvCapabilityInt16) && - ContainsSizedIntOrFloatType(id, SpvOpTypeInt, 16)) || - (!HasCapability(SpvCapabilityInt8) && - ContainsSizedIntOrFloatType(id, SpvOpTypeInt, 8)) || - (!HasCapability(SpvCapabilityFloat16) && - ContainsSizedIntOrFloatType(id, SpvOpTypeFloat, 16))) { + if ((!HasCapability(spv::Capability::Int16) && + ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 16)) || + (!HasCapability(spv::Capability::Int8) && + ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 8)) || + (!HasCapability(spv::Capability::Float16) && + ContainsSizedIntOrFloatType(id, spv::Op::OpTypeFloat, 16))) { return true; } return false; @@ -1518,33 +1544,34 @@ bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const { const auto f = [](const Instruction* inst) { - return inst->opcode() == SpvOpTypeRuntimeArray; + return inst->opcode() == spv::Op::OpTypeRuntimeArray; }; return ContainsType(id, f, /* traverse_all_types = */ false); } bool ValidationState_t::IsValidStorageClass( - SpvStorageClass storage_class) const { + spv::StorageClass storage_class) const { if (spvIsVulkanEnv(context()->target_env)) { switch (storage_class) { - case SpvStorageClassUniformConstant: - case SpvStorageClassUniform: - case SpvStorageClassStorageBuffer: - case SpvStorageClassInput: - case SpvStorageClassOutput: - case SpvStorageClassImage: - case SpvStorageClassWorkgroup: - case SpvStorageClassPrivate: - case SpvStorageClassFunction: - case SpvStorageClassPushConstant: - case SpvStorageClassPhysicalStorageBuffer: - case SpvStorageClassRayPayloadKHR: - case SpvStorageClassIncomingRayPayloadKHR: - case SpvStorageClassHitAttributeKHR: - case SpvStorageClassCallableDataKHR: - case SpvStorageClassIncomingCallableDataKHR: - case SpvStorageClassShaderRecordBufferKHR: - case SpvStorageClassTaskPayloadWorkgroupEXT: + case spv::StorageClass::UniformConstant: + case spv::StorageClass::Uniform: + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::Input: + case spv::StorageClass::Output: + case spv::StorageClass::Image: + case spv::StorageClass::Workgroup: + case spv::StorageClass::Private: + case spv::StorageClass::Function: + case spv::StorageClass::PushConstant: + case spv::StorageClass::PhysicalStorageBuffer: + case spv::StorageClass::RayPayloadKHR: + case spv::StorageClass::IncomingRayPayloadKHR: + case spv::StorageClass::HitAttributeKHR: + case spv::StorageClass::CallableDataKHR: + case spv::StorageClass::IncomingCallableDataKHR: + case spv::StorageClass::ShaderRecordBufferKHR: + case spv::StorageClass::TaskPayloadWorkgroupEXT: + case spv::StorageClass::HitObjectAttributeNV: return true; default: return false; @@ -2150,6 +2177,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-Base-07651); case 7652: return VUID_WRAP(VUID-StandaloneSpirv-Base-07652); + case 7703: + return VUID_WRAP(VUID-StandaloneSpirv-Component-07703); default: return ""; // unknown id } diff --git a/3rdparty/spirv-tools/source/val/validation_state.h b/3rdparty/spirv-tools/source/val/validation_state.h index 1b599ff35..4d5ac0061 100644 --- a/3rdparty/spirv-tools/source/val/validation_state.h +++ b/3rdparty/spirv-tools/source/val/validation_state.h @@ -185,10 +185,10 @@ class ValidationState_t { void ProgressToNextLayoutSectionOrder(); /// Determines if the op instruction is in a previous layout section - bool IsOpcodeInPreviousLayoutSection(SpvOp op); + bool IsOpcodeInPreviousLayoutSection(spv::Op op); /// Determines if the op instruction is part of the current section - bool IsOpcodeInCurrentLayoutSection(SpvOp op); + bool IsOpcodeInCurrentLayoutSection(spv::Op op); DiagnosticStream diag(spv_result_t error_code, const Instruction* inst); @@ -217,7 +217,8 @@ class ValidationState_t { }; /// Registers |id| as an entry point with |execution_model| and |interfaces|. - void RegisterEntryPoint(const uint32_t id, SpvExecutionModel execution_model, + void RegisterEntryPoint(const uint32_t id, + spv::ExecutionModel execution_model, EntryPointDescription&& desc) { entry_points_.push_back(id); entry_point_to_execution_models_[id].insert(execution_model); @@ -235,7 +236,7 @@ class ValidationState_t { /// Registers execution mode for the given entry point. void RegisterExecutionModeForEntryPoint(uint32_t entry_point, - SpvExecutionMode execution_mode) { + spv::ExecutionMode execution_mode) { entry_point_to_execution_modes_[entry_point].insert(execution_mode); } @@ -247,7 +248,7 @@ class ValidationState_t { /// Returns Execution Models for the given Entry Point. /// Returns nullptr if none found (would trigger assertion). - const std::set* GetExecutionModels( + const std::set* GetExecutionModels( uint32_t entry_point) const { const auto it = entry_point_to_execution_models_.find(entry_point); if (it == entry_point_to_execution_models_.end()) { @@ -259,7 +260,7 @@ class ValidationState_t { /// Returns Execution Modes for the given Entry Point. /// Returns nullptr if none found. - const std::set* GetExecutionModes( + const std::set* GetExecutionModes( uint32_t entry_point) const { const auto it = entry_point_to_execution_modes_.find(entry_point); if (it == entry_point_to_execution_modes_.end()) { @@ -300,7 +301,7 @@ class ValidationState_t { return (id_to_function_.find(id) != id_to_function_.end()); } /// Registers the capability and its dependent capabilities - void RegisterCapability(SpvCapability cap); + void RegisterCapability(spv::Capability cap); /// Registers the extension. void RegisterExtension(Extension ext); @@ -308,14 +309,14 @@ class ValidationState_t { /// Registers the function in the module. Subsequent instructions will be /// called against this function spv_result_t RegisterFunction(uint32_t id, uint32_t ret_type_id, - SpvFunctionControlMask function_control, + spv::FunctionControlMask function_control, uint32_t function_type_id); /// Register a function end instruction spv_result_t RegisterFunctionEnd(); /// Returns true if the capability is enabled in the module. - bool HasCapability(SpvCapability cap) const { + bool HasCapability(spv::Capability cap) const { return module_capabilities_.Contains(cap); } @@ -339,16 +340,16 @@ class ValidationState_t { bool HasAnyOfExtensions(const ExtensionSet& extensions) const; /// Sets the addressing model of this module (logical/physical). - void set_addressing_model(SpvAddressingModel am); + void set_addressing_model(spv::AddressingModel am); /// Returns true if the OpMemoryModel was found. bool has_memory_model_specified() const { - return addressing_model_ != SpvAddressingModelMax && - memory_model_ != SpvMemoryModelMax; + return addressing_model_ != spv::AddressingModel::Max && + memory_model_ != spv::MemoryModel::Max; } /// Returns the addressing model of this module, or Logical if uninitialized. - SpvAddressingModel addressing_model() const; + spv::AddressingModel addressing_model() const; /// Returns the addressing model of this module, or Logical if uninitialized. uint32_t pointer_size_and_alignment() const { @@ -356,10 +357,10 @@ class ValidationState_t { } /// Sets the memory model of this module. - void set_memory_model(SpvMemoryModel mm); + void set_memory_model(spv::MemoryModel mm); /// Returns the memory model of this module, or Simple if uninitialized. - SpvMemoryModel memory_model() const; + spv::MemoryModel memory_model() const; /// Sets the bit width for sampler/image type variables. If not set, they are /// considered opaque @@ -432,8 +433,8 @@ class ValidationState_t { // The decorations are sorted by member_index, so this look up will give the // exact range of decorations for this member index. - Decoration min_decoration((SpvDecoration)0, {}, member_index); - Decoration max_decoration(SpvDecorationMax, {}, member_index); + Decoration min_decoration((spv::Decoration)0, {}, member_index); + Decoration max_decoration(spv::Decoration::Max, {}, member_index); FieldDecorationsIter result; result.begin = decorations.lower_bound(min_decoration); @@ -449,7 +450,7 @@ class ValidationState_t { /// Returns true if the given id has the given decoration , /// otherwise returns false. - bool HasDecoration(uint32_t id, SpvDecoration dec) { + bool HasDecoration(uint32_t id, spv::Decoration dec) { const auto& decorations = id_decorations_.find(id); if (decorations == id_decorations_.end()) return false; @@ -485,7 +486,7 @@ class ValidationState_t { Instruction* consumer); // Record a function's storage class consumer instruction - void RegisterStorageClassConsumer(SpvStorageClass storage_class, + void RegisterStorageClassConsumer(spv::StorageClass storage_class, Instruction* consumer); /// Returns the set of Global Variables. @@ -616,7 +617,7 @@ class ValidationState_t { // Returns true if |id| is a type id that contains |type| (or integer or // floating point type) of |width| bits. - bool ContainsSizedIntOrFloatType(uint32_t id, SpvOp type, + bool ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, uint32_t width) const; // Returns true if |id| is a type id that contains a 8- or 16-bit int or // 16-bit float that is not generally enabled for use. @@ -642,7 +643,7 @@ class ValidationState_t { // Returns opcode of the instruction which issued the id or OpNop if the // instruction is not registered. - SpvOp GetIdOpcode(uint32_t id) const; + spv::Op GetIdOpcode(uint32_t id) const; // Returns type_id for given id operand if it has a type or zero otherwise. // |operand_index| is expected to be pointing towards an operand which is an @@ -652,7 +653,7 @@ class ValidationState_t { // Provides information on pointer type. Returns false iff not pointer type. bool GetPointerTypeInfo(uint32_t id, uint32_t* data_type, - uint32_t* storage_class) const; + spv::StorageClass* storage_class) const; // Is the ID the type of a pointer to a uniform block: Block-decorated struct // in uniform storage class? The result is only valid after internal method @@ -732,6 +733,9 @@ class ValidationState_t { } return std::string(desc->name); } + std::string SpvDecorationString(spv::Decoration decoration) { + return SpvDecorationString(uint32_t(decoration)); + } // Returns whether type m1 and type m2 are cooperative matrices with // the same "shape" (matching scope, rows, cols). If any are specialization @@ -764,7 +768,7 @@ class ValidationState_t { const Instruction* TracePointer(const Instruction* inst) const; // Validates the storage class for the target environment. - bool IsValidStorageClass(SpvStorageClass storage_class) const; + bool IsValidStorageClass(spv::StorageClass storage_class) const; // Takes a Vulkan Valid Usage ID (VUID) as |id| and optional |reference| and // will return a non-empty string only if ID is known and targeting Vulkan. @@ -883,8 +887,8 @@ class ValidationState_t { AssemblyGrammar grammar_; - SpvAddressingModel addressing_model_; - SpvMemoryModel memory_model_; + spv::AddressingModel addressing_model_; + spv::MemoryModel memory_model_; // pointer size derived from addressing model. Assumes all storage classes // have the same pointer size (for physical pointer types). uint32_t pointer_size_and_alignment_; @@ -905,11 +909,11 @@ class ValidationState_t { /// Mapping entry point -> execution models. It is presumed that the same /// function could theoretically be used as 'main' by multiple OpEntryPoint /// instructions. - std::unordered_map> + std::unordered_map> entry_point_to_execution_models_; /// Mapping entry point -> execution modes. - std::unordered_map> + std::unordered_map> entry_point_to_execution_modes_; /// Mapping function -> array of entry points inside this