Add support for OpVectorInsertDynamic, OpVectorExtractDynamic
Bug: b/126873455
Tests: dEQP-VK.spirv_assembly.*
Change-Id: I8b6b6329b37469b9779178488f96fc62c341997b
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27308
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 4436d5a..560b932 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -312,6 +312,9 @@
case spv::OpCompositeInsert:
case spv::OpCompositeExtract:
case spv::OpVectorShuffle:
+ case spv::OpVectorTimesScalar:
+ case spv::OpVectorExtractDynamic:
+ case spv::OpVectorInsertDynamic:
case spv::OpNot: // Unary ops
case spv::OpSNegate:
case spv::OpFNegate:
@@ -374,7 +377,6 @@
case spv::OpIsNan:
case spv::OpAny:
case spv::OpAll:
- case spv::OpVectorTimesScalar:
// Instructions that yield an intermediate value
{
Type::ID typeId = insn.word(1);
@@ -1100,6 +1102,14 @@
EmitVectorShuffle(insn, routine);
break;
+ case spv::OpVectorExtractDynamic:
+ EmitVectorExtractDynamic(insn, routine);
+ break;
+
+ case spv::OpVectorInsertDynamic:
+ EmitVectorInsertDynamic(insn, routine);
+ break;
+
case spv::OpVectorTimesScalar:
EmitVectorTimesScalar(insn, routine);
break;
@@ -1544,6 +1554,41 @@
}
}
+ void SpirvShader::EmitVectorExtractDynamic(sw::SpirvShader::InsnIterator insn, sw::SpirvRoutine *routine) const
+ {
+ auto &type = getType(insn.word(1));
+ auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
+ auto &srcType = getType(getObject(insn.word(3)).type);
+
+ GenericValue src(this, routine, insn.word(3));
+ GenericValue index(this, routine, insn.word(4));
+
+ SIMD::UInt v = SIMD::UInt(0);
+
+ for (auto i = 0u; i < srcType.sizeInComponents; i++)
+ {
+ v |= CmpEQ(index.UInt(0), SIMD::UInt(i)) & src.UInt(i);
+ }
+
+ dst.emplace(0, v);
+ }
+
+ void SpirvShader::EmitVectorInsertDynamic(sw::SpirvShader::InsnIterator insn, sw::SpirvRoutine *routine) const
+ {
+ auto &type = getType(insn.word(1));
+ auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
+
+ GenericValue src(this, routine, insn.word(3));
+ GenericValue component(this, routine, insn.word(4));
+ GenericValue index(this, routine, insn.word(5));
+
+ for (auto i = 0u; i < type.sizeInComponents; i++)
+ {
+ SIMD::UInt mask = CmpEQ(SIMD::UInt(i), index.UInt(0));
+ dst.emplace(i, (src.UInt(i) & ~mask) | (component.UInt(0) & mask));
+ }
+ }
+
void SpirvShader::EmitVectorTimesScalar(InsnIterator insn, SpirvRoutine *routine) const
{
auto &type = getType(insn.word(1));