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));
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp index e6905f8..e17c5d2 100644 --- a/src/Pipeline/SpirvShader.hpp +++ b/src/Pipeline/SpirvShader.hpp
@@ -484,6 +484,8 @@ void EmitCompositeExtract(InsnIterator insn, SpirvRoutine *routine) const; void EmitVectorShuffle(InsnIterator insn, SpirvRoutine *routine) const; void EmitVectorTimesScalar(InsnIterator insn, SpirvRoutine *routine) const; + void EmitVectorExtractDynamic(InsnIterator insn, SpirvRoutine *routine) const; + void EmitVectorInsertDynamic(InsnIterator insn, SpirvRoutine *routine) const; void EmitUnaryOp(InsnIterator insn, SpirvRoutine *routine) const; void EmitBinaryOp(InsnIterator insn, SpirvRoutine *routine) const; void EmitDot(InsnIterator insn, SpirvRoutine *routine) const;