Returns a decoration used to make it explicit
| 2260 | |
| 2261 | // Returns a decoration used to make it explicit |
| 2262 | spv::Decoration UsesExplicitLayout( |
| 2263 | ValidationState_t& vstate, uint32_t type_id, |
| 2264 | std::unordered_map<uint32_t, spv::Decoration>& cache) { |
| 2265 | if (type_id == 0) { |
| 2266 | return spv::Decoration::Max; |
| 2267 | } |
| 2268 | |
| 2269 | if (cache.count(type_id)) { |
| 2270 | return cache[type_id]; |
| 2271 | } |
| 2272 | |
| 2273 | spv::Decoration res = spv::Decoration::Max; |
| 2274 | const auto type_inst = vstate.FindDef(type_id); |
| 2275 | if (type_inst->opcode() == spv::Op::OpTypeStruct || |
| 2276 | type_inst->opcode() == spv::Op::OpTypeArray || |
| 2277 | type_inst->opcode() == spv::Op::OpTypeRuntimeArray || |
| 2278 | type_inst->opcode() == spv::Op::OpTypePointer || |
| 2279 | type_inst->opcode() == spv::Op::OpTypeUntypedPointerKHR) { |
| 2280 | const auto& id_decs = vstate.id_decorations(); |
| 2281 | const auto iter = id_decs.find(type_id); |
| 2282 | if (iter != id_decs.end()) { |
| 2283 | bool allowLayoutDecorations = false; |
| 2284 | if (type_inst->opcode() == spv::Op::OpTypePointer || |
| 2285 | type_inst->opcode() == spv::Op::OpTypeUntypedPointerKHR) { |
| 2286 | const auto sc = type_inst->GetOperandAs<spv::StorageClass>(1); |
| 2287 | allowLayoutDecorations = AllowsLayout(vstate, sc); |
| 2288 | } |
| 2289 | if (!allowLayoutDecorations) { |
| 2290 | for (const auto& d : iter->second) { |
| 2291 | const spv::Decoration dec = d.dec_type(); |
| 2292 | if (dec == spv::Decoration::Block || |
| 2293 | dec == spv::Decoration::BufferBlock || |
| 2294 | dec == spv::Decoration::Offset || |
| 2295 | dec == spv::Decoration::ArrayStride || |
| 2296 | dec == spv::Decoration::MatrixStride) { |
| 2297 | res = dec; |
| 2298 | break; |
| 2299 | } |
| 2300 | } |
| 2301 | } |
| 2302 | } |
| 2303 | |
| 2304 | if (res == spv::Decoration::Max) { |
| 2305 | switch (type_inst->opcode()) { |
| 2306 | case spv::Op::OpTypeStruct: |
| 2307 | for (uint32_t i = 1; |
| 2308 | res == spv::Decoration::Max && i < type_inst->operands().size(); |
| 2309 | i++) { |
| 2310 | res = UsesExplicitLayout( |
| 2311 | vstate, type_inst->GetOperandAs<uint32_t>(i), cache); |
| 2312 | } |
| 2313 | break; |
| 2314 | case spv::Op::OpTypeArray: |
| 2315 | case spv::Op::OpTypeRuntimeArray: |
| 2316 | res = UsesExplicitLayout(vstate, type_inst->GetOperandAs<uint32_t>(1), |
| 2317 | cache); |
| 2318 | break; |
| 2319 | case spv::Op::OpTypePointer: { |
no test coverage detected