Vulkan-specific validation for long vectors
| 862 | |
| 863 | // Vulkan-specific validation for long vectors |
| 864 | spv_result_t ValidateVariableVulkanLongVector(ValidationState_t& _, |
| 865 | const Instruction* inst, |
| 866 | spv::StorageClass storage_class, |
| 867 | const Instruction& pointee) { |
| 868 | if (_.HasCapability(spv::Capability::LongVectorEXT)) { |
| 869 | if ((storage_class != spv::StorageClass::Function && |
| 870 | storage_class != spv::StorageClass::Private && |
| 871 | storage_class != spv::StorageClass::StorageBuffer && |
| 872 | storage_class != spv::StorageClass::PhysicalStorageBuffer && |
| 873 | storage_class != spv::StorageClass::Workgroup && |
| 874 | storage_class != spv::StorageClass::Uniform && |
| 875 | storage_class != spv::StorageClass::PushConstant && |
| 876 | storage_class != spv::StorageClass::ShaderRecordBufferKHR) && |
| 877 | _.ContainsType(pointee.id(), [&](const Instruction* type_inst) { |
| 878 | auto opcode = type_inst->opcode(); |
| 879 | if (opcode == spv::Op::OpTypeVector || |
| 880 | opcode == spv::Op::OpTypeVectorIdEXT) { |
| 881 | uint32_t dim = _.GetDimension(type_inst->id()); |
| 882 | return dim > 4; |
| 883 | } |
| 884 | return false; |
| 885 | })) { |
| 886 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 887 | << _.VkErrorID(12297) |
| 888 | << "Long vector types with more than 4 components (or types " |
| 889 | "containing them) not supported in storage class " |
| 890 | << StorageClassToString(storage_class); |
| 891 | } |
| 892 | |
| 893 | if ((storage_class == spv::StorageClass::StorageBuffer || |
| 894 | storage_class == spv::StorageClass::PhysicalStorageBuffer || |
| 895 | storage_class == spv::StorageClass::Uniform || |
| 896 | storage_class == spv::StorageClass::PushConstant || |
| 897 | storage_class == spv::StorageClass::ShaderRecordBufferKHR || |
| 898 | (storage_class == spv::StorageClass::Workgroup && |
| 899 | _.HasDecoration(pointee.id(), spv::Decoration::Block))) && |
| 900 | _.ContainsType(pointee.id(), [&](const Instruction* type_inst) { |
| 901 | auto opcode = type_inst->opcode(); |
| 902 | if (opcode == spv::Op::OpTypeVectorIdEXT) { |
| 903 | auto component_count = |
| 904 | _.FindDef(type_inst->GetOperandAs<uint32_t>(2u)); |
| 905 | return (bool)spvOpcodeIsSpecConstant(component_count->opcode()); |
| 906 | } |
| 907 | return false; |
| 908 | })) { |
| 909 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 910 | << _.VkErrorID(12294) |
| 911 | << "Long vector types with spec constant component count " |
| 912 | "not supported in storage class with explicit layout " |
| 913 | << StorageClassToString(storage_class); |
| 914 | } |
| 915 | } else { |
| 916 | if ((storage_class != spv::StorageClass::Function && |
| 917 | storage_class != spv::StorageClass::Private) && |
| 918 | _.ContainsType(pointee.id(), [](const Instruction* type_inst) { |
| 919 | auto opcode = type_inst->opcode(); |
| 920 | return opcode == spv::Op::OpTypeVectorIdEXT; |
| 921 | })) { |
no test coverage detected