OSDN Git Service

Add support for OpVectorInsertDynamic, OpVectorExtractDynamic
authorChris Forbes <chrisforbes@google.com>
Fri, 15 Mar 2019 17:31:08 +0000 (10:31 -0700)
committerChris Forbes <chrisforbes@google.com>
Fri, 15 Mar 2019 19:19:25 +0000 (19:19 +0000)
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>

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

index 4436d5a..560b932 100644 (file)
@@ -312,6 +312,9 @@ namespace sw
                        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 @@ namespace sw
                        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 @@ namespace sw
                        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 @@ namespace sw
                }
        }
 
+       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));
index e6905f8..e17c5d2 100644 (file)
@@ -484,6 +484,8 @@ namespace sw
                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;