| 932 | } |
| 933 | |
| 934 | spv_result_t ValidateVariableShader(ValidationState_t& _, |
| 935 | const Instruction* inst, |
| 936 | spv::StorageClass storage_class, |
| 937 | const Instruction* value_type, |
| 938 | uint32_t value_id) { |
| 939 | // Don't allow variables containing 16-bit elements without the appropriate |
| 940 | // capabilities. |
| 941 | if ((!_.HasCapability(spv::Capability::Int16) && |
| 942 | _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 16)) || |
| 943 | (!_.HasCapability(spv::Capability::Float16) && |
| 944 | _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeFloat, 16))) { |
| 945 | auto underlying_type = value_type; |
| 946 | while (underlying_type && |
| 947 | underlying_type->opcode() == spv::Op::OpTypePointer) { |
| 948 | storage_class = underlying_type->GetOperandAs<spv::StorageClass>(1u); |
| 949 | underlying_type = _.FindDef(underlying_type->GetOperandAs<uint32_t>(2u)); |
| 950 | } |
| 951 | bool storage_class_ok = true; |
| 952 | std::string sc_name = _.grammar().lookupOperandName( |
| 953 | SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); |
| 954 | switch (storage_class) { |
| 955 | case spv::StorageClass::StorageBuffer: |
| 956 | case spv::StorageClass::PhysicalStorageBuffer: |
| 957 | if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess)) { |
| 958 | storage_class_ok = false; |
| 959 | } |
| 960 | break; |
| 961 | case spv::StorageClass::Uniform: |
| 962 | if (underlying_type && |
| 963 | !_.HasCapability( |
| 964 | spv::Capability::UniformAndStorageBuffer16BitAccess)) { |
| 965 | if (underlying_type->opcode() == spv::Op::OpTypeArray || |
| 966 | underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { |
| 967 | underlying_type = |
| 968 | _.FindDef(underlying_type->GetOperandAs<uint32_t>(1u)); |
| 969 | } |
| 970 | if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess) || |
| 971 | !_.HasDecoration(underlying_type->id(), |
| 972 | spv::Decoration::BufferBlock)) { |
| 973 | storage_class_ok = false; |
| 974 | } |
| 975 | } |
| 976 | break; |
| 977 | case spv::StorageClass::PushConstant: |
| 978 | if (!_.HasCapability(spv::Capability::StoragePushConstant16)) { |
| 979 | storage_class_ok = false; |
| 980 | } |
| 981 | break; |
| 982 | case spv::StorageClass::Input: |
| 983 | case spv::StorageClass::Output: |
| 984 | if (!_.HasCapability(spv::Capability::StorageInputOutput16)) { |
| 985 | storage_class_ok = false; |
| 986 | } |
| 987 | break; |
| 988 | case spv::StorageClass::Workgroup: |
| 989 | if (!_.HasCapability( |
| 990 | spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR)) { |
| 991 | storage_class_ok = false; |
no test coverage detected