| 131 | } // namespace |
| 132 | |
| 133 | spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { |
| 134 | switch (inst->opcode()) { |
| 135 | case spv::Op::OpUndef: |
| 136 | if (auto error = ValidateUndef(_, inst)) return error; |
| 137 | break; |
| 138 | default: |
| 139 | break; |
| 140 | } |
| 141 | switch (inst->opcode()) { |
| 142 | case spv::Op::OpBeginInvocationInterlockEXT: |
| 143 | case spv::Op::OpEndInvocationInterlockEXT: |
| 144 | _.function(inst->function()->id()) |
| 145 | ->RegisterExecutionModelLimitation( |
| 146 | spv::ExecutionModel::Fragment, |
| 147 | "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT " |
| 148 | "require Fragment execution model"); |
| 149 | |
| 150 | _.function(inst->function()->id()) |
| 151 | ->RegisterLimitation([](const ValidationState_t& state, |
| 152 | const Function* entry_point, |
| 153 | std::string* message) { |
| 154 | const auto* execution_modes = |
| 155 | state.GetExecutionModes(entry_point->id()); |
| 156 | |
| 157 | auto find_interlock = [](const spv::ExecutionMode& mode) { |
| 158 | switch (mode) { |
| 159 | case spv::ExecutionMode::PixelInterlockOrderedEXT: |
| 160 | case spv::ExecutionMode::PixelInterlockUnorderedEXT: |
| 161 | case spv::ExecutionMode::SampleInterlockOrderedEXT: |
| 162 | case spv::ExecutionMode::SampleInterlockUnorderedEXT: |
| 163 | case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: |
| 164 | case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: |
| 165 | return true; |
| 166 | default: |
| 167 | return false; |
| 168 | } |
| 169 | }; |
| 170 | |
| 171 | bool found = false; |
| 172 | if (execution_modes) { |
| 173 | auto i = std::find_if(execution_modes->begin(), |
| 174 | execution_modes->end(), find_interlock); |
| 175 | found = (i != execution_modes->end()); |
| 176 | } |
| 177 | |
| 178 | if (!found) { |
| 179 | *message = |
| 180 | "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT " |
| 181 | "require a fragment shader interlock execution mode."; |
| 182 | return false; |
| 183 | } |
| 184 | return true; |
| 185 | }); |
| 186 | break; |
| 187 | case spv::Op::OpDemoteToHelperInvocationEXT: |
| 188 | _.function(inst->function()->id()) |
| 189 | ->RegisterExecutionModelLimitation( |
| 190 | spv::ExecutionModel::Fragment, |
no test coverage detected