OSDN Git Service

Add support for OpMatrixTimesVector
authorChris Forbes <chrisforbes@google.com>
Wed, 27 Mar 2019 20:53:20 +0000 (09:53 +1300)
committerChris Forbes <chrisforbes@google.com>
Thu, 28 Mar 2019 19:49:02 +0000 (19:49 +0000)
Bug: b/126873455
Test: dEQP-VK.glsl.matrix.mul.*
Change-Id: I818ea43d952f8d6d6a2a569a18936277a69b2fab
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28130
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Ben Clayton <bclayton@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 f68af02..617c02f 100644 (file)
@@ -359,6 +359,7 @@ namespace sw
                        case spv::OpVectorShuffle:
                        case spv::OpVectorTimesScalar:
                        case spv::OpMatrixTimesScalar:
+                       case spv::OpMatrixTimesVector:
                        case spv::OpVectorExtractDynamic:
                        case spv::OpVectorInsertDynamic:
                        case spv::OpNot: // Unary ops
@@ -1472,6 +1473,9 @@ namespace sw
                case spv::OpMatrixTimesScalar:
                        return EmitVectorTimesScalar(insn, state);
 
+               case spv::OpMatrixTimesVector:
+                       return EmitMatrixTimesVector(insn, state);
+
                case spv::OpNot:
                case spv::OpSNegate:
                case spv::OpFNegate:
@@ -2053,6 +2057,28 @@ namespace sw
                return EmitResult::Continue;
        }
 
+       SpirvShader::EmitResult SpirvShader::EmitMatrixTimesVector(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 rhsType = getType(getObject(insn.word(4)).type);
+
+               for (auto i = 0u; i < type.sizeInComponents; i++)
+               {
+                       SIMD::Float v = lhs.Float(i) * rhs.Float(0);
+                       for (auto j = 1u; j < rhsType.sizeInComponents; j++)
+                       {
+                               v += lhs.Float(i + type.sizeInComponents * j) * rhs.Float(j);
+                       }
+                       dst.move(i, v);
+               }
+
+               return EmitResult::Continue;
+       }
+
        SpirvShader::EmitResult SpirvShader::EmitUnaryOp(InsnIterator insn, EmitState *state) const
        {
                auto routine = state->routine;
index f776643..1d54487 100644 (file)
@@ -596,6 +596,7 @@ namespace sw
                EmitResult EmitCompositeExtract(InsnIterator insn, EmitState *state) const;
                EmitResult EmitVectorShuffle(InsnIterator insn, EmitState *state) const;
                EmitResult EmitVectorTimesScalar(InsnIterator insn, EmitState *state) const;
+               EmitResult EmitMatrixTimesVector(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;