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;