Updated spirv-tools.

This commit is contained in:
Бранимир Караџић
2025-02-08 17:24:36 -08:00
parent a4cd9d8b5b
commit 1687187482
48 changed files with 2002 additions and 322 deletions

View File

@@ -1 +1 @@
"v2024.4", "SPIRV-Tools v2024.4 v2024.4.rc2-10-g7812970d"
"v2024.4", "SPIRV-Tools v2024.4 v2024.4.rc2-55-g2fc78cee"

View File

@@ -30,6 +30,8 @@ static const spv::Capability pygen_variable_caps_CooperativeMatrixNV[] = {spv::C
static const spv::Capability pygen_variable_caps_CooperativeMatrixPerElementOperationsNV[] = {spv::Capability::CooperativeMatrixPerElementOperationsNV};
static const spv::Capability pygen_variable_caps_CooperativeMatrixReductionsNV[] = {spv::Capability::CooperativeMatrixReductionsNV};
static const spv::Capability pygen_variable_caps_CooperativeMatrixTensorAddressingNV[] = {spv::Capability::CooperativeMatrixTensorAddressingNV};
static const spv::Capability pygen_variable_caps_CooperativeVectorNV[] = {spv::Capability::CooperativeVectorNV};
static const spv::Capability pygen_variable_caps_CooperativeVectorTrainingNV[] = {spv::Capability::CooperativeVectorTrainingNV};
static const spv::Capability pygen_variable_caps_DemoteToHelperInvocation[] = {spv::Capability::DemoteToHelperInvocation};
static const spv::Capability pygen_variable_caps_DerivativeControl[] = {spv::Capability::DerivativeControl};
static const spv::Capability pygen_variable_caps_DeviceEnqueue[] = {spv::Capability::DeviceEnqueue};
@@ -72,12 +74,15 @@ static const spv::Capability pygen_variable_caps_QuadControlKHR[] = {spv::Capabi
static const spv::Capability pygen_variable_caps_RawAccessChainsNV[] = {spv::Capability::RawAccessChainsNV};
static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR};
static const spv::Capability pygen_variable_caps_RayQueryPositionFetchKHR[] = {spv::Capability::RayQueryPositionFetchKHR};
static const spv::Capability pygen_variable_caps_RayTracingClusterAccelerationStructureNV[] = {spv::Capability::RayTracingClusterAccelerationStructureNV};
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_RayTracingLinearSweptSpheresGeometryNV[] = {spv::Capability::RayTracingLinearSweptSpheresGeometryNV};
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_RayTracingSpheresGeometryNV[] = {spv::Capability::RayTracingSpheresGeometryNV};
static const spv::Capability pygen_variable_caps_ReplicatedCompositesEXT[] = {spv::Capability::ReplicatedCompositesEXT};
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};
@@ -87,6 +92,9 @@ static const spv::Capability pygen_variable_caps_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_Subgroup2DBlockIOINTEL[] = {spv::Capability::Subgroup2DBlockIOINTEL};
static const spv::Capability pygen_variable_caps_Subgroup2DBlockTransformINTEL[] = {spv::Capability::Subgroup2DBlockTransformINTEL};
static const spv::Capability pygen_variable_caps_Subgroup2DBlockTransposeINTEL[] = {spv::Capability::Subgroup2DBlockTransposeINTEL};
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};
@@ -96,6 +104,7 @@ static const spv::Capability pygen_variable_caps_SubgroupBufferPrefetchINTEL[] =
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_SubgroupMatrixMultiplyAccumulateINTEL[] = {spv::Capability::SubgroupMatrixMultiplyAccumulateINTEL};
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_TensorAddressingNV[] = {spv::Capability::TensorAddressingNV};
@@ -596,6 +605,11 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"ReorderThreadWithHintNV", spv::Op::OpReorderThreadWithHintNV, 0, nullptr, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeHitObjectNV", spv::Op::OpTypeHitObjectNV, 0, nullptr, 1, pygen_variable_caps_ShaderInvocationReorderNV, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ImageSampleFootprintNV", spv::Op::OpImageSampleFootprintNV, 0, nullptr, 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},
{"TypeCooperativeVectorNV", spv::Op::OpTypeCooperativeVectorNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorNV, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorMatrixMulNV", spv::Op::OpCooperativeVectorMatrixMulNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorNV, 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_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorOuterProductAccumulateNV", spv::Op::OpCooperativeVectorOuterProductAccumulateNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorTrainingNV, 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_OPTIONAL_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorReduceSumAccumulateNV", spv::Op::OpCooperativeVectorReduceSumAccumulateNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorTrainingNV, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorMatrixMulAddNV", spv::Op::OpCooperativeVectorMatrixMulAddNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorNV, 16, {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, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixConvertNV", spv::Op::OpCooperativeMatrixConvertNV, 0, nullptr, 1, pygen_variable_caps_CooperativeMatrixConversionsNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"EmitMeshTasksEXT", spv::Op::OpEmitMeshTasksEXT, 0, nullptr, 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, 0, nullptr, 1, pygen_variable_caps_MeshShadingEXT, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
@@ -603,6 +617,8 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"WritePackedPrimitiveIndices4x8NV", spv::Op::OpWritePackedPrimitiveIndices4x8NV, 0, nullptr, 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},
{"FetchMicroTriangleVertexPositionNV", spv::Op::OpFetchMicroTriangleVertexPositionNV, 0, nullptr, 1, pygen_variable_caps_DisplacementMicromapNV, 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},
{"FetchMicroTriangleVertexBarycentricNV", spv::Op::OpFetchMicroTriangleVertexBarycentricNV, 0, nullptr, 1, pygen_variable_caps_DisplacementMicromapNV, 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},
{"CooperativeVectorLoadNV", spv::Op::OpCooperativeVectorLoadNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorNV, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorStoreNV", spv::Op::OpCooperativeVectorStoreNV, 0, nullptr, 1, pygen_variable_caps_CooperativeVectorNV, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ReportIntersectionKHR", spv::Op::OpReportIntersectionKHR, 1, pygen_variable_aliases_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, 0, nullptr, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TerminateRayNV", spv::Op::OpTerminateRayNV, 0, nullptr, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
@@ -612,6 +628,8 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"RayQueryGetIntersectionTriangleVertexPositionsKHR", spv::Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR, 0, nullptr, 1, pygen_variable_caps_RayQueryPositionFetchKHR, 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},
{"TypeAccelerationStructureKHR", spv::Op::OpTypeAccelerationStructureKHR, 1, pygen_variable_aliases_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, 0, nullptr, 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},
{"RayQueryGetClusterIdNV", spv::Op::OpRayQueryGetClusterIdNV, 0, nullptr, 1, pygen_variable_caps_RayTracingClusterAccelerationStructureNV, 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},
{"HitObjectGetClusterIdNV", spv::Op::OpHitObjectGetClusterIdNV, 0, nullptr, 1, pygen_variable_caps_RayTracingClusterAccelerationStructureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeCooperativeMatrixNV", spv::Op::OpTypeCooperativeMatrixNV, 0, nullptr, 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, 0, nullptr, 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, 0, nullptr, 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},
@@ -646,6 +664,19 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"ConvertSampledImageToUNV", spv::Op::OpConvertSampledImageToUNV, 0, nullptr, 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, 0, nullptr, 1, pygen_variable_caps_BindlessTextureNV, 1, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"RawAccessChainNV", spv::Op::OpRawAccessChainNV, 0, nullptr, 1, pygen_variable_caps_RawAccessChainsNV, 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_RAW_ACCESS_CHAIN_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"RayQueryGetIntersectionSpherePositionNV", spv::Op::OpRayQueryGetIntersectionSpherePositionNV, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 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},
{"RayQueryGetIntersectionSphereRadiusNV", spv::Op::OpRayQueryGetIntersectionSphereRadiusNV, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 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},
{"RayQueryGetIntersectionLSSPositionsNV", spv::Op::OpRayQueryGetIntersectionLSSPositionsNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 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},
{"RayQueryGetIntersectionLSSRadiiNV", spv::Op::OpRayQueryGetIntersectionLSSRadiiNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 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},
{"RayQueryGetIntersectionLSSHitValueNV", spv::Op::OpRayQueryGetIntersectionLSSHitValueNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 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},
{"HitObjectGetSpherePositionNV", spv::Op::OpHitObjectGetSpherePositionNV, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"HitObjectGetSphereRadiusNV", spv::Op::OpHitObjectGetSphereRadiusNV, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"HitObjectGetLSSPositionsNV", spv::Op::OpHitObjectGetLSSPositionsNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"HitObjectGetLSSRadiiNV", spv::Op::OpHitObjectGetLSSRadiiNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"HitObjectIsSphereHitNV", spv::Op::OpHitObjectIsSphereHitNV, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"HitObjectIsLSSHitNV", spv::Op::OpHitObjectIsLSSHitNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"RayQueryIsSphereHitNV", spv::Op::OpRayQueryIsSphereHitNV, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 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},
{"RayQueryIsLSSHitNV", spv::Op::OpRayQueryIsLSSHitNV, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 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},
{"SubgroupShuffleINTEL", spv::Op::OpSubgroupShuffleINTEL, 0, nullptr, 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, 0, nullptr, 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, 0, nullptr, 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},
@@ -672,7 +703,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"UMul32x16INTEL", spv::Op::OpUMul32x16INTEL, 0, nullptr, 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, 0, nullptr, 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, 0, nullptr, 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, 0, nullptr, 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},
{"AsmTargetINTEL", spv::Op::OpAsmTargetINTEL, 0, nullptr, 1, pygen_variable_caps_AsmINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"AsmINTEL", spv::Op::OpAsmINTEL, 0, nullptr, 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, 0, nullptr, 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, 0, nullptr, 4, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXTAtomicFloat16VectorNV, 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},
@@ -892,6 +923,12 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"ControlBarrierWaitINTEL", spv::Op::OpControlBarrierWaitINTEL, 0, nullptr, 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},
{"ArithmeticFenceEXT", spv::Op::OpArithmeticFenceEXT, 0, nullptr, 1, pygen_variable_caps_ArithmeticFenceEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupBlockPrefetchINTEL", spv::Op::OpSubgroupBlockPrefetchINTEL, 0, nullptr, 1, pygen_variable_caps_SubgroupBufferPrefetchINTEL, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"Subgroup2DBlockLoadINTEL", spv::Op::OpSubgroup2DBlockLoadINTEL, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockIOINTEL, 10, {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},
{"Subgroup2DBlockLoadTransformINTEL", spv::Op::OpSubgroup2DBlockLoadTransformINTEL, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockTransformINTEL, 10, {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},
{"Subgroup2DBlockLoadTransposeINTEL", spv::Op::OpSubgroup2DBlockLoadTransposeINTEL, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockTransposeINTEL, 10, {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},
{"Subgroup2DBlockPrefetchINTEL", spv::Op::OpSubgroup2DBlockPrefetchINTEL, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockIOINTEL, 9, {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},
{"Subgroup2DBlockStoreINTEL", spv::Op::OpSubgroup2DBlockStoreINTEL, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockIOINTEL, 10, {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},
{"SubgroupMatrixMultiplyAccumulateINTEL", spv::Op::OpSubgroupMatrixMultiplyAccumulateINTEL, 0, nullptr, 1, pygen_variable_caps_SubgroupMatrixMultiplyAccumulateINTEL, 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_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"GroupIMulKHR", spv::Op::OpGroupIMulKHR, 0, nullptr, 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, 0, nullptr, 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, 0, nullptr, 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},

File diff suppressed because one or more lines are too long

View File

@@ -34,6 +34,7 @@ kSPV_EXT_shader_viewport_index_layer,
kSPV_GOOGLE_decorate_string,
kSPV_GOOGLE_hlsl_functionality1,
kSPV_GOOGLE_user_type,
kSPV_INTEL_2d_block_io,
kSPV_INTEL_arbitrary_precision_fixed_point,
kSPV_INTEL_arbitrary_precision_floating_point,
kSPV_INTEL_arbitrary_precision_integers,
@@ -72,6 +73,7 @@ kSPV_INTEL_runtime_aligned,
kSPV_INTEL_shader_integer_functions2,
kSPV_INTEL_split_barrier,
kSPV_INTEL_subgroup_buffer_prefetch,
kSPV_INTEL_subgroup_matrix_multiply_accumulate,
kSPV_INTEL_subgroups,
kSPV_INTEL_unstructured_loop_controls,
kSPV_INTEL_usm_storage_classes,
@@ -118,12 +120,15 @@ kSPV_KHR_vulkan_memory_model,
kSPV_KHR_workgroup_memory_explicit_layout,
kSPV_NVX_multiview_per_view_attributes,
kSPV_NV_bindless_texture,
kSPV_NV_cluster_acceleration_structure,
kSPV_NV_compute_shader_derivatives,
kSPV_NV_cooperative_matrix,
kSPV_NV_cooperative_matrix2,
kSPV_NV_cooperative_vector,
kSPV_NV_displacement_micromap,
kSPV_NV_fragment_shader_barycentric,
kSPV_NV_geometry_shader_passthrough,
kSPV_NV_linear_swept_spheres,
kSPV_NV_mesh_shader,
kSPV_NV_raw_access_chains,
kSPV_NV_ray_tracing,

View File

@@ -69,6 +69,7 @@ static const char* pygen_variable_aliases_ShaderNonUniformEXT[] = {"ShaderNonUni
static const char* pygen_variable_aliases_ShaderRecordBufferNV[] = {"ShaderRecordBufferNV"};
static const char* pygen_variable_aliases_ShaderViewportIndexLayerNV[] = {"ShaderViewportIndexLayerNV"};
static const char* pygen_variable_aliases_ShadingRateNV[] = {"ShadingRateNV"};
static const char* pygen_variable_aliases_SkipBuiltinPrimitivesNV[] = {"SkipBuiltinPrimitivesNV"};
static const char* pygen_variable_aliases_StorageBufferArrayNonUniformIndexingEXT[] = {"StorageBufferArrayNonUniformIndexingEXT"};
static const char* pygen_variable_aliases_StorageImageArrayNonUniformIndexingEXT[] = {"StorageImageArrayNonUniformIndexingEXT"};
static const char* pygen_variable_aliases_StorageTexelBufferArrayDynamicIndexingEXT[] = {"StorageTexelBufferArrayDynamicIndexingEXT"};
@@ -185,13 +186,16 @@ static const spv::Capability pygen_variable_caps_RawAccessChainsNV[] = {spv::Cap
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_RayTracingClusterAccelerationStructureNV[] = {spv::Capability::RayTracingClusterAccelerationStructureNV};
static const spv::Capability pygen_variable_caps_RayTracingDisplacementMicromapNV[] = {spv::Capability::RayTracingDisplacementMicromapNV};
static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR};
static const spv::Capability pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV[] = {spv::Capability::RayTracingLinearSweptSpheresGeometryNV};
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_RayTracingPositionFetchKHR[] = {spv::Capability::RayTracingPositionFetchKHR};
static const spv::Capability pygen_variable_caps_RayTracingSpheresGeometryNV[] = {spv::Capability::RayTracingSpheresGeometryNV};
static const spv::Capability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {spv::Capability::RayTraversalPrimitiveCullingKHR};
static const spv::Capability pygen_variable_caps_RegisterLimitsINTEL[] = {spv::Capability::RegisterLimitsINTEL};
static const spv::Capability pygen_variable_caps_RoundToInfinityINTEL[] = {spv::Capability::RoundToInfinityINTEL};
@@ -223,6 +227,7 @@ static const spv::Capability pygen_variable_caps_StencilExportEXT[] = {spv::Capa
static const spv::Capability pygen_variable_caps_StorageBuffer16BitAccess[] = {spv::Capability::StorageBuffer16BitAccess};
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_Subgroup2DBlockIOINTEL[] = {spv::Capability::Subgroup2DBlockIOINTEL};
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};
@@ -270,6 +275,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_tile_image[]
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_user_type[] = {spvtools::Extension::kSPV_GOOGLE_user_type};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_2d_block_io[] = {spvtools::Extension::kSPV_INTEL_2d_block_io};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_fixed_point[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_fixed_point};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_floating_point[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_floating_point};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_integers[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_integers};
@@ -307,6 +313,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_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_subgroup_buffer_prefetch[] = {spvtools::Extension::kSPV_INTEL_subgroup_buffer_prefetch};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroup_matrix_multiply_accumulate[] = {spvtools::Extension::kSPV_INTEL_subgroup_matrix_multiply_accumulate};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroups[] = {spvtools::Extension::kSPV_INTEL_subgroups};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_usm_storage_classes[] = {spvtools::Extension::kSPV_INTEL_usm_storage_classes};
@@ -352,10 +359,13 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_workgroup_memory_ex
static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributes[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes};
static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes, spvtools::Extension::kSPV_NV_mesh_shader};
static const spvtools::Extension pygen_variable_exts_SPV_NV_bindless_texture[] = {spvtools::Extension::kSPV_NV_bindless_texture};
static const spvtools::Extension pygen_variable_exts_SPV_NV_cluster_acceleration_structure[] = {spvtools::Extension::kSPV_NV_cluster_acceleration_structure};
static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix};
static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix2[] = {spvtools::Extension::kSPV_NV_cooperative_matrix2};
static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_vector[] = {spvtools::Extension::kSPV_NV_cooperative_vector};
static const spvtools::Extension pygen_variable_exts_SPV_NV_displacement_micromap[] = {spvtools::Extension::kSPV_NV_displacement_micromap};
static const spvtools::Extension pygen_variable_exts_SPV_NV_geometry_shader_passthrough[] = {spvtools::Extension::kSPV_NV_geometry_shader_passthrough};
static const spvtools::Extension pygen_variable_exts_SPV_NV_linear_swept_spheres[] = {spvtools::Extension::kSPV_NV_linear_swept_spheres};
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader};
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_mesh_shader, spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_NV_raw_access_chains[] = {spvtools::Extension::kSPV_NV_raw_access_chains};
@@ -488,7 +498,7 @@ static const spv_operand_desc_t pygen_variable_RayFlagsEntries[] = {
{"CullFrontFacingTrianglesKHR", 0x0020, 0, nullptr, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"CullOpaqueKHR", 0x0040, 0, nullptr, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"CullNoOpaqueKHR", 0x0080, 0, nullptr, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SkipTrianglesKHR", 0x0100, 0, nullptr, 1, pygen_variable_caps_RayTraversalPrimitiveCullingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SkipTrianglesKHR", 0x0100, 1, pygen_variable_aliases_SkipBuiltinPrimitivesNV, 1, pygen_variable_caps_RayTraversalPrimitiveCullingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SkipAABBsKHR", 0x0200, 0, nullptr, 1, pygen_variable_caps_RayTraversalPrimitiveCullingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"ForceOpacityMicromap2StateEXT", 0x0400, 0, nullptr, 1, pygen_variable_caps_RayTracingOpacityMicromapEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
@@ -519,7 +529,8 @@ static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = {
{"NZSL", 9, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
{"WGSL", 10, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
{"Slang", 11, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
{"Zig", 12, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}
{"Zig", 12, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
{"Rust", 13, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = {
@@ -1119,12 +1130,19 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
{"HitMicroTriangleVertexBarycentricsNV", 5344, 0, nullptr, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"IncomingRayFlagsKHR", 5351, 1, pygen_variable_aliases_IncomingRayFlagsNV, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"RayGeometryIndexKHR", 5352, 0, nullptr, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"HitIsSphereNV", 5359, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"HitIsLSSNV", 5360, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"HitSpherePositionNV", 5361, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"WarpsPerSMNV", 5374, 0, nullptr, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
{"SMCountNV", 5375, 0, nullptr, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
{"WarpIDNV", 5376, 0, nullptr, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
{"SMIDNV", 5377, 0, nullptr, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
{"HitLSSPositionsNV", 5396, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"HitKindFrontFacingMicroTriangleNV", 5405, 0, nullptr, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"HitKindBackFacingMicroTriangleNV", 5406, 0, nullptr, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"HitSphereRadiusNV", 5420, 0, nullptr, 1, pygen_variable_caps_RayTracingSpheresGeometryNV, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"HitLSSRadiiNV", 5421, 0, nullptr, 1, pygen_variable_caps_RayTracingLinearSweptSpheresGeometryNV, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"ClusterIDNV", 5436, 0, nullptr, 1, pygen_variable_caps_RayTracingClusterAccelerationStructureNV, 1, pygen_variable_exts_SPV_NV_cluster_acceleration_structure, {}, 0xffffffffu, 0xffffffffu},
{"CullMaskKHR", 6021, 0, nullptr, 1, pygen_variable_caps_RayCullMaskKHR, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu}
};
@@ -1318,14 +1336,19 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"ShaderInvocationReorderNV", 5383, 0, nullptr, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_shader_invocation_reorder, {}, 0xffffffffu, 0xffffffffu},
{"BindlessTextureNV", 5390, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_bindless_texture, {}, 0xffffffffu, 0xffffffffu},
{"RayQueryPositionFetchKHR", 5391, 0, nullptr, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorNV", 5394, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_vector, {}, 0xffffffffu, 0xffffffffu},
{"AtomicFloat16VectorNV", 5404, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_atomic_fp16_vector, {}, 0xffffffffu, 0xffffffffu},
{"RayTracingDisplacementMicromapNV", 5409, 0, nullptr, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_displacement_micromap, {}, 0xffffffffu, 0xffffffffu},
{"RawAccessChainsNV", 5414, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_raw_access_chains, {}, 0xffffffffu, 0xffffffffu},
{"RayTracingSpheresGeometryNV", 5418, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"RayTracingLinearSweptSpheresGeometryNV", 5419, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_linear_swept_spheres, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixReductionsNV", 5430, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_matrix2, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixConversionsNV", 5431, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_matrix2, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixPerElementOperationsNV", 5432, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_matrix2, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixTensorAddressingNV", 5433, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_matrix2, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixBlockLoadsNV", 5434, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_matrix2, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeVectorTrainingNV", 5435, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_cooperative_vector, {}, 0xffffffffu, 0xffffffffu},
{"RayTracingClusterAccelerationStructureNV", 5437, 0, nullptr, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_cluster_acceleration_structure, {}, 0xffffffffu, 0xffffffffu},
{"TensorAddressingNV", 5439, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_NV_tensor_addressing, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupShuffleINTEL", 5568, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupBufferBlockIOINTEL", 5569, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},
@@ -1333,7 +1356,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"SubgroupImageMediaBlockIOINTEL", 5579, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_media_block_io, {}, 0xffffffffu, 0xffffffffu},
{"RoundToInfinityINTEL", 5582, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu},
{"FloatingPointModeINTEL", 5583, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu},
{"IntegerFunctions2INTEL", 5584, 0, nullptr, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_INTEL_shader_integer_functions2, {}, 0xffffffffu, 0xffffffffu},
{"IntegerFunctions2INTEL", 5584, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_shader_integer_functions2, {}, 0xffffffffu, 0xffffffffu},
{"FunctionPointersINTEL", 5603, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu},
{"IndirectReferencesINTEL", 5604, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu},
{"AsmINTEL", 5606, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_inline_assembly, {}, 0xffffffffu, 0xffffffffu},
@@ -1396,6 +1419,10 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"GlobalVariableHostAccessINTEL", 6187, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_global_variable_host_access, {}, 0xffffffffu, 0xffffffffu},
{"GlobalVariableFPGADecorationsINTEL", 6189, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_global_variable_fpga_decorations, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupBufferPrefetchINTEL", 6220, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroup_buffer_prefetch, {}, 0xffffffffu, 0xffffffffu},
{"Subgroup2DBlockIOINTEL", 6228, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_2d_block_io, {}, 0xffffffffu, 0xffffffffu},
{"Subgroup2DBlockTransformINTEL", 6229, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockIOINTEL, 1, pygen_variable_exts_SPV_INTEL_2d_block_io, {}, 0xffffffffu, 0xffffffffu},
{"Subgroup2DBlockTransposeINTEL", 6230, 0, nullptr, 1, pygen_variable_caps_Subgroup2DBlockIOINTEL, 1, pygen_variable_exts_SPV_INTEL_2d_block_io, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupMatrixMultiplyAccumulateINTEL", 6236, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroup_matrix_multiply_accumulate, {}, 0xffffffffu, 0xffffffffu},
{"GroupUniformArithmeticKHR", 6400, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_uniform_group_instructions, {}, 0xffffffffu, 0xffffffffu},
{"MaskedGatherScatterINTEL", 6427, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_masked_gather_scatter, {}, 0xffffffffu, 0xffffffffu},
{"CacheControlsINTEL", 6441, 0, nullptr, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_cache_controls, {}, 0xffffffffu, 0xffffffffu},
@@ -1488,10 +1515,53 @@ static const spv_operand_desc_t pygen_variable_NamedMaximumNumberOfRegistersEntr
{"AutoINTEL", 0, 0, nullptr, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_MatrixMultiplyAccumulateOperandsEntries[] = {
{"None", 0x0, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixASignedComponentsINTEL", 0x1, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixBSignedComponentsINTEL", 0x2, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixCBFloat16INTEL", 0x4, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixResultBFloat16INTEL", 0x8, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixAPackedInt8INTEL", 0x10, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixBPackedInt8INTEL", 0x20, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixAPackedInt4INTEL", 0x40, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixBPackedInt4INTEL", 0x80, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixATF32INTEL", 0x100, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixBTF32INTEL", 0x200, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixAPackedFloat16INTEL", 0x400, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixBPackedFloat16INTEL", 0x800, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixAPackedBFloat16INTEL", 0x1000, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MatrixBPackedBFloat16INTEL", 0x2000, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_FPEncodingEntries[] = {
{"place holder", 0, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(999,0), 0}
};
static const spv_operand_desc_t pygen_variable_CooperativeVectorMatrixLayoutEntries[] = {
{"RowMajorNV", 0, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"ColumnMajorNV", 1, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"InferencingOptimalNV", 2, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"TrainingOptimalNV", 3, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_ComponentTypeEntries[] = {
{"Float16NV", 0, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"Float32NV", 1, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"Float64NV", 2, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SignedInt8NV", 3, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SignedInt16NV", 4, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SignedInt32NV", 5, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SignedInt64NV", 6, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"UnsignedInt8NV", 7, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"UnsignedInt16NV", 8, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"UnsignedInt32NV", 9, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"UnsignedInt64NV", 10, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SignedInt8PackedNV", 1000491000, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"UnsignedInt8PackedNV", 1000491001, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"FloatE4M3NV", 1000491002, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"FloatE5M2NV", 1000491003, 0, nullptr, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_DebugInfoFlagsEntries[] = {
{"None", 0x0000, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FlagIsProtected", 0x01, 0, nullptr, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
@@ -1663,7 +1733,10 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = {
{SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, ARRAY_SIZE(pygen_variable_LoadCacheControlEntries), pygen_variable_LoadCacheControlEntries},
{SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, ARRAY_SIZE(pygen_variable_StoreCacheControlEntries), pygen_variable_StoreCacheControlEntries},
{SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS, ARRAY_SIZE(pygen_variable_NamedMaximumNumberOfRegistersEntries), pygen_variable_NamedMaximumNumberOfRegistersEntries},
{SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, ARRAY_SIZE(pygen_variable_MatrixMultiplyAccumulateOperandsEntries), pygen_variable_MatrixMultiplyAccumulateOperandsEntries},
{SPV_OPERAND_TYPE_FPENCODING, ARRAY_SIZE(pygen_variable_FPEncodingEntries), pygen_variable_FPEncodingEntries},
{SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT, ARRAY_SIZE(pygen_variable_CooperativeVectorMatrixLayoutEntries), pygen_variable_CooperativeVectorMatrixLayoutEntries},
{SPV_OPERAND_TYPE_COMPONENT_TYPE, ARRAY_SIZE(pygen_variable_ComponentTypeEntries), pygen_variable_ComponentTypeEntries},
{SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, ARRAY_SIZE(pygen_variable_DebugInfoFlagsEntries), pygen_variable_DebugInfoFlagsEntries},
{SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, ARRAY_SIZE(pygen_variable_DebugBaseTypeAttributeEncodingEntries), pygen_variable_DebugBaseTypeAttributeEncodingEntries},
{SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, ARRAY_SIZE(pygen_variable_DebugCompositeTypeEntries), pygen_variable_DebugCompositeTypeEntries},
@@ -1681,5 +1754,6 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = {
{SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries},
{SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT, ARRAY_SIZE(pygen_variable_PackedVectorFormatEntries), pygen_variable_PackedVectorFormatEntries},
{SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS, ARRAY_SIZE(pygen_variable_CooperativeMatrixOperandsEntries), pygen_variable_CooperativeMatrixOperandsEntries},
{SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, ARRAY_SIZE(pygen_variable_MatrixMultiplyAccumulateOperandsEntries), pygen_variable_MatrixMultiplyAccumulateOperandsEntries},
{SPV_OPERAND_TYPE_OPTIONAL_FPENCODING, ARRAY_SIZE(pygen_variable_FPEncodingEntries), pygen_variable_FPEncodingEntries}
};

View File

@@ -321,6 +321,12 @@ typedef enum spv_operand_type_t {
SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE,
// Enum type from SPV_NV_cooperative_matrix2
SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS,
// Optional types from SPV_INTEL_subgroup_matrix_multiply_accumulate
SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS,
SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS,
SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT,
SPV_OPERAND_TYPE_COMPONENT_TYPE,
// This is a sentinel value, and does not represent an operand type.
// It should come last.
@@ -730,6 +736,11 @@ SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetSkipBlockLayout(
SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowLocalSizeId(
spv_validator_options options, bool val);
// Allow Offset (in addition to ConstOffset) for texture operations.
// Was added for VK_KHR_maintenance8
SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowOffsetTextureOperand(
spv_validator_options options, bool val);
// Whether friendly names should be used in validation error messages.
SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetFriendlyNames(
spv_validator_options options, bool val);

View File

@@ -126,6 +126,12 @@ class SPIRV_TOOLS_EXPORT ValidatorOptions {
spvValidatorOptionsSetAllowLocalSizeId(options_, val);
}
// Allow Offset (in addition to ConstOffset) for texture
// operations. Was added for VK_KHR_maintenance8
void SetAllowOffsetTextureOperand(bool val) {
spvValidatorOptionsSetAllowOffsetTextureOperand(options_, val);
}
// Records whether or not the validator should relax the rules on pointer
// usage in logical addressing mode.
//

View File

@@ -726,7 +726,9 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS: {
case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS: {
// This operand is a mask.
// Map an optional operand type to its corresponding concrete type.
@@ -738,6 +740,9 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
parsed_operand.type = SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS;
if (type == SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS)
parsed_operand.type = SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS;
if (type == SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS)
parsed_operand.type =
SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS;
// Check validity of set mask bits. Also prepare for operands for those
// masks if they have any. To get operand order correct, scan from

View File

@@ -15,6 +15,8 @@
#ifndef SOURCE_CFA_H_
#define SOURCE_CFA_H_
#include <stddef.h>
#include <algorithm>
#include <cassert>
#include <cstdint>

View File

@@ -420,6 +420,7 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer,
std::vector<LinkageSymbolInfo> imports;
std::unordered_map<std::string, std::vector<LinkageSymbolInfo>> exports;
std::unordered_map<std::string, LinkageSymbolInfo> linkonce;
// Figure out the imports and exports
for (const auto& decoration : linked_context.annotations()) {
@@ -478,10 +479,24 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer,
<< " LinkageAttributes; " << id << " is neither of them.\n";
}
if (spv::LinkageType(type) == spv::LinkageType::Import)
if (spv::LinkageType(type) == spv::LinkageType::Import) {
imports.push_back(symbol_info);
else if (spv::LinkageType(type) == spv::LinkageType::Export)
} else if (spv::LinkageType(type) == spv::LinkageType::Export) {
exports[symbol_info.name].push_back(symbol_info);
} else if (spv::LinkageType(type) == spv::LinkageType::LinkOnceODR) {
if (linkonce.find(symbol_info.name) == linkonce.end())
linkonce[symbol_info.name] = symbol_info;
}
}
for (const auto& possible_export : linkonce) {
if (exports.find(possible_export.first) == exports.end())
exports[possible_export.first].push_back(possible_export.second);
else
return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
<< "Combination of Export and LinkOnceODR is not allowed, found "
"for \""
<< possible_export.second.name << "\".";
}
// Find the import/export pairs
@@ -661,8 +676,10 @@ spv_result_t RemoveLinkageSpecificInstructions(
if (inst->opcode() == spv::Op::OpDecorate &&
spv::Decoration(inst->GetSingleWordOperand(1u)) ==
spv::Decoration::LinkageAttributes &&
spv::LinkageType(inst->GetSingleWordOperand(3u)) ==
spv::LinkageType::Export) {
(spv::LinkageType(inst->GetSingleWordOperand(3u)) ==
spv::LinkageType::Export ||
spv::LinkageType(inst->GetSingleWordOperand(3u)) ==
spv::LinkageType::LinkOnceODR)) {
linked_context->KillInst(&*inst);
}
}

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2016 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -241,6 +243,10 @@ spv_result_t FriendlyNameMapper::ParseInstruction(
SaveName(result_id,
std::string("_runtimearr_") + NameForId(inst.words[2]));
break;
case spv::Op::OpTypeNodePayloadArrayAMDX:
SaveName(result_id,
std::string("_payloadarr_") + NameForId(inst.words[2]));
break;
case spv::Op::OpTypePointer:
SaveName(result_id, std::string("_ptr_") +
NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS,

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2015-2022 The Khronos Group Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
// reserved.
// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All
// rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -265,12 +265,14 @@ int32_t spvOpcodeIsConstant(const spv::Op opcode) {
case spv::Op::OpConstantSampler:
case spv::Op::OpConstantNull:
case spv::Op::OpConstantFunctionPointerINTEL:
case spv::Op::OpConstantStringAMDX:
case spv::Op::OpSpecConstantTrue:
case spv::Op::OpSpecConstantFalse:
case spv::Op::OpSpecConstant:
case spv::Op::OpSpecConstantComposite:
case spv::Op::OpSpecConstantCompositeReplicateEXT:
case spv::Op::OpSpecConstantOp:
case spv::Op::OpSpecConstantStringAMDX:
return true;
default:
return false;
@@ -301,6 +303,7 @@ int32_t spvOpcodeIsComposite(const spv::Op opcode) {
case spv::Op::OpTypeRuntimeArray:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
return true;
default:
return false;
@@ -318,6 +321,7 @@ bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) {
case spv::Op::OpFunctionParameter:
case spv::Op::OpImageTexelPointer:
case spv::Op::OpCopyObject:
case spv::Op::OpAllocateNodePayloadsAMDX:
case spv::Op::OpSelect:
case spv::Op::OpPhi:
case spv::Op::OpFunctionCall:
@@ -344,6 +348,7 @@ int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
case spv::Op::OpImageTexelPointer:
case spv::Op::OpCopyObject:
case spv::Op::OpRawAccessChainNV:
case spv::Op::OpAllocateNodePayloadsAMDX:
return true;
default:
return false;
@@ -377,11 +382,13 @@ int32_t spvOpcodeGeneratesType(spv::Op op) {
case spv::Op::OpTypeAccelerationStructureNV:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
// case spv::Op::OpTypeAccelerationStructureKHR: covered by
// spv::Op::OpTypeAccelerationStructureNV
case spv::Op::OpTypeRayQueryKHR:
case spv::Op::OpTypeHitObjectNV:
case spv::Op::OpTypeUntypedPointerKHR:
case spv::Op::OpTypeNodePayloadArrayAMDX:
case spv::Op::OpTypeTensorLayoutNV:
case spv::Op::OpTypeTensorViewNV:
return true;

View File

@@ -237,6 +237,9 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
return "cooperative matrix reduce";
case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
return "tensor addressing operands";
case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
return "matrix multiply accumulate operands";
case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
return "initialization mode qualifier";
case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
@@ -297,6 +300,10 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
return "quantization mode";
case SPV_OPERAND_TYPE_OVERFLOW_MODES:
return "overflow mode";
case SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT:
return "cooperative vector matrix layout";
case SPV_OPERAND_TYPE_COMPONENT_TYPE:
return "component type";
case SPV_OPERAND_TYPE_NONE:
return "NONE";
@@ -396,6 +403,8 @@ bool spvOperandIsConcrete(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
case SPV_OPERAND_TYPE_FPENCODING:
case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE:
case SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT:
case SPV_OPERAND_TYPE_COMPONENT_TYPE:
return true;
default:
break;
@@ -415,6 +424,7 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
@@ -437,6 +447,7 @@ bool spvOperandIsOptional(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_CIV:
case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:

View File

@@ -207,6 +207,7 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForExtract(
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
type_id = type_inst->GetSingleWordInOperand(0);
break;
default:
@@ -255,6 +256,7 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain(
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
type_id = type_inst->GetSingleWordInOperand(0);
break;
default:
@@ -516,6 +518,7 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) {
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
new_operands.emplace_back(inst->GetInOperand(i));
type_id = type_inst->GetSingleWordInOperand(0);
break;
@@ -591,6 +594,7 @@ bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) {
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
type_id = type_inst->GetSingleWordInOperand(0);
break;
default:
@@ -654,6 +658,7 @@ bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) {
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
type_id = type_inst->GetSingleWordInOperand(0);
break;
default:

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2019 Google LLC
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -99,6 +101,7 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst,
case spv::Op::OpCopyMemorySized:
case spv::Op::OpVariable:
case spv::Op::OpBitcast:
case spv::Op::OpAllocateNodePayloadsAMDX:
// Nothing to change for these opcode. The result type is the same
// regardless of the storage class of the operand.
return false;
@@ -319,6 +322,7 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) {
switch (type_inst->opcode()) {
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray:
case spv::Op::OpTypeNodePayloadArrayAMDX:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeCooperativeMatrixKHR:

View File

@@ -77,7 +77,10 @@ int32_t ImageOperandsMaskInOperandIndex(Instruction* inst) {
// Returns the element width of |type|.
uint32_t ElementWidth(const analysis::Type* type) {
if (const analysis::Vector* vec_type = type->AsVector()) {
if (const analysis::CooperativeVectorNV* coopvec_type =
type->AsCooperativeVectorNV()) {
return ElementWidth(coopvec_type->component_type());
} else if (const analysis::Vector* vec_type = type->AsVector()) {
return ElementWidth(vec_type->element_type());
} else if (const analysis::Float* float_type = type->AsFloat()) {
return float_type->width();

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2017 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -539,6 +541,7 @@ void IRContext::AddCombinatorsForCapability(uint32_t capability) {
(uint32_t)spv::Op::OpTypeHitObjectNV,
(uint32_t)spv::Op::OpTypeArray,
(uint32_t)spv::Op::OpTypeRuntimeArray,
(uint32_t)spv::Op::OpTypeNodePayloadArrayAMDX,
(uint32_t)spv::Op::OpTypeStruct,
(uint32_t)spv::Op::OpTypeOpaque,
(uint32_t)spv::Op::OpTypePointer,

View File

@@ -1,6 +1,8 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -431,7 +433,7 @@ void LocalAccessChainConvertPass::InitExtensions() {
"SPV_EXT_fragment_shader_interlock",
"SPV_KHR_compute_shader_derivatives", "SPV_NV_cooperative_matrix",
"SPV_KHR_cooperative_matrix", "SPV_KHR_ray_tracing_position_fetch",
"SPV_KHR_fragment_shading_rate"});
"SPV_AMDX_shader_enqueue", "SPV_KHR_fragment_shading_rate"});
}
bool LocalAccessChainConvertPass::AnyIndexIsOutOfBounds(

View File

@@ -1,6 +1,8 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -238,6 +240,7 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() {
"SPV_AMD_gcn_shader",
"SPV_KHR_shader_ballot",
"SPV_AMD_shader_ballot",
"SPV_AMDX_shader_enqueue",
"SPV_AMD_gpu_shader_half_float",
"SPV_KHR_shader_draw_parameters",
"SPV_KHR_subgroup_vote",

View File

@@ -1,6 +1,8 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -145,7 +147,9 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() {
"SPV_NV_cooperative_matrix",
"SPV_KHR_cooperative_matrix",
"SPV_KHR_ray_tracing_position_fetch",
"SPV_KHR_fragment_shading_rate"});
"SPV_AMDX_shader_enqueue",
"SPV_KHR_fragment_shading_rate",
"SPV_KHR_ray_tracing"});
}
bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
std::vector<Instruction*> users;

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2017 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -671,7 +673,8 @@ bool ScalarReplacementPass::CheckTypeAnnotations(
for (auto inst :
get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) {
uint32_t decoration;
if (inst->opcode() == spv::Op::OpDecorate) {
if (inst->opcode() == spv::Op::OpDecorate ||
inst->opcode() == spv::Op::OpDecorateId) {
decoration = inst->GetSingleWordInOperand(1u);
} else {
assert(inst->opcode() == spv::Op::OpMemberDecorate);

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2016 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -335,6 +337,17 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) {
std::initializer_list<Operand>{{SPV_OPERAND_TYPE_ID, {subtype}}});
break;
}
case Type::kNodePayloadArrayAMDX: {
uint32_t subtype =
GetTypeInstruction(type->AsNodePayloadArrayAMDX()->element_type());
if (subtype == 0) {
return 0;
}
typeInst = MakeUnique<Instruction>(
context(), spv::Op::OpTypeNodePayloadArrayAMDX, 0, id,
std::initializer_list<Operand>{{SPV_OPERAND_TYPE_ID, {subtype}}});
break;
}
case Type::kStruct: {
std::vector<Operand> ops;
const Struct* structTy = type->AsStruct();
@@ -463,6 +476,20 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) {
0, id, operands);
break;
}
case Type::kCooperativeVectorNV: {
auto coop_vec = type->AsCooperativeVectorNV();
uint32_t const component_type =
GetTypeInstruction(coop_vec->component_type());
if (component_type == 0) {
return 0;
}
typeInst = MakeUnique<Instruction>(
context(), spv::Op::OpTypeCooperativeVectorNV, 0, id,
std::initializer_list<Operand>{
{SPV_OPERAND_TYPE_ID, {component_type}},
{SPV_OPERAND_TYPE_ID, {coop_vec->components()}}});
break;
}
default:
assert(false && "Unexpected type");
break;
@@ -623,6 +650,13 @@ Type* TypeManager::RebuildType(uint32_t type_id, const Type& type) {
MakeUnique<RuntimeArray>(RebuildType(GetId(ele_ty), *ele_ty));
break;
}
case Type::kNodePayloadArrayAMDX: {
const NodePayloadArrayAMDX* array_ty = type.AsNodePayloadArrayAMDX();
const Type* ele_ty = array_ty->element_type();
rebuilt_ty =
MakeUnique<NodePayloadArrayAMDX>(RebuildType(GetId(ele_ty), *ele_ty));
break;
}
case Type::kStruct: {
const Struct* struct_ty = type.AsStruct();
std::vector<const Type*> subtypes;
@@ -701,6 +735,14 @@ Type* TypeManager::RebuildType(uint32_t type_id, const Type& type) {
tv_type->dim_id(), tv_type->has_dimensions_id(), tv_type->perm());
break;
}
case Type::kCooperativeVectorNV: {
const CooperativeVectorNV* cv_type = type.AsCooperativeVectorNV();
const Type* component_type = cv_type->component_type();
rebuilt_ty = MakeUnique<CooperativeVectorNV>(
RebuildType(GetId(component_type), *component_type),
cv_type->components());
break;
}
default:
assert(false && "Unhandled type");
return nullptr;
@@ -837,6 +879,14 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) {
return type;
}
break;
case spv::Op::OpTypeNodePayloadArrayAMDX:
type = new NodePayloadArrayAMDX(GetType(inst.GetSingleWordInOperand(0)));
if (id_to_incomplete_type_.count(inst.GetSingleWordInOperand(0))) {
incomplete_types_.emplace_back(inst.result_id(), type);
id_to_incomplete_type_[inst.result_id()] = type;
return type;
}
break;
case spv::Op::OpTypeStruct: {
std::vector<const Type*> element_types;
bool incomplete_type = false;
@@ -942,6 +992,10 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) {
inst.GetSingleWordInOperand(1), inst.GetSingleWordInOperand(2),
inst.GetSingleWordInOperand(3), inst.GetSingleWordInOperand(4));
break;
case spv::Op::OpTypeCooperativeVectorNV:
type = new CooperativeVectorNV(GetType(inst.GetSingleWordInOperand(0)),
inst.GetSingleWordInOperand(1));
break;
case spv::Op::OpTypeRayQueryKHR:
type = new RayQueryKHR();
break;
@@ -988,7 +1042,8 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) {
if (!IsAnnotationInst(opcode)) return;
switch (opcode) {
case spv::Op::OpDecorate: {
case spv::Op::OpDecorate:
case spv::Op::OpDecorateId: {
const auto count = inst.NumOperands();
std::vector<uint32_t> data;
for (uint32_t i = 1; i < count; ++i) {

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2016 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -90,6 +92,7 @@ bool Type::IsUniqueType() const {
case kStruct:
case kArray:
case kRuntimeArray:
case kNodePayloadArrayAMDX:
return false;
default:
return true;
@@ -129,6 +132,7 @@ std::unique_ptr<Type> Type::Clone() const {
DeclareKindCase(AccelerationStructureNV);
DeclareKindCase(CooperativeMatrixNV);
DeclareKindCase(CooperativeMatrixKHR);
DeclareKindCase(CooperativeVectorNV);
DeclareKindCase(RayQueryKHR);
DeclareKindCase(HitObjectNV);
#undef DeclareKindCase
@@ -162,6 +166,7 @@ bool Type::operator==(const Type& other) const {
DeclareKindCase(SampledImage);
DeclareKindCase(Array);
DeclareKindCase(RuntimeArray);
DeclareKindCase(NodePayloadArrayAMDX);
DeclareKindCase(Struct);
DeclareKindCase(Opaque);
DeclareKindCase(Pointer);
@@ -177,6 +182,7 @@ bool Type::operator==(const Type& other) const {
DeclareKindCase(AccelerationStructureNV);
DeclareKindCase(CooperativeMatrixNV);
DeclareKindCase(CooperativeMatrixKHR);
DeclareKindCase(CooperativeVectorNV);
DeclareKindCase(RayQueryKHR);
DeclareKindCase(HitObjectNV);
DeclareKindCase(TensorLayoutNV);
@@ -220,6 +226,7 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const {
DeclareKindCase(SampledImage);
DeclareKindCase(Array);
DeclareKindCase(RuntimeArray);
DeclareKindCase(NodePayloadArrayAMDX);
DeclareKindCase(Struct);
DeclareKindCase(Opaque);
DeclareKindCase(Pointer);
@@ -235,6 +242,7 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const {
DeclareKindCase(AccelerationStructureNV);
DeclareKindCase(CooperativeMatrixNV);
DeclareKindCase(CooperativeMatrixKHR);
DeclareKindCase(CooperativeVectorNV);
DeclareKindCase(RayQueryKHR);
DeclareKindCase(HitObjectNV);
DeclareKindCase(TensorLayoutNV);
@@ -489,6 +497,34 @@ void RuntimeArray::ReplaceElementType(const Type* type) {
element_type_ = type;
}
NodePayloadArrayAMDX::NodePayloadArrayAMDX(const Type* type)
: Type(kNodePayloadArrayAMDX), element_type_(type) {
assert(!type->AsVoid());
}
bool NodePayloadArrayAMDX::IsSameImpl(const Type* that,
IsSameCache* seen) const {
const NodePayloadArrayAMDX* rat = that->AsNodePayloadArrayAMDX();
if (!rat) return false;
return element_type_->IsSameImpl(rat->element_type_, seen) &&
HasSameDecorations(that);
}
std::string NodePayloadArrayAMDX::str() const {
std::ostringstream oss;
oss << "[" << element_type_->str() << "]";
return oss.str();
}
size_t NodePayloadArrayAMDX::ComputeExtraStateHash(size_t hash,
SeenTypes* seen) const {
return element_type_->ComputeHashValue(hash, seen);
}
void NodePayloadArrayAMDX::ReplaceElementType(const Type* type) {
element_type_ = type;
}
Struct::Struct(const std::vector<const Type*>& types)
: Type(kStruct), element_types_(types) {
for (const auto* t : types) {
@@ -802,6 +838,35 @@ bool TensorViewNV::IsSameImpl(const Type* that, IsSameCache*) const {
has_dimensions_id_ == tv->has_dimensions_id_ && perm_ == tv->perm_;
}
CooperativeVectorNV::CooperativeVectorNV(const Type* type,
const uint32_t components)
: Type(kCooperativeVectorNV),
component_type_(type),
components_(components) {
assert(type != nullptr);
assert(components != 0);
}
std::string CooperativeVectorNV::str() const {
std::ostringstream oss;
oss << "<" << component_type_->str() << ", " << components_ << ">";
return oss.str();
}
size_t CooperativeVectorNV::ComputeExtraStateHash(size_t hash,
SeenTypes* seen) const {
hash = hash_combine(hash, components_);
return component_type_->ComputeHashValue(hash, seen);
}
bool CooperativeVectorNV::IsSameImpl(const Type* that,
IsSameCache* seen) const {
const CooperativeVectorNV* mt = that->AsCooperativeVectorNV();
if (!mt) return false;
return component_type_->IsSameImpl(mt->component_type_, seen) &&
components_ == mt->components_ && HasSameDecorations(that);
}
} // namespace analysis
} // namespace opt
} // namespace spvtools

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2016 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -46,6 +48,7 @@ class Sampler;
class SampledImage;
class Array;
class RuntimeArray;
class NodePayloadArrayAMDX;
class Struct;
class Opaque;
class Pointer;
@@ -61,6 +64,7 @@ class NamedBarrier;
class AccelerationStructureNV;
class CooperativeMatrixNV;
class CooperativeMatrixKHR;
class CooperativeVectorNV;
class RayQueryKHR;
class HitObjectNV;
class TensorLayoutNV;
@@ -89,6 +93,7 @@ class Type {
kSampledImage,
kArray,
kRuntimeArray,
kNodePayloadArrayAMDX,
kStruct,
kOpaque,
kPointer,
@@ -104,6 +109,7 @@ class Type {
kAccelerationStructureNV,
kCooperativeMatrixNV,
kCooperativeMatrixKHR,
kCooperativeVectorNV,
kRayQueryKHR,
kHitObjectNV,
kTensorLayoutNV,
@@ -193,6 +199,7 @@ class Type {
DeclareCastMethod(SampledImage)
DeclareCastMethod(Array)
DeclareCastMethod(RuntimeArray)
DeclareCastMethod(NodePayloadArrayAMDX)
DeclareCastMethod(Struct)
DeclareCastMethod(Opaque)
DeclareCastMethod(Pointer)
@@ -208,6 +215,7 @@ class Type {
DeclareCastMethod(AccelerationStructureNV)
DeclareCastMethod(CooperativeMatrixNV)
DeclareCastMethod(CooperativeMatrixKHR)
DeclareCastMethod(CooperativeVectorNV)
DeclareCastMethod(RayQueryKHR)
DeclareCastMethod(HitObjectNV)
DeclareCastMethod(TensorLayoutNV)
@@ -221,7 +229,9 @@ protected:
protected:
// Decorations attached to this type. Each decoration is encoded as a vector
// of uint32_t numbers. The first uint32_t number is the decoration value,
// and the rest are the parameters to the decoration (if exists).
// and the rest are the parameters to the decoration (if any exist).
// The parameters can be either all literals or all ids depending on the
// decoration value.
std::vector<std::vector<uint32_t>> decorations_;
private:
@@ -440,6 +450,29 @@ class RuntimeArray : public Type {
const Type* element_type_;
};
class NodePayloadArrayAMDX : public Type {
public:
NodePayloadArrayAMDX(const Type* element_type);
NodePayloadArrayAMDX(const NodePayloadArrayAMDX&) = default;
std::string str() const override;
const Type* element_type() const { return element_type_; }
NodePayloadArrayAMDX* AsNodePayloadArrayAMDX() override { return this; }
const NodePayloadArrayAMDX* AsNodePayloadArrayAMDX() const override {
return this;
}
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
void ReplaceElementType(const Type* element_type);
private:
bool IsSameImpl(const Type* that, IsSameCache*) const override;
const Type* element_type_;
};
class Struct : public Type {
public:
Struct(const std::vector<const Type*>& element_types);
@@ -712,6 +745,30 @@ class TensorViewNV : public Type {
std::vector<uint32_t> perm_;
};
class CooperativeVectorNV : public Type {
public:
CooperativeVectorNV(const Type* type, const uint32_t components);
CooperativeVectorNV(const CooperativeVectorNV&) = default;
std::string str() const override;
CooperativeVectorNV* AsCooperativeVectorNV() override { return this; }
const CooperativeVectorNV* AsCooperativeVectorNV() const override {
return this;
}
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
const Type* component_type() const { return component_type_; }
uint32_t components() const { return components_; }
private:
bool IsSameImpl(const Type* that, IsSameCache*) const override;
const Type* component_type_;
const uint32_t components_;
};
#define DefineParameterlessType(type, name) \
class type : public Type { \
public: \

View File

@@ -142,11 +142,20 @@ constexpr auto ordered_universal_envs = std::array<spv_target_env, 7>{
};
// When a new SPIR-V version is released, update this table.
// Users see this ordered list when running 'spirv-val --help'. Order
// matters for readability.
static_assert(spv::Version == 0x10600);
inline constexpr std::pair<const char*, spv_target_env> spvTargetEnvNameMap[] =
{
{"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4},
// Do not reorder blindly. The algorithm to find the target looks for
// the first entry where the key is a prefix of the string provided by
// the user. For example, if the user provides `vulkan1.2spv1.5`, it
// will match `vulkan1.2`. If this feature is to work correctly, the
// keys must be ordered so that a string is before its prefix. For
// example, `vulkan1.1spv1.4` must be before `vulkan1.1`. Otherwise,
// `vulkan1.1` will be returned when looking for `vulkan1.1spv1.4`.
{"vulkan1.0", SPV_ENV_VULKAN_1_0},
{"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4},
{"vulkan1.1", SPV_ENV_VULKAN_1_1},
{"vulkan1.2", SPV_ENV_VULKAN_1_2},
{"vulkan1.3", SPV_ENV_VULKAN_1_3},

View File

@@ -126,6 +126,11 @@ void spvValidatorOptionsSetAllowLocalSizeId(spv_validator_options options,
options->allow_localsizeid = val;
}
void spvValidatorOptionsSetAllowOffsetTextureOperand(
spv_validator_options options, bool val) {
options->allow_offset_texture_operand = val;
}
void spvValidatorOptionsSetFriendlyNames(spv_validator_options options,
bool val) {
options->use_friendly_names = val;

View File

@@ -48,6 +48,7 @@ struct spv_validator_options_t {
workgroup_scalar_block_layout(false),
skip_block_layout(false),
allow_localsizeid(false),
allow_offset_texture_operand(false),
before_hlsl_legalization(false),
use_friendly_names(true) {}
@@ -60,6 +61,7 @@ struct spv_validator_options_t {
bool workgroup_scalar_block_layout;
bool skip_block_layout;
bool allow_localsizeid;
bool allow_offset_texture_operand;
bool before_hlsl_legalization;
bool use_friendly_names;
};

View File

@@ -416,7 +416,8 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar,
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE: {
case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS: {
uint32_t value;
if (auto error = grammar.parseMaskOperand(type, textValue, &value)) {
return context->diagnostic(error)

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2018 Google LLC.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -30,6 +32,11 @@ bool DecorationTakesIdParameters(spv::Decoration type) {
case spv::Decoration::AlignmentId:
case spv::Decoration::MaxByteOffsetId:
case spv::Decoration::HlslCounterBufferGOOGLE:
case spv::Decoration::NodeMaxPayloadsAMDX:
case spv::Decoration::NodeSharesPayloadLimitsWithAMDX:
case spv::Decoration::PayloadNodeArraySizeAMDX:
case spv::Decoration::PayloadNodeNameAMDX:
case spv::Decoration::PayloadNodeBaseIndexAMDX:
return true;
default:
break;
@@ -163,6 +170,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec,
case spv::Decoration::Stream:
case spv::Decoration::RestrictPointer:
case spv::Decoration::AliasedPointer:
case spv::Decoration::PerPrimitiveEXT:
if (target->opcode() != spv::Op::OpVariable &&
target->opcode() != spv::Op::OpUntypedVariableKHR &&
target->opcode() != spv::Op::OpFunctionParameter &&

View File

@@ -40,19 +40,34 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
bool supportsCoopMat =
(opcode != spv::Op::OpFMul && opcode != spv::Op::OpFRem &&
opcode != spv::Op::OpFMod);
bool supportsCoopVec =
(opcode != spv::Op::OpFRem && opcode != spv::Op::OpFMod);
if (!_.IsFloatScalarType(result_type) &&
!_.IsFloatVectorType(result_type) &&
!(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type)) &&
!(opcode == spv::Op::OpFMul &&
_.IsCooperativeMatrixKHRType(result_type) &&
_.IsFloatCooperativeMatrixType(result_type)))
_.IsFloatCooperativeMatrixType(result_type)) &&
!(supportsCoopVec && _.IsFloatCooperativeVectorNVType(result_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected floating scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) {
if (supportsCoopVec && _.IsCooperativeVectorNVType(result_type)) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!_.IsCooperativeVectorNVType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
<< operand_index;
}
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, type_id, result_type);
if (ret != SPV_SUCCESS) return ret;
} else if (supportsCoopMat &&
_.IsCooperativeMatrixKHRType(result_type)) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!_.IsCooperativeMatrixKHRType(type_id) ||
!_.IsFloatCooperativeMatrixType(type_id)) {
@@ -76,17 +91,32 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpUDiv:
case spv::Op::OpUMod: {
bool supportsCoopMat = (opcode == spv::Op::OpUDiv);
bool supportsCoopVec = (opcode == spv::Op::OpUDiv);
if (!_.IsUnsignedIntScalarType(result_type) &&
!_.IsUnsignedIntVectorType(result_type) &&
!(supportsCoopMat &&
_.IsUnsignedIntCooperativeMatrixType(result_type)))
_.IsUnsignedIntCooperativeMatrixType(result_type)) &&
!(supportsCoopVec &&
_.IsUnsignedIntCooperativeVectorNVType(result_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected unsigned int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) {
if (supportsCoopVec && _.IsCooperativeVectorNVType(result_type)) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!_.IsCooperativeVectorNVType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
<< operand_index;
}
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, type_id, result_type);
if (ret != SPV_SUCCESS) return ret;
} else if (supportsCoopMat &&
_.IsCooperativeMatrixKHRType(result_type)) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!_.IsCooperativeMatrixKHRType(type_id) ||
!_.IsUnsignedIntCooperativeMatrixType(type_id)) {
@@ -117,11 +147,14 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
bool supportsCoopMat =
(opcode != spv::Op::OpIMul && opcode != spv::Op::OpSRem &&
opcode != spv::Op::OpSMod);
bool supportsCoopVec =
(opcode != spv::Op::OpSRem && opcode != spv::Op::OpSMod);
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
!(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) &&
!(opcode == spv::Op::OpIMul &&
_.IsCooperativeMatrixKHRType(result_type) &&
_.IsIntCooperativeMatrixType(result_type)))
_.IsIntCooperativeMatrixType(result_type)) &&
!(supportsCoopVec && _.IsIntCooperativeVectorNVType(result_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -133,6 +166,18 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
++operand_index) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (supportsCoopVec && _.IsCooperativeVectorNVType(result_type)) {
if (!_.IsCooperativeVectorNVType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
<< operand_index;
}
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, type_id, result_type);
if (ret != SPV_SUCCESS) return ret;
}
if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) {
if (!_.IsCooperativeMatrixKHRType(type_id) ||
!_.IsIntCooperativeMatrixType(type_id)) {
@@ -151,7 +196,8 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
!(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) &&
!(opcode == spv::Op::OpIMul &&
_.IsCooperativeMatrixKHRType(result_type) &&
_.IsIntCooperativeMatrixType(result_type))))
_.IsIntCooperativeMatrixType(result_type)) &&
!(supportsCoopVec && _.IsIntCooperativeVectorNVType(result_type))))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as operand: "
<< spvOpcodeString(opcode) << " operand index "
@@ -210,7 +256,8 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
}
case spv::Op::OpVectorTimesScalar: {
if (!_.IsFloatVectorType(result_type))
if (!_.IsFloatVectorType(result_type) &&
!_.IsFloatCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected float vector type as Result Type: "
<< spvOpcodeString(opcode);

View File

@@ -64,7 +64,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpShiftRightLogical:
case spv::Op::OpShiftRightArithmetic:
case spv::Op::OpShiftLeftLogical: {
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
!_.IsIntCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -74,7 +75,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
const uint32_t shift_type = _.GetOperandTypeId(inst, 3);
if (!base_type ||
(!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)))
(!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type) &&
!_.IsIntCooperativeVectorNVType(base_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Base to be int scalar or vector: "
<< spvOpcodeString(opcode);
@@ -90,7 +92,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
<< "as Result Type: " << spvOpcodeString(opcode);
if (!shift_type ||
(!_.IsIntScalarType(shift_type) && !_.IsIntVectorType(shift_type)))
(!_.IsIntScalarType(shift_type) && !_.IsIntVectorType(shift_type) &&
!_.IsIntCooperativeVectorNVType(shift_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Shift to be int scalar or vector: "
<< spvOpcodeString(opcode);
@@ -106,7 +109,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpBitwiseXor:
case spv::Op::OpBitwiseAnd:
case spv::Op::OpNot: {
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
!_.IsIntCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -118,7 +122,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
++operand_index) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!type_id ||
(!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id)))
(!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id) &&
!_.IsIntCooperativeVectorNVType(type_id)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector as operand: "
<< spvOpcodeString(opcode) << " operand index "

View File

@@ -122,7 +122,7 @@ typedef enum VUIDError_ {
VUIDErrorMax,
} VUIDError;
const static uint32_t NumVUIDBuiltins = 39;
const static uint32_t NumVUIDBuiltins = 40;
typedef struct {
spv::BuiltIn builtIn;
@@ -172,6 +172,8 @@ std::array<BuiltinVUIDMapping, NumVUIDBuiltins> builtinVUIDInfo = {{
{spv::BuiltIn::PrimitivePointIndicesEXT, {7041, 7043, 7044}},
{spv::BuiltIn::PrimitiveLineIndicesEXT, {7047, 7049, 7050}},
{spv::BuiltIn::PrimitiveTriangleIndicesEXT, {7053, 7055, 7056}},
{spv::BuiltIn::CullPrimitiveEXT, {7034, 7035, 7036}},
// clang-format on
}};
@@ -269,6 +271,9 @@ class BuiltInsValidator {
// specified. Seeds id_to_at_reference_checks_ with decorated ids if needed.
spv_result_t ValidateSingleBuiltInAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateSingleBuiltInAtDefinitionVulkan(
const Decoration& decoration, const Instruction& inst,
const spv::BuiltIn label);
// The following section contains functions which are called when id defined
// by |inst| is decorated with BuiltIn |decoration|.
@@ -671,6 +676,37 @@ class BuiltInsValidator {
// instruction.
void Update(const Instruction& inst);
// Check if "inst" is an interface variable
// or type of a interface varibale of any mesh entry point
bool isMeshInterfaceVar(const Instruction& inst) {
auto getUnderlyingTypeId = [&](const Instruction* ifxVar) {
auto pointerTypeInst = _.FindDef(ifxVar->type_id());
auto typeInst = _.FindDef(pointerTypeInst->GetOperandAs<uint32_t>(2));
while (typeInst->opcode() == spv::Op::OpTypeArray) {
typeInst = _.FindDef(typeInst->GetOperandAs<uint32_t>(1));
};
return typeInst->id();
};
for (const uint32_t entry_point : _.entry_points()) {
const auto* models = _.GetExecutionModels(entry_point);
if (models->find(spv::ExecutionModel::MeshEXT) != models->end() ||
models->find(spv::ExecutionModel::MeshNV) != models->end()) {
for (const auto& desc : _.entry_point_descriptions(entry_point)) {
for (auto interface : desc.interfaces) {
if (inst.opcode() == spv::Op::OpTypeStruct) {
auto varInst = _.FindDef(interface);
if (inst.id() == getUnderlyingTypeId(varInst)) return true;
} else if (inst.id() == interface) {
return true;
}
}
}
}
}
return false;
}
ValidationState_t& _;
// Mapping id -> list of rules which validate instruction referencing the
@@ -2154,6 +2190,17 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtDefinition(
return error;
}
}
if (_.HasCapability(spv::Capability::MeshShadingEXT)) {
if (isMeshInterfaceVar(inst) &&
!_.HasDecoration(inst.id(), spv::Decoration::PerPrimitiveEXT)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7040)
<< "According to the Vulkan spec the variable decorated with "
"Builtin PrimitiveId within the MeshEXT Execution Model must "
"also be decorated with the PerPrimitiveEXT decoration. ";
}
}
}
// Seed at reference checks with this built-in.
@@ -2765,6 +2812,21 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition(
return error;
}
}
if (isMeshInterfaceVar(inst) &&
_.HasCapability(spv::Capability::MeshShadingEXT) &&
!_.HasDecoration(inst.id(), spv::Decoration::PerPrimitiveEXT)) {
const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]);
uint32_t vkerrid = (label == spv::BuiltIn::Layer) ? 7039 : 7060;
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vkerrid)
<< "According to the Vulkan spec the variable decorated with "
"Builtin "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
decoration.params()[0])
<< " within the MeshEXT Execution Model must also be decorated "
"with the PerPrimitiveEXT decoration. ";
}
}
// Seed at reference checks with this built-in.
@@ -3215,16 +3277,8 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition(
spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtDefinition(
const Decoration& decoration, const Instruction& inst) {
// Vulkan requires 32-bit int, but Universal has no restrictions
if (spvIsVulkanEnv(_.context()->target_env)) {
if (spvIsVulkanEnv(_.context()->target_env) &&
!spvOpcodeIsConstant(inst.opcode())) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(4426)
<< "Vulkan spec requires BuiltIn WorkgroupSize to be a "
"constant. "
<< GetIdDesc(inst) << " is not a constant.";
}
if (spv_result_t error = ValidateI32Vec(
decoration, inst, 3,
[this, &inst](const std::string& message) -> spv_result_t {
@@ -3239,6 +3293,34 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtDefinition(
}
}
if (!spvOpcodeIsConstant(inst.opcode())) {
if (spvIsVulkanEnv(_.context()->target_env)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(4426)
<< "Vulkan spec requires BuiltIn WorkgroupSize to be a "
"constant. "
<< GetIdDesc(inst) << " is not a constant.";
}
} else if (inst.opcode() == spv::Op::OpConstantComposite) {
// can only validate product if static and not spec constant
if (_.FindDef(inst.word(3))->opcode() == spv::Op::OpConstant &&
_.FindDef(inst.word(4))->opcode() == spv::Op::OpConstant &&
_.FindDef(inst.word(5))->opcode() == spv::Op::OpConstant) {
uint64_t x_size, y_size, z_size;
// ValidateI32Vec above confirms there will be 3 words to read
bool static_x = _.EvalConstantValUint64(inst.word(3), &x_size);
bool static_y = _.EvalConstantValUint64(inst.word(4), &y_size);
bool static_z = _.EvalConstantValUint64(inst.word(5), &z_size);
if (static_x && static_y && static_z &&
((x_size * y_size * z_size) == 0)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< "WorkgroupSize decorations must not have a static "
"product of zero (X = "
<< x_size << ", Y = " << y_size << ", Z = " << z_size << ").";
}
}
}
// Seed at reference checks with this built-in.
return ValidateWorkgroupSizeAtReference(decoration, inst, inst, inst);
}
@@ -3893,6 +3975,15 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtDefinition(
})) {
return error;
}
if (isMeshInterfaceVar(inst) &&
_.HasCapability(spv::Capability::MeshShadingEXT) &&
!_.HasDecoration(inst.id(), spv::Decoration::PerPrimitiveEXT)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7059)
<< "The variable decorated with PrimitiveShadingRateKHR "
"within the MeshEXT Execution Model must also be "
"decorated with the PerPrimitiveEXT decoration";
}
}
// Seed at reference checks with this built-in.
@@ -3930,7 +4021,7 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference(
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " to be used only with Vertex, Geometry, or MeshNV "
<< " to be used only with Vertex, Geometry, MeshNV or MeshEXT "
"execution models. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
@@ -4190,60 +4281,160 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition(
if (spvIsVulkanEnv(_.context()->target_env)) {
const spv::BuiltIn builtin = decoration.builtin();
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
if (builtin == spv::BuiltIn::PrimitivePointIndicesEXT) {
if (spv_result_t error = ValidateI32Arr(
decoration, inst,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a 32-bit int array."
<< message;
})) {
switch (builtin) {
case spv::BuiltIn::PrimitivePointIndicesEXT:
if (spv_result_t error = ValidateI32Arr(
decoration, inst,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a 32-bit int array."
<< message;
})) {
return error;
}
break;
case spv::BuiltIn::PrimitiveLineIndicesEXT:
if (spv_result_t error = ValidateArrayedI32Vec(
decoration, inst, 2,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a 2-component 32-bit int "
"array."
<< message;
})) {
return error;
}
break;
case spv::BuiltIn::PrimitiveTriangleIndicesEXT:
if (spv_result_t error = ValidateArrayedI32Vec(
decoration, inst, 3,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a 3-component 32-bit int "
"array."
<< message;
})) {
return error;
}
break;
case spv::BuiltIn::CullPrimitiveEXT:
if (spv_result_t error = ValidateBool(
decoration, inst,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a boolean value "
"array."
<< message;
})) {
return error;
}
if (!_.HasDecoration(inst.id(), spv::Decoration::PerPrimitiveEXT)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7038)
<< "The variable decorated with CullPrimitiveEXT within the "
"MeshEXT Execution Model must also be decorated with the "
"PerPrimitiveEXT decoration ";
}
break;
default:
assert(0 && "Unexpected mesh EXT builtin");
}
for (const uint32_t entry_point : _.entry_points()) {
const auto* modes = _.GetExecutionModes(entry_point);
uint64_t maxOutputPrimitives = _.GetOutputPrimitivesEXT(entry_point);
uint32_t underlying_type = 0;
if (spv_result_t error =
GetUnderlyingType(_, decoration, inst, &underlying_type)) {
return error;
}
}
if (builtin == spv::BuiltIn::PrimitiveLineIndicesEXT) {
if (spv_result_t error = ValidateArrayedI32Vec(
decoration, inst, 2,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a 2-component 32-bit int "
"array."
<< message;
})) {
return error;
uint64_t primitiveArrayDim = 0;
if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) {
underlying_type = _.FindDef(underlying_type)->word(3u);
if (!_.EvalConstantValUint64(underlying_type, &primitiveArrayDim)) {
assert(0 && "Array type definition is corrupt");
}
}
}
if (builtin == spv::BuiltIn::PrimitiveTriangleIndicesEXT) {
if (spv_result_t error = ValidateArrayedI32Vec(
decoration, inst, 3,
[this, &inst, &decoration,
&vuid](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN,
(uint32_t)decoration.builtin())
<< " variable needs to be a 3-component 32-bit int "
"array."
<< message;
})) {
return error;
switch (builtin) {
case spv::BuiltIn::PrimitivePointIndicesEXT:
if (!modes || !modes->count(spv::ExecutionMode::OutputPoints)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7042)
<< "The PrimitivePointIndicesEXT decoration must be used "
"with "
"the OutputPoints Execution Mode. ";
}
if (primitiveArrayDim && primitiveArrayDim != maxOutputPrimitives) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7046)
<< "The size of the array decorated with "
"PrimitivePointIndicesEXT must match the value specified "
"by OutputPrimitivesEXT. ";
}
break;
case spv::BuiltIn::PrimitiveLineIndicesEXT:
if (!modes || !modes->count(spv::ExecutionMode::OutputLinesEXT)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7048)
<< "The PrimitiveLineIndicesEXT decoration must be used "
"with "
"the OutputLinesEXT Execution Mode. ";
}
if (primitiveArrayDim && primitiveArrayDim != maxOutputPrimitives) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7052)
<< "The size of the array decorated with "
"PrimitiveLineIndicesEXT must match the value specified "
"by OutputPrimitivesEXT. ";
}
break;
case spv::BuiltIn::PrimitiveTriangleIndicesEXT:
if (!modes || !modes->count(spv::ExecutionMode::OutputTrianglesEXT)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7054)
<< "The PrimitiveTriangleIndicesEXT decoration must be used "
"with "
"the OutputTrianglesEXT Execution Mode. ";
}
if (primitiveArrayDim && primitiveArrayDim != maxOutputPrimitives) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(7058)
<< "The size of the array decorated with "
"PrimitiveTriangleIndicesEXT must match the value "
"specified "
"by OutputPrimitivesEXT. ";
}
break;
default:
break; // no validation rules
}
}
}
@@ -4273,7 +4464,6 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference(
referenced_from_inst)
<< " " << GetStorageClassDesc(referenced_from_inst);
}
for (const spv::ExecutionModel execution_model : execution_models_) {
if (execution_model != spv::ExecutionModel::MeshEXT) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
@@ -4304,18 +4494,20 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference(
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
const Decoration& decoration, const Instruction& inst) {
const spv::BuiltIn label = decoration.builtin();
if (!spvIsVulkanEnv(_.context()->target_env)) {
// Early return. All currently implemented rules are based on Vulkan spec.
//
// TODO: If you are adding validation rules for environments other than
// Vulkan (or general rules which are not environment independent), then
// you need to modify or remove this condition. Consider also adding early
// returns into BuiltIn-specific rules, so that the system doesn't spawn new
// rules which don't do anything.
return SPV_SUCCESS;
// Universial checks
if (label == spv::BuiltIn::WorkgroupSize) {
return ValidateWorkgroupSizeAtDefinition(decoration, inst);
}
if (spvIsVulkanEnv(_.context()->target_env)) {
return ValidateSingleBuiltInAtDefinitionVulkan(decoration, inst, label);
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinitionVulkan(
const Decoration& decoration, const Instruction& inst,
const spv::BuiltIn label) {
// If you are adding a new BuiltIn enum, please register it here.
// If the newly added enum has validation rules associated with it
// consider leaving a TODO and/or creating an issue.
@@ -4407,9 +4599,6 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case spv::BuiltIn::VertexIndex: {
return ValidateVertexIndexAtDefinition(decoration, inst);
}
case spv::BuiltIn::WorkgroupSize: {
return ValidateWorkgroupSizeAtDefinition(decoration, inst);
}
case spv::BuiltIn::VertexId: {
return ValidateVertexIdAtDefinition(decoration, inst);
}
@@ -4476,6 +4665,7 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case spv::BuiltIn::CullMaskKHR: {
return ValidateRayTracingBuiltinsAtDefinition(decoration, inst);
}
case spv::BuiltIn::CullPrimitiveEXT:
case spv::BuiltIn::PrimitivePointIndicesEXT:
case spv::BuiltIn::PrimitiveLineIndicesEXT:
case spv::BuiltIn::PrimitiveTriangleIndicesEXT: {

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2017 Google Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -104,7 +106,8 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _,
}
break;
}
case spv::Op::OpTypeRuntimeArray: {
case spv::Op::OpTypeRuntimeArray:
case spv::Op::OpTypeNodePayloadArrayAMDX: {
*member_type = type_inst->word(2);
// Array size is unknown.
break;
@@ -122,6 +125,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _,
*member_type = type_inst->word(component_index + 2);
break;
}
case spv::Op::OpTypeCooperativeVectorNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeMatrixNV: {
*member_type = type_inst->word(2);
@@ -148,7 +152,8 @@ spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _,
const uint32_t vector_type = _.GetOperandTypeId(inst, 2);
const spv::Op vector_opcode = _.GetIdOpcode(vector_type);
if (vector_opcode != spv::Op::OpTypeVector) {
if (vector_opcode != spv::Op::OpTypeVector &&
vector_opcode != spv::Op::OpTypeCooperativeVectorNV) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Vector type to be OpTypeVector";
}
@@ -176,7 +181,8 @@ spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _,
const Instruction* inst) {
const uint32_t result_type = inst->type_id();
const spv::Op result_opcode = _.GetIdOpcode(result_type);
if (result_opcode != spv::Op::OpTypeVector) {
if (result_opcode != spv::Op::OpTypeVector &&
result_opcode != spv::Op::OpTypeCooperativeVectorNV) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Result Type to be OpTypeVector";
}
@@ -214,14 +220,24 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _,
const uint32_t result_type = inst->type_id();
const spv::Op result_opcode = _.GetIdOpcode(result_type);
switch (result_opcode) {
case spv::Op::OpTypeVector: {
const uint32_t num_result_components = _.GetDimension(result_type);
case spv::Op::OpTypeVector:
case spv::Op::OpTypeCooperativeVectorNV: {
uint32_t num_result_components = _.GetDimension(result_type);
const uint32_t result_component_type = _.GetComponentType(result_type);
uint32_t given_component_count = 0;
if (num_operands <= 3) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected number of constituents to be at least 2";
bool comp_is_int32 = true, comp_is_const_int32 = true;
if (result_opcode == spv::Op::OpTypeVector) {
if (num_operands <= 3) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected number of constituents to be at least 2";
}
} else {
uint32_t comp_count_id =
_.FindDef(result_type)->GetOperandAs<uint32_t>(2);
std::tie(comp_is_int32, comp_is_const_int32, num_result_components) =
_.EvalInt32IfConst(comp_count_id);
}
for (uint32_t operand_index = 2; operand_index < num_operands;
@@ -241,7 +257,8 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _,
}
}
if (num_result_components != given_component_count) {
if (comp_is_const_int32 &&
num_result_components != given_component_count) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected total number of given components to be equal "
<< "to the size of Result Type vector";

View File

@@ -46,9 +46,18 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _,
const auto constituent_count = inst->words().size() - 3;
switch (result_type->opcode()) {
case spv::Op::OpTypeVector: {
const auto component_count = result_type->GetOperandAs<uint32_t>(2);
if (component_count != constituent_count) {
case spv::Op::OpTypeVector:
case spv::Op::OpTypeCooperativeVectorNV: {
uint32_t num_result_components = _.GetDimension(result_type->id());
bool comp_is_int32 = true, comp_is_const_int32 = true;
if (result_type->opcode() == spv::Op::OpTypeCooperativeVectorNV) {
uint32_t comp_count_id = result_type->GetOperandAs<uint32_t>(2);
std::tie(comp_is_int32, comp_is_const_int32, num_result_components) =
_.EvalInt32IfConst(comp_count_id);
}
if (comp_is_const_int32 && num_result_components != constituent_count) {
// TODO: Output ID's on diagnostic
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name
@@ -312,6 +321,7 @@ bool IsTypeNullable(const std::vector<uint32_t>& instruction,
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
case spv::Op::OpTypeVector: {
auto base_type = _.FindDef(instruction[2]);
return base_type && IsTypeNullable(base_type->words(), _);

View File

@@ -33,7 +33,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpConvertFToU: {
if (!_.IsUnsignedIntScalarType(result_type) &&
!_.IsUnsignedIntVectorType(result_type) &&
!_.IsUnsignedIntCooperativeMatrixType(result_type))
!_.IsUnsignedIntCooperativeMatrixType(result_type) &&
!_.IsUnsignedIntCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected unsigned int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -41,13 +42,19 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t input_type = _.GetOperandTypeId(inst, 2);
if (!input_type || (!_.IsFloatScalarType(input_type) &&
!_.IsFloatVectorType(input_type) &&
!_.IsFloatCooperativeMatrixType(input_type)))
!_.IsFloatCooperativeMatrixType(input_type) &&
!_.IsFloatCooperativeVectorNVType(input_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be float scalar or vector: "
<< spvOpcodeString(opcode);
if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
if (_.IsCooperativeVectorNVType(result_type) ||
_.IsCooperativeVectorNVType(input_type)) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
} else if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
spv_result_t ret =
_.CooperativeMatrixShapesMatch(inst, result_type, input_type, true);
if (ret != SPV_SUCCESS) return ret;
@@ -63,7 +70,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpConvertFToS: {
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
!_.IsIntCooperativeMatrixType(result_type))
!_.IsIntCooperativeMatrixType(result_type) &&
!_.IsIntCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -71,13 +79,19 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t input_type = _.GetOperandTypeId(inst, 2);
if (!input_type || (!_.IsFloatScalarType(input_type) &&
!_.IsFloatVectorType(input_type) &&
!_.IsFloatCooperativeMatrixType(input_type)))
!_.IsFloatCooperativeMatrixType(input_type) &&
!_.IsFloatCooperativeVectorNVType(input_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be float scalar or vector: "
<< spvOpcodeString(opcode);
if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
if (_.IsCooperativeVectorNVType(result_type) ||
_.IsCooperativeVectorNVType(input_type)) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
} else if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
spv_result_t ret =
_.CooperativeMatrixShapesMatch(inst, result_type, input_type, true);
if (ret != SPV_SUCCESS) return ret;
@@ -95,7 +109,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpConvertUToF: {
if (!_.IsFloatScalarType(result_type) &&
!_.IsFloatVectorType(result_type) &&
!_.IsFloatCooperativeMatrixType(result_type))
!_.IsFloatCooperativeMatrixType(result_type) &&
!_.IsFloatCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected float scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -103,13 +118,19 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t input_type = _.GetOperandTypeId(inst, 2);
if (!input_type ||
(!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) &&
!_.IsIntCooperativeMatrixType(input_type)))
!_.IsIntCooperativeMatrixType(input_type) &&
!_.IsIntCooperativeVectorNVType(input_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be int scalar or vector: "
<< spvOpcodeString(opcode);
if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
if (_.IsCooperativeVectorNVType(result_type) ||
_.IsCooperativeVectorNVType(input_type)) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
} else if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
spv_result_t ret =
_.CooperativeMatrixShapesMatch(inst, result_type, input_type, true);
if (ret != SPV_SUCCESS) return ret;
@@ -126,7 +147,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpUConvert: {
if (!_.IsUnsignedIntScalarType(result_type) &&
!_.IsUnsignedIntVectorType(result_type) &&
!_.IsUnsignedIntCooperativeMatrixType(result_type))
!_.IsUnsignedIntCooperativeMatrixType(result_type) &&
!_.IsUnsignedIntCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected unsigned int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -134,13 +156,19 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t input_type = _.GetOperandTypeId(inst, 2);
if (!input_type ||
(!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) &&
!_.IsIntCooperativeMatrixType(input_type)))
!_.IsIntCooperativeMatrixType(input_type) &&
!_.IsIntCooperativeVectorNVType(input_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be int scalar or vector: "
<< spvOpcodeString(opcode);
if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
if (_.IsCooperativeVectorNVType(result_type) ||
_.IsCooperativeVectorNVType(input_type)) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
} else if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
spv_result_t ret =
_.CooperativeMatrixShapesMatch(inst, result_type, input_type, true);
if (ret != SPV_SUCCESS) return ret;
@@ -161,7 +189,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpSConvert: {
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
!_.IsIntCooperativeMatrixType(result_type))
!_.IsIntCooperativeMatrixType(result_type) &&
!_.IsIntCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -169,13 +198,19 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t input_type = _.GetOperandTypeId(inst, 2);
if (!input_type ||
(!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) &&
!_.IsIntCooperativeMatrixType(input_type)))
!_.IsIntCooperativeMatrixType(input_type) &&
!_.IsIntCooperativeVectorNVType(input_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be int scalar or vector: "
<< spvOpcodeString(opcode);
if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
if (_.IsCooperativeVectorNVType(result_type) ||
_.IsCooperativeVectorNVType(input_type)) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
} else if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
spv_result_t ret =
_.CooperativeMatrixShapesMatch(inst, result_type, input_type, true);
if (ret != SPV_SUCCESS) return ret;
@@ -197,7 +232,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpFConvert: {
if (!_.IsFloatScalarType(result_type) &&
!_.IsFloatVectorType(result_type) &&
!_.IsFloatCooperativeMatrixType(result_type))
!_.IsFloatCooperativeMatrixType(result_type) &&
!_.IsFloatCooperativeVectorNVType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected float scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -205,13 +241,19 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t input_type = _.GetOperandTypeId(inst, 2);
if (!input_type || (!_.IsFloatScalarType(input_type) &&
!_.IsFloatVectorType(input_type) &&
!_.IsFloatCooperativeMatrixType(input_type)))
!_.IsFloatCooperativeMatrixType(input_type) &&
!_.IsFloatCooperativeVectorNVType(input_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be float scalar or vector: "
<< spvOpcodeString(opcode);
if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
if (_.IsCooperativeVectorNVType(result_type) ||
_.IsCooperativeVectorNVType(input_type)) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
} else if (_.IsCooperativeMatrixType(result_type) ||
_.IsCooperativeMatrixType(input_type)) {
spv_result_t ret =
_.CooperativeMatrixShapesMatch(inst, result_type, input_type, true);
if (ret != SPV_SUCCESS) return ret;
@@ -475,9 +517,11 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const bool result_is_coopmat = _.IsCooperativeMatrixType(result_type);
const bool input_is_coopmat = _.IsCooperativeMatrixType(input_type);
const bool result_is_coopvec = _.IsCooperativeVectorNVType(result_type);
const bool input_is_coopvec = _.IsCooperativeVectorNVType(input_type);
if (!result_is_pointer && !result_is_int_scalar && !result_is_coopmat &&
!_.IsIntVectorType(result_type) &&
!result_is_coopvec && !_.IsIntVectorType(result_type) &&
!_.IsFloatScalarType(result_type) &&
!_.IsFloatVectorType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -485,17 +529,28 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
<< "or scalar type: " << spvOpcodeString(opcode);
if (!input_is_pointer && !input_is_int_scalar && !input_is_coopmat &&
!_.IsIntVectorType(input_type) && !_.IsFloatScalarType(input_type) &&
!_.IsFloatVectorType(input_type))
!input_is_coopvec && !_.IsIntVectorType(input_type) &&
!_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be a pointer or int or float vector "
<< "or scalar: " << spvOpcodeString(opcode);
if (result_is_coopvec != input_is_coopvec)
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Cooperative vector can only be cast to another cooperative "
<< "vector: " << spvOpcodeString(opcode);
if (result_is_coopmat != input_is_coopmat)
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Cooperative matrix can only be cast to another cooperative "
<< "matrix: " << spvOpcodeString(opcode);
if (result_is_coopvec) {
spv_result_t ret =
_.CooperativeVectorDimensionsMatch(inst, result_type, input_type);
if (ret != SPV_SUCCESS) return ret;
}
if (result_is_coopmat) {
spv_result_t ret = _.CooperativeMatrixShapesMatch(inst, result_type,
input_type, false);

View File

@@ -767,6 +767,7 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
int num_workgroup_variables = 0;
int num_workgroup_variables_with_block = 0;
int num_workgroup_variables_with_aliased = 0;
bool has_task_payload = false;
for (const auto& desc : descs) {
std::unordered_set<Instruction*> seen_vars;
std::unordered_set<spv::BuiltIn> input_var_builtin;
@@ -786,6 +787,19 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
const auto sc_index = 2u;
const spv::StorageClass storage_class =
var_instr->GetOperandAs<spv::StorageClass>(sc_index);
if (vstate.version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
// SPV_EXT_mesh_shader, at most one task payload is permitted
// per entry point
if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) {
if (has_task_payload) {
return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
<< "There can be at most one OpVariable with storage "
"class TaskPayloadWorkgroupEXT associated with "
"an OpEntryPoint";
}
has_task_payload = true;
}
}
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.
@@ -1450,11 +1464,29 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
: (sc == spv::StorageClass::Workgroup ? "Workgroup"
: "StorageBuffer"));
const auto data_type = vstate.FindDef(data_type_id);
auto data_type = vstate.FindDef(data_type_id);
scalar_block_layout =
sc == spv::StorageClass::Workgroup
? vstate.options()->workgroup_scalar_block_layout
: vstate.options()->scalar_block_layout;
// If the data type is an array that contains a Block- or
// BufferBlock-decorated struct, then use the struct for layout checks
// instead of the array. In this case, the array represents a descriptor
// array which should not have an explicit layout.
if (data_type->opcode() == spv::Op::OpTypeArray ||
data_type->opcode() == spv::Op::OpTypeRuntimeArray) {
const auto ele_type =
vstate.FindDef(data_type->GetOperandAs<uint32_t>(1u));
if (ele_type->opcode() == spv::Op::OpTypeStruct &&
(vstate.HasDecoration(ele_type->id(), spv::Decoration::Block) ||
vstate.HasDecoration(ele_type->id(),
spv::Decoration::BufferBlock))) {
data_type = ele_type;
data_type_id = ele_type->id();
}
}
// Assume uniform storage class uses block rules unless we see a
// BufferBlock decorated struct in the data type.
bool bufferRules = sc == spv::StorageClass::Uniform ? false : true;
@@ -1500,7 +1532,8 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) {
// to the same id.
static const spv::Decoration mutually_exclusive_per_id[][2] = {
{spv::Decoration::Block, spv::Decoration::BufferBlock},
{spv::Decoration::Restrict, spv::Decoration::Aliased}};
{spv::Decoration::Restrict, spv::Decoration::Aliased},
{spv::Decoration::RestrictPointer, spv::Decoration::AliasedPointer}};
static const auto num_mutually_exclusive_per_id_pairs =
sizeof(mutually_exclusive_per_id) / (2 * sizeof(spv::Decoration));

View File

@@ -1057,7 +1057,10 @@ spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) {
if (extension ==
ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) ||
extension == ExtensionToString(kSPV_EXT_mesh_shader) ||
extension == ExtensionToString(kSPV_NV_shader_invocation_reorder)) {
extension == ExtensionToString(kSPV_NV_shader_invocation_reorder) ||
extension ==
ExtensionToString(kSPV_NV_cluster_acceleration_structure) ||
extension == ExtensionToString(kSPV_NV_linear_swept_spheres)) {
return _.diag(SPV_ERROR_WRONG_VERSION, inst)
<< extension << " extension requires SPIR-V version 1.4 or later.";
}
@@ -1136,7 +1139,16 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
case GLSLstd450NMin:
case GLSLstd450NMax:
case GLSLstd450NClamp: {
if (!_.IsFloatScalarOrVectorType(result_type)) {
bool supportsCoopVec =
(ext_inst_key == GLSLstd450FMin || ext_inst_key == GLSLstd450FMax ||
ext_inst_key == GLSLstd450FClamp ||
ext_inst_key == GLSLstd450NMin || ext_inst_key == GLSLstd450NMax ||
ext_inst_key == GLSLstd450NClamp ||
ext_inst_key == GLSLstd450Step || ext_inst_key == GLSLstd450Fma);
if (!_.IsFloatScalarOrVectorType(result_type) &&
!(supportsCoopVec &&
_.IsFloatCooperativeVectorNVType(result_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be a float scalar or vector type";
@@ -1166,7 +1178,14 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
case GLSLstd450FindILsb:
case GLSLstd450FindUMsb:
case GLSLstd450FindSMsb: {
if (!_.IsIntScalarOrVectorType(result_type)) {
bool supportsCoopVec =
(ext_inst_key == GLSLstd450UMin || ext_inst_key == GLSLstd450UMax ||
ext_inst_key == GLSLstd450UClamp ||
ext_inst_key == GLSLstd450SMin || ext_inst_key == GLSLstd450SMax ||
ext_inst_key == GLSLstd450SClamp);
if (!_.IsIntScalarOrVectorType(result_type) &&
!(supportsCoopVec && _.IsIntCooperativeVectorNVType(result_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be an int scalar or vector type";
@@ -1178,7 +1197,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
for (uint32_t operand_index = 4; operand_index < num_operands;
++operand_index) {
const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
if (!operand_type || !_.IsIntScalarOrVectorType(operand_type)) {
if (!operand_type ||
(!_.IsIntScalarOrVectorType(operand_type) &&
!(supportsCoopVec &&
_.IsIntCooperativeVectorNVType(operand_type)))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected all operands to be int scalars or vectors";
@@ -1231,7 +1253,13 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
case GLSLstd450Log2:
case GLSLstd450Atan2:
case GLSLstd450Pow: {
if (!_.IsFloatScalarOrVectorType(result_type)) {
bool supportsCoopVec =
(ext_inst_key == GLSLstd450Atan || ext_inst_key == GLSLstd450Tanh ||
ext_inst_key == GLSLstd450Exp || ext_inst_key == GLSLstd450Log);
if (!_.IsFloatScalarOrVectorType(result_type) &&
!(supportsCoopVec &&
_.IsFloatCooperativeVectorNVType(result_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be a 16 or 32-bit scalar or "

View File

@@ -152,80 +152,6 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _,
"type of the same index.";
}
// 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) == spv::Op::OpTypeArray) {
param_nonarray_type_id =
_.FindDef(param_nonarray_type_id)->GetOperandAs<uint32_t>(1u);
}
if (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypePointer ||
_.GetIdOpcode(param_nonarray_type_id) ==
spv::Op::OpTypeUntypedPointerKHR) {
auto param_nonarray_type = _.FindDef(param_nonarray_type_id);
if (param_nonarray_type->GetOperandAs<spv::StorageClass>(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 spv::Decoration::Aliased == d.dec_type();
});
bool foundRestrict = std::any_of(
decorations.begin(), decorations.end(), [](const Decoration& d) {
return spv::Decoration::Restrict == d.dec_type();
});
if (!foundAliased && !foundRestrict) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpFunctionParameter " << inst->id()
<< ": expected Aliased or Restrict for PhysicalStorageBuffer "
"pointer.";
}
if (foundAliased && foundRestrict) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpFunctionParameter " << inst->id()
<< ": can't specify both Aliased and Restrict for "
"PhysicalStorageBuffer pointer.";
}
} else if (param_nonarray_type->opcode() == spv::Op::OpTypePointer) {
const auto pointee_type_id =
param_nonarray_type->GetOperandAs<uint32_t>(2);
const auto pointee_type = _.FindDef(pointee_type_id);
if (spv::Op::OpTypePointer == pointee_type->opcode() &&
pointee_type->GetOperandAs<spv::StorageClass>(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 spv::Decoration::AliasedPointer == d.dec_type();
});
bool foundRestrict = std::any_of(
decorations.begin(), decorations.end(), [](const Decoration& d) {
return spv::Decoration::RestrictPointer == d.dec_type();
});
if (!foundAliased && !foundRestrict) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpFunctionParameter " << inst->id()
<< ": expected AliasedPointer or RestrictPointer for "
"PhysicalStorageBuffer pointer.";
}
if (foundAliased && foundRestrict) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpFunctionParameter " << inst->id()
<< ": can't specify both AliasedPointer and "
"RestrictPointer for PhysicalStorageBuffer pointer.";
}
}
}
}
return SPV_SUCCESS;
}

View File

@@ -455,13 +455,14 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
}
if (!_.options()->before_hlsl_legalization &&
spvIsVulkanEnv(_.context()->target_env)) {
spvIsVulkanEnv(_.context()->target_env) &&
!_.options()->allow_offset_texture_operand) {
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)
<< _.VkErrorID(10213)
<< "Image Operand Offset can only be used with "
"OpImage*Gather operations";
}

View File

@@ -481,6 +481,10 @@ spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) {
spv::ExecutionMode::LocalSizeId) {
_.RegisterEntryPointLocalSize(entry_point, inst);
}
if (inst->GetOperandAs<spv::ExecutionMode>(1) ==
spv::ExecutionMode::OutputPrimitivesEXT) {
_.RegisterEntryPointOutputPrimitivesEXT(entry_point, inst);
}
} else if (opcode == spv::Op::OpVariable) {
const auto storage_class = inst->GetOperandAs<spv::StorageClass>(2);
if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) {

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2018 Google LLC.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
// reserved.
// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All
// rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -196,37 +196,6 @@ bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage,
return false;
}
bool ContainsCooperativeMatrix(ValidationState_t& _,
const Instruction* storage) {
const size_t elem_type_index = 1;
uint32_t elem_type_id;
Instruction* elem_type;
switch (storage->opcode()) {
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
return true;
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray:
elem_type_id = storage->GetOperandAs<uint32_t>(elem_type_index);
elem_type = _.FindDef(elem_type_id);
return ContainsCooperativeMatrix(_, elem_type);
case spv::Op::OpTypeStruct:
for (size_t member_type_index = 1;
member_type_index < storage->operands().size();
++member_type_index) {
auto member_type_id =
storage->GetOperandAs<uint32_t>(member_type_index);
auto member_type = _.FindDef(member_type_id);
if (ContainsCooperativeMatrix(_, member_type)) return true;
}
break;
default:
break;
}
return false;
}
std::pair<spv::StorageClass, spv::StorageClass> GetStorageClass(
ValidationState_t& _, const Instruction* inst) {
spv::StorageClass dst_sc = spv::StorageClass::Max;
@@ -235,6 +204,7 @@ std::pair<spv::StorageClass, spv::StorageClass> GetStorageClass(
case spv::Op::OpCooperativeMatrixLoadNV:
case spv::Op::OpCooperativeMatrixLoadTensorNV:
case spv::Op::OpCooperativeMatrixLoadKHR:
case spv::Op::OpCooperativeVectorLoadNV:
case spv::Op::OpLoad: {
auto load_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(2));
auto load_pointer_type = _.FindDef(load_pointer->type_id());
@@ -244,6 +214,7 @@ std::pair<spv::StorageClass, spv::StorageClass> GetStorageClass(
case spv::Op::OpCooperativeMatrixStoreNV:
case spv::Op::OpCooperativeMatrixStoreTensorNV:
case spv::Op::OpCooperativeMatrixStoreKHR:
case spv::Op::OpCooperativeVectorStoreNV:
case spv::Op::OpStore: {
auto store_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(0));
auto store_pointer_type = _.FindDef(store_pointer->type_id());
@@ -280,8 +251,9 @@ int MemoryAccessNumWords(uint32_t mask) {
// Returns the scope ID operand for MakeAvailable memory access with mask
// at the given operand index.
// This function is only called for OpLoad, OpStore, OpCopyMemory and
// OpCopyMemorySized, OpCooperativeMatrixLoadNV, and
// OpCooperativeMatrixStoreNV.
// OpCopyMemorySized, OpCooperativeMatrixLoadNV,
// OpCooperativeMatrixStoreNV, OpCooperativeVectorLoadNV,
// OpCooperativeVectorStoreNV.
uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask,
uint32_t mask_index) {
assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR));
@@ -292,8 +264,9 @@ uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask,
}
// This function is only called for OpLoad, OpStore, OpCopyMemory,
// OpCopyMemorySized, OpCooperativeMatrixLoadNV, and
// OpCooperativeMatrixStoreNV.
// OpCopyMemorySized, OpCooperativeMatrixLoadNV,
// OpCooperativeMatrixStoreNV, OpCooperativeVectorLoadNV,
// OpCooperativeVectorStoreNV.
uint32_t GetMakeVisibleScope(const Instruction* inst, uint32_t mask,
uint32_t mask_index) {
assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR));
@@ -333,7 +306,8 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
if (inst->opcode() == spv::Op::OpLoad ||
inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV ||
inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV ||
inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR ||
inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "MakePointerAvailableKHR cannot be used with OpLoad.";
}
@@ -354,7 +328,8 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
if (inst->opcode() == spv::Op::OpStore ||
inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV ||
inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR ||
inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV) {
inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV ||
inst->opcode() == spv::Op::OpCooperativeVectorStoreNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "MakePointerVisibleKHR cannot be used with OpStore.";
}
@@ -496,7 +471,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
storage_class != spv::StorageClass::CallableDataKHR &&
storage_class != spv::StorageClass::IncomingCallableDataKHR &&
storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT &&
storage_class != spv::StorageClass::HitObjectAttributeNV) {
storage_class != spv::StorageClass::HitObjectAttributeNV &&
storage_class != spv::StorageClass::NodePayloadAMDX) {
bool storage_input_or_output = storage_class == spv::StorageClass::Input ||
storage_class == spv::StorageClass::Output;
bool builtin = false;
@@ -524,7 +500,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
"Classes: Workgroup, CrossWorkgroup, Private, Function, "
"Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, "
"HitAttributeKHR, CallableDataKHR, "
"IncomingCallableDataKHR, or UniformConstant";
"IncomingCallableDataKHR, NodePayloadAMDX, or "
"UniformConstant";
}
}
}
@@ -725,33 +702,6 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
<< "PhysicalStorageBuffer must not be used with OpVariable.";
}
auto pointee_base = pointee;
while (pointee_base && pointee_base->opcode() == spv::Op::OpTypeArray) {
pointee_base = _.FindDef(pointee_base->GetOperandAs<uint32_t>(1u));
}
if (pointee_base && pointee_base->opcode() == spv::Op::OpTypePointer) {
if (pointee_base->GetOperandAs<spv::StorageClass>(1u) ==
spv::StorageClass::PhysicalStorageBuffer) {
// check for AliasedPointer/RestrictPointer
bool foundAliased =
_.HasDecoration(inst->id(), spv::Decoration::AliasedPointer);
bool foundRestrict =
_.HasDecoration(inst->id(), spv::Decoration::RestrictPointer);
if (!foundAliased && !foundRestrict) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpVariable " << inst->id()
<< ": expected AliasedPointer or RestrictPointer for "
<< "PhysicalStorageBuffer pointer.";
}
if (foundAliased && foundRestrict) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpVariable " << inst->id()
<< ": can't specify both AliasedPointer and "
<< "RestrictPointer for PhysicalStorageBuffer pointer.";
}
}
}
// Vulkan specific validation rules for OpTypeRuntimeArray
if (spvIsVulkanEnv(_.context()->target_env)) {
// OpTypeRuntimeArray should only ever be in a container like OpTypeStruct,
@@ -819,7 +769,12 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
// Cooperative matrix types can only be allocated in Function or Private
if ((storage_class != spv::StorageClass::Function &&
storage_class != spv::StorageClass::Private) &&
pointee && ContainsCooperativeMatrix(_, pointee)) {
pointee &&
_.ContainsType(pointee->id(), [](const Instruction* type_inst) {
auto opcode = type_inst->opcode();
return opcode == spv::Op::OpTypeCooperativeMatrixNV ||
opcode == spv::Op::OpTypeCooperativeMatrixKHR;
})) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Cooperative matrix types (or types containing them) can only be "
"allocated "
@@ -827,6 +782,20 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
"parameters";
}
if ((storage_class != spv::StorageClass::Function &&
storage_class != spv::StorageClass::Private) &&
pointee &&
_.ContainsType(pointee->id(), [](const Instruction* type_inst) {
auto opcode = type_inst->opcode();
return opcode == spv::Op::OpTypeCooperativeVectorNV;
})) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Cooperative vector types (or types containing them) can only be "
"allocated "
<< "in Function or Private storage classes or as function "
"parameters";
}
if (_.HasCapability(spv::Capability::Shader)) {
// Don't allow variables containing 16-bit elements without the appropriate
// capabilities.
@@ -1595,12 +1564,15 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
switch (type_pointee->opcode()) {
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeCooperativeVectorNV:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray: {
case spv::Op::OpTypeRuntimeArray:
case spv::Op::OpTypeNodePayloadArrayAMDX: {
// In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV,
// OpTypeArray, and OpTypeRuntimeArray, word 2 is the Element Type.
// OpTypeCooperativeVectorNV, OpTypeArray, and OpTypeRuntimeArray, word
// 2 is the Element Type.
type_pointee = _.FindDef(type_pointee->word(2));
break;
}
@@ -1609,9 +1581,10 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
// index: the index must be an OpConstant.
int64_t cur_index;
if (!_.EvalConstantValInt64(cur_word, &cur_index)) {
return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr)
<< "The <id> passed to " << instr_name
<< " to index into a "
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "The <id> passed to " << instr_name << " to index "
<< _.getIdName(cur_word)
<< " into a "
"structure must be an OpConstant.";
}
@@ -1620,10 +1593,10 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
const int64_t num_struct_members =
static_cast<int64_t>(type_pointee->words().size() - 2);
if (cur_index >= num_struct_members || cur_index < 0) {
return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr)
<< "Index is out of bounds: " << instr_name
<< " cannot find index " << cur_index
<< " into the structure <id> "
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Index " << _.getIdName(cur_word)
<< " is out of bounds: " << instr_name << " cannot find index "
<< cur_index << " into the structure <id> "
<< _.getIdName(type_pointee->id()) << ". This structure has "
<< num_struct_members << " members. Largest valid index is "
<< num_struct_members - 1 << ".";
@@ -2398,6 +2371,392 @@ spv_result_t ValidateCooperativeMatrixLoadStoreTensorNV(
return SPV_SUCCESS;
}
spv_result_t ValidateInt32Operand(ValidationState_t& _, const Instruction* inst,
uint32_t operand_index,
const char* opcode_name,
const char* operand_name) {
const auto type_id =
_.FindDef(inst->GetOperandAs<uint32_t>(operand_index))->type_id();
if (!_.IsIntScalarType(type_id) || _.GetBitWidth(type_id) != 32) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " " << operand_name << " type <id> "
<< _.getIdName(type_id) << " is not a 32 bit integer.";
}
return SPV_SUCCESS;
}
spv_result_t ValidateCooperativeVectorPointer(ValidationState_t& _,
const Instruction* inst,
const char* opname,
uint32_t pointer_index) {
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
const auto pointer = _.FindDef(pointer_id);
if (!pointer ||
((_.addressing_model() == spv::AddressingModel::Logical) &&
((!_.features().variable_pointers &&
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
(_.features().variable_pointers &&
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opname << " Pointer <id> " << _.getIdName(pointer_id)
<< " is not a logical pointer.";
}
const auto pointer_type_id = pointer->type_id();
const auto pointer_type = _.FindDef(pointer_type_id);
if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opname << " type for pointer <id> " << _.getIdName(pointer_id)
<< " is not a pointer type.";
}
const auto storage_class_index = 1u;
const auto storage_class =
pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);
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 <id> "
<< _.getIdName(pointer_type_id)
<< " is not Workgroup or StorageBuffer.";
}
const auto pointee_id = pointer_type->GetOperandAs<uint32_t>(2);
const auto pointee_type = _.FindDef(pointee_id);
if (!pointee_type ||
(pointee_type->opcode() != spv::Op::OpTypeArray &&
pointee_type->opcode() != spv::Op::OpTypeRuntimeArray)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opname << " Pointer <id> " << _.getIdName(pointer->id())
<< "s Type must be an array type.";
}
const auto array_elem_type_id = pointee_type->GetOperandAs<uint32_t>(1);
auto array_elem_type = _.FindDef(array_elem_type_id);
if (!array_elem_type || !(_.IsIntScalarOrVectorType(array_elem_type_id) ||
_.IsFloatScalarOrVectorType(array_elem_type_id))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opname << " Pointer <id> " << _.getIdName(pointer->id())
<< "s Type must be an array of scalar or vector type.";
}
return SPV_SUCCESS;
}
spv_result_t ValidateCooperativeVectorLoadStoreNV(ValidationState_t& _,
const Instruction* inst) {
uint32_t type_id;
const char* opname;
if (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) {
type_id = inst->type_id();
opname = "spv::Op::OpCooperativeVectorLoadNV";
} else {
// get Object operand's type
type_id = _.FindDef(inst->GetOperandAs<uint32_t>(2))->type_id();
opname = "spv::Op::OpCooperativeVectorStoreNV";
}
auto vector_type = _.FindDef(type_id);
if (vector_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
if (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "spv::Op::OpCooperativeVectorLoadNV Result Type <id> "
<< _.getIdName(type_id) << " is not a cooperative vector type.";
} else {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "spv::Op::OpCooperativeVectorStoreNV Object type <id> "
<< _.getIdName(type_id) << " is not a cooperative vector type.";
}
}
const auto pointer_index =
(inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) ? 2u : 0u;
if (auto error =
ValidateCooperativeVectorPointer(_, inst, opname, pointer_index)) {
return error;
}
const auto memory_access_index =
(inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) ? 4u : 3u;
if (inst->operands().size() > memory_access_index) {
if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
return error;
}
return SPV_SUCCESS;
}
spv_result_t ValidateCooperativeVectorOuterProductNV(ValidationState_t& _,
const Instruction* inst) {
const auto pointer_index = 0u;
const auto opcode_name =
"spv::Op::OpCooperativeVectorOuterProductAccumulateNV";
if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
pointer_index)) {
return error;
}
auto type_id = _.FindDef(inst->GetOperandAs<uint32_t>(2))->type_id();
auto a_type = _.FindDef(type_id);
if (a_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " A type <id> " << _.getIdName(type_id)
<< " is not a cooperative vector type.";
}
type_id = _.FindDef(inst->GetOperandAs<uint32_t>(3))->type_id();
auto b_type = _.FindDef(type_id);
if (b_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " B type <id> " << _.getIdName(type_id)
<< " is not a cooperative vector type.";
}
const auto a_component_type_id = a_type->GetOperandAs<uint32_t>(1);
const auto b_component_type_id = b_type->GetOperandAs<uint32_t>(1);
if (a_component_type_id != b_component_type_id) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " A and B component types "
<< _.getIdName(a_component_type_id) << " and "
<< _.getIdName(b_component_type_id) << " do not match.";
}
if (auto error = ValidateInt32Operand(_, inst, 1, opcode_name, "Offset")) {
return error;
}
if (auto error =
ValidateInt32Operand(_, inst, 4, opcode_name, "MemoryLayout")) {
return error;
}
if (auto error = ValidateInt32Operand(_, inst, 5, opcode_name,
"MatrixInterpretation")) {
return error;
}
if (inst->operands().size() > 6) {
if (auto error =
ValidateInt32Operand(_, inst, 6, opcode_name, "MatrixStride")) {
return error;
}
}
return SPV_SUCCESS;
}
spv_result_t ValidateCooperativeVectorReduceSumNV(ValidationState_t& _,
const Instruction* inst) {
const auto opcode_name = "spv::Op::OpCooperativeVectorReduceSumAccumulateNV";
const auto pointer_index = 0u;
if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
pointer_index)) {
return error;
}
auto type_id = _.FindDef(inst->GetOperandAs<uint32_t>(2))->type_id();
auto v_type = _.FindDef(type_id);
if (v_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " V type <id> " << _.getIdName(type_id)
<< " is not a cooperative vector type.";
}
if (auto error = ValidateInt32Operand(_, inst, 1, opcode_name, "Offset")) {
return error;
}
return SPV_SUCCESS;
}
bool InterpretationIsPacked(spv::ComponentType interp) {
switch (interp) {
case spv::ComponentType::SignedInt8PackedNV:
case spv::ComponentType::UnsignedInt8PackedNV:
return true;
default:
return false;
}
}
using std::get;
spv_result_t ValidateCooperativeVectorMatrixMulNV(ValidationState_t& _,
const Instruction* inst) {
const bool has_bias =
inst->opcode() == spv::Op::OpCooperativeVectorMatrixMulAddNV;
const auto opcode_name = has_bias
? "spv::Op::OpCooperativeVectorMatrixMulAddNV"
: "spv::Op::OpCooperativeVectorMatrixMulNV";
const auto bias_offset = has_bias ? 3 : 0;
const auto result_type_index = 0u;
const auto input_index = 2u;
const auto input_interpretation_index = 3u;
const auto matrix_index = 4u;
const auto matrix_interpretation_index = 6u;
const auto bias_index = 7u;
const auto bias_interpretation_index = 9u;
const auto m_index = 7u + bias_offset;
const auto k_index = 8u + bias_offset;
const auto memory_layout_index = 9u + bias_offset;
const auto transpose_index = 10u + bias_offset;
const auto result_type_id = inst->GetOperandAs<uint32_t>(result_type_index);
const auto input_id = inst->GetOperandAs<uint32_t>(input_index);
const auto input_interpretation_id =
inst->GetOperandAs<uint32_t>(input_interpretation_index);
const auto matrix_interpretation_id =
inst->GetOperandAs<uint32_t>(matrix_interpretation_index);
const auto bias_interpretation_id =
inst->GetOperandAs<uint32_t>(bias_interpretation_index);
const auto m_id = inst->GetOperandAs<uint32_t>(m_index);
const auto k_id = inst->GetOperandAs<uint32_t>(k_index);
const auto memory_layout_id =
inst->GetOperandAs<uint32_t>(memory_layout_index);
const auto transpose_id = inst->GetOperandAs<uint32_t>(transpose_index);
if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
matrix_index)) {
return error;
}
if (inst->opcode() == spv::Op::OpCooperativeVectorMatrixMulAddNV) {
if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
bias_index)) {
return error;
}
}
const auto result_type = _.FindDef(result_type_id);
if (result_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " result type <id> " << _.getIdName(result_type_id)
<< " is not a cooperative vector type.";
}
const auto result_component_type_id = result_type->GetOperandAs<uint32_t>(1u);
if (!(_.IsIntScalarType(result_component_type_id) &&
_.GetBitWidth(result_component_type_id) == 32) &&
!(_.IsFloatScalarType(result_component_type_id) &&
(_.GetBitWidth(result_component_type_id) == 32 ||
_.GetBitWidth(result_component_type_id) == 16))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " result component type <id> "
<< _.getIdName(result_component_type_id)
<< " is not a 32 bit int or 16/32 bit float.";
}
const auto m_eval = _.EvalInt32IfConst(m_id);
const auto rc_eval =
_.EvalInt32IfConst(result_type->GetOperandAs<uint32_t>(2u));
if (get<1>(m_eval) && get<1>(rc_eval) && get<2>(m_eval) != get<2>(rc_eval)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " result type number of components "
<< get<2>(rc_eval) << " does not match M " << get<2>(m_eval);
}
const auto k_eval = _.EvalInt32IfConst(k_id);
const auto input = _.FindDef(input_id);
const auto input_type = _.FindDef(input->type_id());
const auto input_num_components_id = input_type->GetOperandAs<uint32_t>(2u);
auto input_interp_eval = _.EvalInt32IfConst(input_interpretation_id);
if (get<1>(input_interp_eval) &&
!InterpretationIsPacked(spv::ComponentType{get<2>(input_interp_eval)})) {
const auto inc_eval = _.EvalInt32IfConst(input_num_components_id);
if (get<1>(inc_eval) && get<1>(k_eval) &&
get<2>(inc_eval) != get<2>(k_eval)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " input number of components "
<< get<2>(inc_eval) << " does not match K " << get<2>(k_eval);
}
}
if (!_.IsBoolScalarType(_.FindDef(transpose_id)->type_id())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " Transpose <id> " << _.getIdName(transpose_id)
<< " is not a scalar boolean.";
}
const auto check_constant = [&](uint32_t id,
const char* operand_name) -> spv_result_t {
if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " " << operand_name << " <id> "
<< _.getIdName(id) << " is not a constant instruction.";
}
return SPV_SUCCESS;
};
if (auto error =
check_constant(input_interpretation_id, "InputInterpretation")) {
return error;
}
if (auto error =
check_constant(matrix_interpretation_id, "MatrixInterpretation")) {
return error;
}
if (has_bias) {
if (auto error =
check_constant(bias_interpretation_id, "BiasInterpretation")) {
return error;
}
}
if (auto error = check_constant(m_id, "M")) {
return error;
}
if (auto error = check_constant(k_id, "K")) {
return error;
}
if (auto error = check_constant(memory_layout_id, "MemoryLayout")) {
return error;
}
if (auto error = check_constant(transpose_id, "Transpose")) {
return error;
}
if (auto error = ValidateInt32Operand(_, inst, input_interpretation_index,
opcode_name, "InputInterpretation")) {
return error;
}
if (auto error = ValidateInt32Operand(_, inst, matrix_interpretation_index,
opcode_name, "MatrixInterpretation")) {
return error;
}
if (has_bias) {
if (auto error = ValidateInt32Operand(_, inst, bias_interpretation_index,
opcode_name, "BiasInterpretation")) {
return error;
}
}
if (auto error = ValidateInt32Operand(_, inst, m_index, opcode_name, "M")) {
return error;
}
if (auto error = ValidateInt32Operand(_, inst, k_index, opcode_name, "K")) {
return error;
}
if (auto error = ValidateInt32Operand(_, inst, memory_layout_index,
opcode_name, "MemoryLayout")) {
return error;
}
return SPV_SUCCESS;
}
spv_result_t ValidatePtrComparison(ValidationState_t& _,
const Instruction* inst) {
if (_.addressing_model() == spv::AddressingModel::Logical &&
@@ -2511,6 +2870,24 @@ spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) {
if (auto error = ValidateCooperativeMatrixLoadStoreTensorNV(_, inst))
return error;
break;
case spv::Op::OpCooperativeVectorLoadNV:
case spv::Op::OpCooperativeVectorStoreNV:
if (auto error = ValidateCooperativeVectorLoadStoreNV(_, inst))
return error;
break;
case spv::Op::OpCooperativeVectorOuterProductAccumulateNV:
if (auto error = ValidateCooperativeVectorOuterProductNV(_, inst))
return error;
break;
case spv::Op::OpCooperativeVectorReduceSumAccumulateNV:
if (auto error = ValidateCooperativeVectorReduceSumNV(_, inst))
return error;
break;
case spv::Op::OpCooperativeVectorMatrixMulNV:
case spv::Op::OpCooperativeVectorMatrixMulAddNV:
if (auto error = ValidateCooperativeVectorMatrixMulNV(_, inst))
return error;
break;
case spv::Op::OpPtrEqual:
case spv::Op::OpPtrNotEqual:
case spv::Op::OpPtrDiff:

View File

@@ -15,6 +15,7 @@
// Validates ray query instructions from SPV_KHR_ray_query
#include "source/opcode.h"
#include "source/spirv_target_env.h"
#include "source/val/instruction.h"
#include "source/val/validate.h"
#include "source/val/validation_state.h"
@@ -22,6 +23,24 @@
namespace spvtools {
namespace val {
bool IsInterfaceVariable(ValidationState_t& _, const Instruction* inst,
spv::ExecutionModel model) {
bool foundInterface = false;
for (auto entry_point : _.entry_points()) {
const auto* models = _.GetExecutionModels(entry_point);
if (models->find(model) == models->end()) return false;
for (const auto& desc : _.entry_point_descriptions(entry_point)) {
for (auto interface : desc.interfaces) {
if (inst->id() == interface) {
foundInterface = true;
break;
}
}
}
}
return foundInterface;
}
spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) {
const spv::Op opcode = inst->opcode();
switch (opcode) {
@@ -111,7 +130,37 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) {
// No validation rules (for the moment).
break;
}
case spv::Op::OpVariable: {
if (_.HasCapability(spv::Capability::MeshShadingEXT)) {
bool meshInterfaceVar =
IsInterfaceVariable(_, inst, spv::ExecutionModel::MeshEXT);
bool fragInterfaceVar =
IsInterfaceVariable(_, inst, spv::ExecutionModel::Fragment);
const spv::StorageClass storage_class =
inst->GetOperandAs<spv::StorageClass>(2);
bool storage_output = (storage_class == spv::StorageClass::Output);
bool storage_input = (storage_class == spv::StorageClass::Input);
if (_.HasDecoration(inst->id(), spv::Decoration::PerPrimitiveEXT)) {
if (fragInterfaceVar && !storage_input) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "PerPrimitiveEXT decoration must be applied only to "
"variables in the Input Storage Class in the Fragment "
"Execution Model.";
}
if (meshInterfaceVar && !storage_output) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4336)
<< "PerPrimitiveEXT decoration must be applied only to "
"variables in the Output Storage Class in the "
"Storage Class in the MeshEXT Execution Model.";
}
}
}
break;
}
default:
break;
}

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2018 Google LLC.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -323,6 +325,42 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
}
}
if (_.EntryPointHasLocalSizeOrId(entry_point_id)) {
const Instruction* local_size_inst =
_.EntryPointLocalSizeOrId(entry_point_id);
if (local_size_inst) {
const auto mode = local_size_inst->GetOperandAs<spv::ExecutionMode>(1);
const uint32_t operand_x = local_size_inst->GetOperandAs<uint32_t>(2);
const uint32_t operand_y = local_size_inst->GetOperandAs<uint32_t>(3);
const uint32_t operand_z = local_size_inst->GetOperandAs<uint32_t>(4);
if (mode == spv::ExecutionMode::LocalSize) {
if ((operand_x * operand_y * operand_z) == 0) {
return _.diag(SPV_ERROR_INVALID_DATA, local_size_inst)
<< "Local Size execution mode must not have a product of zero "
"(X "
"= "
<< operand_x << ", Y = " << operand_y << ", Z = " << operand_z
<< ").";
}
} else if (mode == spv::ExecutionMode::LocalSizeId) {
// can only validate product if static and not spec constant
// (This is done for us in EvalConstantValUint64)
uint64_t x_size, y_size, z_size;
bool static_x = _.EvalConstantValUint64(operand_x, &x_size);
bool static_y = _.EvalConstantValUint64(operand_y, &y_size);
bool static_z = _.EvalConstantValUint64(operand_z, &z_size);
if (static_x && static_y && static_z &&
((x_size * y_size * z_size) == 0)) {
return _.diag(SPV_ERROR_INVALID_DATA, local_size_inst)
<< "Local Size Id execution mode must not have a product of "
"zero "
"(X = "
<< x_size << ", Y = " << y_size << ", Z = " << z_size << ").";
}
}
}
}
return SPV_SUCCESS;
}
@@ -347,6 +385,12 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
case spv::ExecutionMode::LocalSizeId:
case spv::ExecutionMode::FPFastMathDefault:
case spv::ExecutionMode::MaximumRegistersIdINTEL:
case spv::ExecutionMode::IsApiEntryAMDX:
case spv::ExecutionMode::MaxNodeRecursionAMDX:
case spv::ExecutionMode::MaxNumWorkgroupsAMDX:
case spv::ExecutionMode::ShaderIndexAMDX:
case spv::ExecutionMode::SharesInputWithAMDX:
case spv::ExecutionMode::StaticNumWorkgroupsAMDX:
valid_mode = true;
break;
default:
@@ -368,6 +412,12 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
case spv::ExecutionMode::SubgroupsPerWorkgroupId:
case spv::ExecutionMode::LocalSizeHintId:
case spv::ExecutionMode::LocalSizeId:
case spv::ExecutionMode::IsApiEntryAMDX:
case spv::ExecutionMode::MaxNodeRecursionAMDX:
case spv::ExecutionMode::MaxNumWorkgroupsAMDX:
case spv::ExecutionMode::ShaderIndexAMDX:
case spv::ExecutionMode::SharesInputWithAMDX:
case spv::ExecutionMode::StaticNumWorkgroupsAMDX:
if (!spvOpcodeIsConstant(operand_inst->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "For OpExecutionModeId all Extra Operand ids must be "
@@ -426,7 +476,13 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
} else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId ||
mode == spv::ExecutionMode::LocalSizeHintId ||
mode == spv::ExecutionMode::LocalSizeId ||
mode == spv::ExecutionMode::FPFastMathDefault) {
mode == spv::ExecutionMode::FPFastMathDefault ||
mode == spv::ExecutionMode::IsApiEntryAMDX ||
mode == spv::ExecutionMode::MaxNodeRecursionAMDX ||
mode == spv::ExecutionMode::MaxNumWorkgroupsAMDX ||
mode == spv::ExecutionMode::ShaderIndexAMDX ||
mode == spv::ExecutionMode::SharesInputWithAMDX ||
mode == spv::ExecutionMode::StaticNumWorkgroupsAMDX) {
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 "
@@ -543,6 +599,15 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
"tessellation execution model.";
}
}
if (spvIsVulkanEnv(_.context()->target_env)) {
if (_.HasCapability(spv::Capability::MeshShadingEXT) &&
inst->GetOperandAs<uint32_t>(2) == 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(7330)
<< "In mesh shaders using the MeshEXT Execution Model the "
"OutputVertices Execution Mode must be greater than 0";
}
}
break;
case spv::ExecutionMode::OutputLinesEXT:
case spv::ExecutionMode::OutputTrianglesEXT:
@@ -557,6 +622,16 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
"execution "
"model.";
}
if (mode == spv::ExecutionMode::OutputPrimitivesEXT &&
spvIsVulkanEnv(_.context()->target_env)) {
if (_.HasCapability(spv::Capability::MeshShadingEXT) &&
inst->GetOperandAs<uint32_t>(2) == 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(7331)
<< "In mesh shaders using the MeshEXT Execution Model the "
"OutputPrimitivesEXT Execution Mode must be greater than 0";
}
}
break;
case spv::ExecutionMode::QuadDerivativesKHR:
if (!std::all_of(models->begin(), models->end(),

View File

@@ -23,6 +23,17 @@ namespace spvtools {
namespace val {
namespace {
uint32_t GetArrayLength(ValidationState_t& _, const Instruction* array_type) {
assert(array_type->opcode() == spv::Op::OpTypeArray);
uint32_t const_int_id = array_type->GetOperandAs<uint32_t>(2U);
Instruction* array_length_inst = _.FindDef(const_int_id);
uint32_t array_length = 0;
if (array_length_inst->opcode() == spv::Op::OpConstant) {
array_length = array_length_inst->GetOperandAs<uint32_t>(2);
}
return array_length;
}
spv_result_t ValidateRayQueryPointer(ValidationState_t& _,
const Instruction* inst,
uint32_t ray_query_index) {
@@ -263,6 +274,89 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) {
break;
}
case spv::Op::OpRayQueryGetClusterIdNV: {
if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
if (!_.IsIntScalarType(result_type) || _.GetBitWidth(result_type) != 32) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "expected Result Type to be 32-bit int scalar type";
}
break;
}
case spv::Op::OpRayQueryGetIntersectionSpherePositionNV: {
if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
if (!_.IsFloatVectorType(result_type) ||
_.GetDimension(result_type) != 3 ||
_.GetBitWidth(result_type) != 32) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "expected Result Type to be 32-bit float 3-component "
"vector type";
}
break;
}
case spv::Op::OpRayQueryGetIntersectionLSSPositionsNV: {
if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
auto result_id = _.FindDef(result_type);
if ((result_id->opcode() != spv::Op::OpTypeArray) ||
(GetArrayLength(_, result_id) != 2) ||
!_.IsFloatVectorType(_.GetComponentType(result_type)) ||
_.GetDimension(_.GetComponentType(result_type)) != 3) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected 2 element array of 32-bit 3 component float point "
"vector as Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpRayQueryGetIntersectionLSSRadiiNV: {
if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
if (!_.IsFloatArrayType(result_type) ||
(GetArrayLength(_, _.FindDef(result_type)) != 2) ||
!_.IsFloatScalarType(_.GetComponentType(result_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected 32-bit floating point scalar as Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpRayQueryGetIntersectionSphereRadiusNV:
case spv::Op::OpRayQueryGetIntersectionLSSHitValueNV: {
if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
if (!_.IsFloatScalarType(result_type) ||
_.GetBitWidth(result_type) != 32) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "expected Result Type to be 32-bit floating point "
"scalar type";
}
break;
}
case spv::Op::OpRayQueryIsSphereHitNV:
case spv::Op::OpRayQueryIsLSSHitNV: {
if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
if (!_.IsBoolScalarType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "expected Result Type to be Boolean "
"scalar type";
}
break;
}
default:
break;
}

View File

@@ -26,6 +26,17 @@ namespace val {
static const uint32_t KRayParamInvalidId = std::numeric_limits<uint32_t>::max();
uint32_t GetArrayLength(ValidationState_t& _, const Instruction* array_type) {
assert(array_type->opcode() == spv::Op::OpTypeArray);
uint32_t const_int_id = array_type->GetOperandAs<uint32_t>(2U);
Instruction* array_length_inst = _.FindDef(const_int_id);
uint32_t array_length = 0;
if (array_length_inst->opcode() == spv::Op::OpConstant) {
array_length = array_length_inst->GetOperandAs<uint32_t>(2);
}
return array_length;
}
spv_result_t ValidateHitObjectPointer(ValidationState_t& _,
const Instruction* inst,
uint32_t hit_object_index) {
@@ -614,6 +625,102 @@ spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "bits must be a 32-bit int scalar";
}
break;
}
case spv::Op::OpHitObjectGetClusterIdNV: {
RegisterOpcodeForValidModel(_, inst);
if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
if (!_.IsIntScalarType(result_type) || _.GetBitWidth(result_type) != 32)
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected 32-bit integer type scalar as Result Type: "
<< spvOpcodeString(opcode);
break;
}
case spv::Op::OpHitObjectGetSpherePositionNV: {
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 2 component vector type as "
"Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpHitObjectGetSphereRadiusNV: {
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 scalar as Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpHitObjectGetLSSPositionsNV: {
RegisterOpcodeForValidModel(_, inst);
if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
auto result_id = _.FindDef(result_type);
if ((result_id->opcode() != spv::Op::OpTypeArray) ||
(GetArrayLength(_, result_id) != 2) ||
!_.IsFloatVectorType(_.GetComponentType(result_type)) ||
_.GetDimension(_.GetComponentType(result_type)) != 3) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected 2 element array of 32-bit 3 component float point "
"vector as Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpHitObjectGetLSSRadiiNV: {
RegisterOpcodeForValidModel(_, inst);
if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
if (!_.IsFloatArrayType(result_type) ||
(GetArrayLength(_, _.FindDef(result_type)) != 2) ||
!_.IsFloatScalarType(_.GetComponentType(result_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected 2 element array of 32-bit floating point scalar as "
"Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpHitObjectIsSphereHitNV: {
RegisterOpcodeForValidModel(_, inst);
if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
if (!_.IsBoolScalarType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Boolean scalar as Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
case spv::Op::OpHitObjectIsLSSHitNV: {
RegisterOpcodeForValidModel(_, inst);
if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
if (!_.IsBoolScalarType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Boolean scalar as Result Type: "
<< spvOpcodeString(opcode);
}
break;
}
default:

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2018 Google LLC.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
// Copyright (c) 2024 NVIDIA Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,6 +38,7 @@ spv_result_t ValidateUniqueness(ValidationState_t& _, const Instruction* inst) {
const auto opcode = inst->opcode();
if (opcode != spv::Op::OpTypeArray && opcode != spv::Op::OpTypeRuntimeArray &&
opcode != spv::Op::OpTypeNodePayloadArrayAMDX &&
opcode != spv::Op::OpTypeStruct && opcode != spv::Op::OpTypePointer &&
opcode != spv::Op::OpTypeUntypedPointerKHR &&
!_.RegisterUniqueTypeDeclaration(inst)) {
@@ -166,6 +169,57 @@ spv_result_t ValidateTypeVector(ValidationState_t& _, const Instruction* inst) {
return SPV_SUCCESS;
}
spv_result_t ValidateTypeCooperativeVectorNV(ValidationState_t& _,
const Instruction* inst) {
const auto component_index = 1;
const auto component_type_id = inst->GetOperandAs<uint32_t>(component_index);
const auto component_type = _.FindDef(component_type_id);
if (!component_type || (spv::Op::OpTypeFloat != component_type->opcode() &&
spv::Op::OpTypeInt != component_type->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpTypeCooperativeVectorNV Component Type <id> "
<< _.getIdName(component_type_id)
<< " is not a scalar numerical type.";
}
const auto num_components_index = 2;
const auto num_components_id =
inst->GetOperandAs<uint32_t>(num_components_index);
const auto num_components = _.FindDef(num_components_id);
if (!num_components || !spvOpcodeIsConstant(num_components->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpTypeCooperativeVectorNV component count <id> "
<< _.getIdName(num_components_id)
<< " is not a scalar constant type.";
}
// NOTE: Check the initialiser value of the constant
const auto const_inst = num_components->words();
const auto const_result_type_index = 1;
const auto const_result_type = _.FindDef(const_inst[const_result_type_index]);
if (!const_result_type || spv::Op::OpTypeInt != const_result_type->opcode()) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpTypeCooperativeVectorNV component count <id> "
<< _.getIdName(num_components_id)
<< " is not a constant integer type.";
}
int64_t num_components_value;
if (_.EvalConstantValInt64(num_components_id, &num_components_value)) {
auto& type_words = const_result_type->words();
const bool is_signed = type_words[3] > 0;
if (num_components_value == 0 || (num_components_value < 0 && is_signed)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpTypeCooperativeVectorNV component count <id> "
<< _.getIdName(num_components_id)
<< " default value must be at least 1: found "
<< num_components_value;
}
}
return SPV_SUCCESS;
}
spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) {
const auto column_type_index = 1;
const auto column_type_id = inst->GetOperandAs<uint32_t>(column_type_index);
@@ -212,6 +266,18 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) {
<< " is a void type.";
}
if (_.HasCapability(spv::Capability::Shader)) {
if (element_type->opcode() == spv::Op::OpTypeStruct &&
(_.HasDecoration(element_type->id(), spv::Decoration::Block) ||
_.HasDecoration(element_type->id(), spv::Decoration::BufferBlock))) {
if (_.HasDecoration(inst->id(), spv::Decoration::ArrayStride)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Array containing a Block or BufferBlock must not be "
"decorated with ArrayStride";
}
}
}
if (spvIsVulkanEnv(_.context()->target_env) &&
element_type->opcode() == spv::Op::OpTypeRuntimeArray) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
@@ -270,6 +336,18 @@ spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _,
<< " is a void type.";
}
if (_.HasCapability(spv::Capability::Shader)) {
if (element_type->opcode() == spv::Op::OpTypeStruct &&
(_.HasDecoration(element_type->id(), spv::Decoration::Block) ||
_.HasDecoration(element_type->id(), spv::Decoration::BufferBlock))) {
if (_.HasDecoration(inst->id(), spv::Decoration::ArrayStride)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Array containing a Block or BufferBlock must not be "
"decorated with ArrayStride";
}
}
}
if (spvIsVulkanEnv(_.context()->target_env) &&
element_type->opcode() == spv::Op::OpTypeRuntimeArray) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
@@ -340,13 +418,20 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) {
// Struct members start at word 2 of OpTypeStruct instruction.
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 && 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;
if (_.ContainsType(
member,
[&_](const Instruction* type_inst) {
if (type_inst->opcode() == spv::Op::OpTypeStruct &&
(_.HasDecoration(type_inst->id(), spv::Decoration::Block) ||
_.HasDecoration(type_inst->id(),
spv::Decoration::BufferBlock))) {
return true;
}
return false;
},
/* traverse_all_types = */ false)) {
has_nested_blockOrBufferBlock_struct = true;
break;
}
}
@@ -797,6 +882,9 @@ spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpTypeCooperativeMatrixKHR:
if (auto error = ValidateTypeCooperativeMatrix(_, inst)) return error;
break;
case spv::Op::OpTypeCooperativeVectorNV:
if (auto error = ValidateTypeCooperativeVectorNV(_, inst)) return error;
break;
case spv::Op::OpTypeUntypedPointerKHR:
if (auto error = ValidateTypeUntypedPointerKHR(_, inst)) return error;
break;

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2015-2016 The Khronos Group Inc.
// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
// reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -881,6 +883,7 @@ uint32_t ValidationState_t::GetComponentType(uint32_t id) const {
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
return inst->word(2);
default:
@@ -909,6 +912,7 @@ uint32_t ValidationState_t::GetDimension(uint32_t id) const {
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
// Actual dimension isn't known, return 0
return 0;
@@ -947,6 +951,19 @@ bool ValidationState_t::IsFloatScalarType(uint32_t id) const {
return inst && inst->opcode() == spv::Op::OpTypeFloat;
}
bool ValidationState_t::IsFloatArrayType(uint32_t id) const {
const Instruction* inst = FindDef(id);
if (!inst) {
return false;
}
if (inst->opcode() == spv::Op::OpTypeArray) {
return IsFloatScalarType(GetComponentType(id));
}
return false;
}
bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
if (!inst) {
@@ -1185,6 +1202,7 @@ bool ValidationState_t::GetStructMemberTypes(
}
bool ValidationState_t::IsPointerType(uint32_t id) const {
if (!id) return false;
const Instruction* inst = FindDef(id);
assert(inst);
return inst->opcode() == spv::Op::OpTypePointer ||
@@ -1289,6 +1307,27 @@ bool ValidationState_t::IsUnsigned64BitHandle(uint32_t id) const {
GetBitWidth(id) == 32));
}
bool ValidationState_t::IsCooperativeVectorNVType(uint32_t id) const {
const Instruction* inst = FindDef(id);
return inst && inst->opcode() == spv::Op::OpTypeCooperativeVectorNV;
}
bool ValidationState_t::IsFloatCooperativeVectorNVType(uint32_t id) const {
if (!IsCooperativeVectorNVType(id)) return false;
return IsFloatScalarType(FindDef(id)->word(2));
}
bool ValidationState_t::IsIntCooperativeVectorNVType(uint32_t id) const {
if (!IsCooperativeVectorNVType(id)) return false;
return IsIntScalarType(FindDef(id)->word(2));
}
bool ValidationState_t::IsUnsignedIntCooperativeVectorNVType(
uint32_t id) const {
if (!IsCooperativeVectorNVType(id)) return false;
return IsUnsignedIntScalarType(FindDef(id)->word(2));
}
spv_result_t ValidationState_t::CooperativeMatrixShapesMatch(
const Instruction* inst, uint32_t result_type_id, uint32_t m2,
bool is_conversion, bool swap_row_col) {
@@ -1372,6 +1411,36 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch(
return SPV_SUCCESS;
}
spv_result_t ValidationState_t::CooperativeVectorDimensionsMatch(
const Instruction* inst, uint32_t v1, uint32_t v2) {
const auto v1_type = FindDef(v1);
const auto v2_type = FindDef(v2);
if (v1_type->opcode() != v2_type->opcode()) {
return diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected cooperative vector types";
}
uint32_t v1_components_id = v1_type->GetOperandAs<uint32_t>(2);
uint32_t v2_components_id = v2_type->GetOperandAs<uint32_t>(2);
bool v1_is_int32 = false, v1_is_const_int32 = false, v2_is_int32 = false,
v2_is_const_int32 = false;
uint32_t v1_value = 0, v2_value = 0;
std::tie(v1_is_int32, v1_is_const_int32, v1_value) =
EvalInt32IfConst(v1_components_id);
std::tie(v2_is_int32, v2_is_const_int32, v2_value) =
EvalInt32IfConst(v2_components_id);
if (v1_is_const_int32 && v2_is_const_int32 && v1_value != v2_value) {
return diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected number of components to be identical";
}
return SPV_SUCCESS;
}
uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst,
size_t operand_index) const {
return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index));
@@ -1664,6 +1733,7 @@ bool ValidationState_t::ContainsType(
case spv::Op::OpTypeSampledImage:
case spv::Op::OpTypeCooperativeMatrixNV:
case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeVectorNV:
return ContainsType(inst->GetOperandAs<uint32_t>(1u), f,
traverse_all_types);
case spv::Op::OpTypePointer:
@@ -1781,6 +1851,7 @@ bool ValidationState_t::IsValidStorageClass(
case spv::StorageClass::TaskPayloadWorkgroupEXT:
case spv::StorageClass::HitObjectAttributeNV:
case spv::StorageClass::TileImageEXT:
case spv::StorageClass::NodePayloadAMDX:
return true;
default:
return false;
@@ -2054,6 +2125,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04330);
case 4334:
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334);
case 4336:
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04336);
case 4337:
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337);
case 4345:
@@ -2258,8 +2331,6 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
case 4659:
return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659);
case 4663:
return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663);
case 4664:
return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664);
case 4667:
@@ -2382,30 +2453,62 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06924);
case 6925:
return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925);
case 7034:
return VUID_WRAP(VUID-CullPrimitiveEXT-CullPrimitiveEXT-07034);
case 7035:
return VUID_WRAP(VUID-CullPrimitiveEXT-CullPrimitiveEXT-07035);
case 7036:
return VUID_WRAP(VUID-CullPrimitiveEXT-CullPrimitiveEXT-07036);
case 7038:
return VUID_WRAP(VUID-CullPrimitiveEXT-CullPrimitiveEXT-07038);
case 7039:
return VUID_WRAP(VUID-Layer-Layer-07039);
case 7040:
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-07040);
case 7041:
return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07041);
case 7042:
return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07042);
case 7043:
return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07043);
case 7044:
return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07044);
case 7046:
return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07046);
case 7047:
return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07047);
case 7048:
return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07048);
case 7049:
return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07049);
case 7050:
return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07050);
case 7052:
return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07052);
case 7053:
return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07053);
case 7054:
return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07054);
case 7055:
return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07055);
case 7056:
return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07056);
case 7058:
return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07058);
case 7059:
return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-07059);
case 7060:
return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-07060);
case 7102:
return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102);
case 7320:
return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320);
case 7290:
return VUID_WRAP(VUID-StandaloneSpirv-Input-07290);
case 7320:
return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320);
case 7330:
return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07330);
case 7331:
return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07331);
case 7650:
return VUID_WRAP(VUID-StandaloneSpirv-Base-07650);
case 7651:
@@ -2428,6 +2531,9 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-09658);
case 9659:
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-09659);
case 10213:
// This use to be a standalone, but maintenance8 will set allow_offset_texture_operand now
return VUID_WRAP(VUID-RuntimeSpirv-Offset-10213);
default:
return ""; // unknown id
}

View File

@@ -245,6 +245,24 @@ class ValidationState_t {
const Instruction* inst) {
entry_point_to_local_size_or_id_[entry_point] = inst;
}
/// Registers that the entry point maximum number of primitives
/// mesh shader will ever emit
void RegisterEntryPointOutputPrimitivesEXT(uint32_t entry_point,
const Instruction* inst) {
entry_point_to_output_primitives_[entry_point] = inst;
}
/// Returns the maximum number of primitives mesh shader can emit
uint32_t GetOutputPrimitivesEXT(uint32_t entry_point) {
auto entry = entry_point_to_output_primitives_.find(entry_point);
if (entry != entry_point_to_output_primitives_.end()) {
auto inst = entry->second;
return inst->GetOperandAs<uint32_t>(2);
}
return 0;
}
/// Returns whether the entry point declares its local size
bool EntryPointHasLocalSizeOrId(uint32_t entry_point) const {
return entry_point_to_local_size_or_id_.find(entry_point) !=
@@ -616,6 +634,7 @@ class ValidationState_t {
// Only works for types not for objects.
bool IsVoidType(uint32_t id) const;
bool IsFloatScalarType(uint32_t id) const;
bool IsFloatArrayType(uint32_t id) const;
bool IsFloatVectorType(uint32_t id) const;
bool IsFloat16Vector2Or4Type(uint32_t id) const;
bool IsFloatScalarOrVectorType(uint32_t id) const;
@@ -644,6 +663,10 @@ class ValidationState_t {
bool IsIntCooperativeMatrixType(uint32_t id) const;
bool IsUnsignedIntCooperativeMatrixType(uint32_t id) const;
bool IsUnsigned64BitHandle(uint32_t id) const;
bool IsCooperativeVectorNVType(uint32_t id) const;
bool IsFloatCooperativeVectorNVType(uint32_t id) const;
bool IsIntCooperativeVectorNVType(uint32_t id) const;
bool IsUnsignedIntCooperativeVectorNVType(uint32_t id) const;
// Returns true if |id| is a type id that contains |type| (or integer or
// floating point type) of |width| bits.
@@ -783,6 +806,9 @@ class ValidationState_t {
uint32_t m2, bool is_conversion,
bool swap_row_col = false);
spv_result_t CooperativeVectorDimensionsMatch(const Instruction* inst,
uint32_t v1, uint32_t v2);
// Returns true if |lhs| and |rhs| logically match and, if the decorations of
// |rhs| are a subset of |lhs|.
//
@@ -971,6 +997,10 @@ class ValidationState_t {
std::unordered_map<uint32_t, const Instruction*>
entry_point_to_local_size_or_id_;
// Mapping entry point -> OutputPrimitivesEXT execution mode instruction
std::unordered_map<uint32_t, const Instruction*>
entry_point_to_output_primitives_;
/// Mapping function -> array of entry points inside this
/// module which can (indirectly) call the function.
std::unordered_map<uint32_t, std::vector<uint32_t>> function_to_entry_points_;