Implement some common forms of OpStore Bug: b/124388146 Change-Id: Ia3c4e6c81432dcfbca5bdd21c857108ee14bda9b Reviewed-on: https://swiftshader-review.googlesource.com/c/24788 Reviewed-by: Ben Clayton <bclayton@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Tested-by: Chris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp index 3b2fac8..cdd3a63 100644 --- a/src/Pipeline/SpirvShader.cpp +++ b/src/Pipeline/SpirvShader.cpp
@@ -660,6 +660,50 @@ } break; } + case spv::OpStore: + { + auto &object = getObject(insn.word(2)); + auto &pointer = getObject(insn.word(1)); + auto &pointerBase = getObject(pointer.pointerBase); + + if (pointerBase.kind == Object::Kind::InterfaceVariable) + { + UNIMPLEMENTED("Location-based store not yet implemented"); + } + + if (pointerBase.storageClass == spv::StorageClassImage || + pointerBase.storageClass == spv::StorageClassUniform || + pointerBase.storageClass == spv::StorageClassUniformConstant) + { + UNIMPLEMENTED("Descriptor-backed store not yet implemented"); + } + + SpirvRoutine::Value& ptrBase = *(routine->lvalues)[pointer.pointerBase]; + auto & src = *(routine->lvalues)[insn.word(2)]; + + if (pointer.kind == Object::Kind::Value) + { + auto offsets = As<Int4>(*(routine->lvalues)[insn.word(1)]); + for (auto i = 0u; i < object.sizeInComponents; i++) + { + // Scattered store + for (int j = 0; j < 4; j++) + { + auto dst = ptrBase[Int(i) + Extract(offsets, j)]; + dst = Insert(dst, Extract(src[i], j), j); + } + } + } + else + { + // no divergent offsets + for (auto i = 0u; i < object.sizeInComponents; i++) + { + ptrBase[i] = src[i]; + } + } + break; + } default: printf("emit: ignoring opcode %d\n", insn.opcode()); break;