OSDN Git Service

Add support for OpMatrixTimesMatrix
authorChris Forbes <chrisforbes@google.com>
Fri, 29 Mar 2019 02:08:39 +0000 (19:08 -0700)
committerChris Forbes <chrisforbes@google.com>
Fri, 29 Mar 2019 02:56:30 +0000 (02:56 +0000)
Bug: b/126873455
Test: dEQP-VK.glsl.matrix.*
Change-Id: I3070690017263b3bf766a329ef7729206f285e45
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28228
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>

src/Pipeline/SpirvShader.cpp
src/Pipeline/SpirvShader.hpp

index 9383517..c54c4cb 100644 (file)
@@ -361,6 +361,7 @@ namespace sw
                        case spv::OpMatrixTimesScalar:
                        case spv::OpMatrixTimesVector:
                        case spv::OpVectorTimesMatrix:
+                       case spv::OpMatrixTimesMatrix:
                        case spv::OpVectorExtractDynamic:
                        case spv::OpVectorInsertDynamic:
                        case spv::OpNot: // Unary ops
@@ -1480,6 +1481,9 @@ namespace sw
                case spv::OpVectorTimesMatrix:
                        return EmitVectorTimesMatrix(insn, state);
 
+               case spv::OpMatrixTimesMatrix:
+                       return EmitMatrixTimesMatrix(insn, state);
+
                case spv::OpNot:
                case spv::OpSNegate:
                case spv::OpFNegate:
@@ -2105,6 +2109,34 @@ namespace sw
                return EmitResult::Continue;
        }
 
+       SpirvShader::EmitResult SpirvShader::EmitMatrixTimesMatrix(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 lhs = GenericValue(this, routine, insn.word(3));
+               auto rhs = GenericValue(this, routine, insn.word(4));
+
+               auto numColumns = type.definition.word(3);
+               auto numRows = getType(type.definition.word(2)).definition.word(3);
+               auto numAdds = getType(getObject(insn.word(3)).type).definition.word(3);
+
+               for (auto row = 0u; row < numRows; row++)
+               {
+                       for (auto col = 0u; col < numColumns; col++)
+                       {
+                               SIMD::Float v = SIMD::Float(0);
+                               for (auto i = 0u; i < numAdds; i++)
+                               {
+                                       v += lhs.Float(i * numRows + row) * rhs.Float(col * numAdds + i);
+                               }
+                               dst.move(numRows * col + row, v);
+                       }
+               }
+
+               return EmitResult::Continue;
+       }
+
        SpirvShader::EmitResult SpirvShader::EmitUnaryOp(InsnIterator insn, EmitState *state) const
        {
                auto routine = state->routine;
index 3410dc1..498c547 100644 (file)
@@ -598,6 +598,7 @@ namespace sw
                EmitResult EmitVectorTimesScalar(InsnIterator insn, EmitState *state) const;
                EmitResult EmitMatrixTimesVector(InsnIterator insn, EmitState *state) const;
                EmitResult EmitVectorTimesMatrix(InsnIterator insn, EmitState *state) const;
+               EmitResult EmitMatrixTimesMatrix(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;