| 76 | } |
| 77 | |
| 78 | spv_result_t ValidateExecutionScope(ValidationState_t& _, |
| 79 | const Instruction* inst, uint32_t scope) { |
| 80 | spv::Op opcode = inst->opcode(); |
| 81 | bool is_int32 = false, is_const_int32 = false; |
| 82 | uint32_t tmp_value = 0; |
| 83 | std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); |
| 84 | |
| 85 | if (auto error = ValidateScope(_, inst, scope)) { |
| 86 | return error; |
| 87 | } |
| 88 | |
| 89 | if (!is_const_int32) { |
| 90 | return SPV_SUCCESS; |
| 91 | } |
| 92 | |
| 93 | spv::Scope value = spv::Scope(tmp_value); |
| 94 | |
| 95 | // Vulkan specific rules |
| 96 | if (spvIsVulkanEnv(_.context()->target_env)) { |
| 97 | // Subgroups were not added until 1.1 |
| 98 | if (_.context()->target_env != SPV_ENV_VULKAN_1_0) { |
| 99 | // Scope for Non Uniform Group Operations must be limited to Subgroup |
| 100 | if ((spvOpcodeIsNonUniformGroupOperation(opcode) && |
| 101 | (opcode != spv::Op::OpGroupNonUniformQuadAllKHR) && |
| 102 | (opcode != spv::Op::OpGroupNonUniformQuadAnyKHR)) && |
| 103 | (value != spv::Scope::Subgroup)) { |
| 104 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 105 | << _.VkErrorID(4642) << spvOpcodeString(opcode) |
| 106 | << ": in Vulkan environment Execution scope is limited to " |
| 107 | << "Subgroup"; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // OpControlBarrier must only use Subgroup execution scope for a subset of |
| 112 | // execution models. |
| 113 | if (opcode == spv::Op::OpControlBarrier && value != spv::Scope::Subgroup) { |
| 114 | std::string errorVUID = _.VkErrorID(4682); |
| 115 | _.function(inst->function()->id()) |
| 116 | ->RegisterExecutionModelLimitation([errorVUID]( |
| 117 | spv::ExecutionModel model, |
| 118 | std::string* message) { |
| 119 | if (model == spv::ExecutionModel::Fragment || |
| 120 | model == spv::ExecutionModel::Vertex || |
| 121 | model == spv::ExecutionModel::Geometry || |
| 122 | model == spv::ExecutionModel::TessellationEvaluation || |
| 123 | model == spv::ExecutionModel::RayGenerationKHR || |
| 124 | model == spv::ExecutionModel::IntersectionKHR || |
| 125 | model == spv::ExecutionModel::AnyHitKHR || |
| 126 | model == spv::ExecutionModel::ClosestHitKHR || |
| 127 | model == spv::ExecutionModel::MissKHR) { |
| 128 | if (message) { |
| 129 | *message = |
| 130 | errorVUID + |
| 131 | "in Vulkan environment, OpControlBarrier execution scope " |
| 132 | "must be Subgroup for Fragment, Vertex, Geometry, " |
| 133 | "TessellationEvaluation, RayGeneration, Intersection, " |
| 134 | "AnyHit, ClosestHit, and Miss execution models"; |
| 135 | } |
no test coverage detected