SpirvShader: Implement OpTranspose
Bug: b/126873455
Tests: dEQP-VK.glsl.matrix.transpose.*
Change-Id: I5b793ecda3d30de456b9ec7f65c386975a86b97f
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28470
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: 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 80ac8ed..553633c 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -362,6 +362,7 @@
case spv::OpVectorTimesMatrix:
case spv::OpMatrixTimesMatrix:
case spv::OpOuterProduct:
+ case spv::OpTranspose:
case spv::OpVectorExtractDynamic:
case spv::OpVectorInsertDynamic:
case spv::OpNot: // Unary ops
@@ -1627,6 +1628,9 @@
case spv::OpOuterProduct:
return EmitOuterProduct(insn, state);
+ case spv::OpTranspose:
+ return EmitTranspose(insn, state);
+
case spv::OpNot:
case spv::OpSNegate:
case spv::OpFNegate:
@@ -2291,6 +2295,27 @@
return EmitResult::Continue;
}
+ SpirvShader::EmitResult SpirvShader::EmitTranspose(InsnIterator insn, EmitState *state) const
+ {
+ auto routine = state->routine;
+ auto &type = getType(insn.word(1));
+ auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
+ auto mat = GenericValue(this, routine, insn.word(3));
+
+ auto numCols = type.definition.word(3);
+ auto numRows = getType(type.definition.word(2)).sizeInComponents;
+
+ for (auto col = 0u; col < numCols; col++)
+ {
+ for (auto row = 0u; row < numRows; row++)
+ {
+ dst.move(col * numRows + row, mat.Float(row * numCols + col));
+ }
+ }
+
+ return EmitResult::Continue;
+ }
+
SpirvShader::EmitResult SpirvShader::EmitUnaryOp(InsnIterator insn, EmitState *state) const
{
auto routine = state->routine;
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 34ac47a..bfbe26a 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -649,6 +649,7 @@
EmitResult EmitVectorTimesMatrix(InsnIterator insn, EmitState *state) const;
EmitResult EmitMatrixTimesMatrix(InsnIterator insn, EmitState *state) const;
EmitResult EmitOuterProduct(InsnIterator insn, EmitState *state) const;
+ EmitResult EmitTranspose(InsnIterator insn, EmitState *state) const;
EmitResult EmitVectorExtractDynamic(InsnIterator insn, EmitState *state) const;
EmitResult EmitVectorInsertDynamic(InsnIterator insn, EmitState *state) const;
EmitResult EmitUnaryOp(InsnIterator insn, EmitState *state) const;