OSDN Git Service

SpirvShader: Add SIMD namespace.
authorBen Clayton <headlessclayton@gmail.com>
Tue, 26 Feb 2019 11:02:42 +0000 (11:02 +0000)
committerBen Clayton <bclayton@google.com>
Thu, 28 Feb 2019 01:30:56 +0000 (01:30 +0000)
This namespace declares typedefs that represent per-lane-scalars.

Once we start mixing per-lane storage with linear external memory, this will help readability.

Bug: b/126126820
Change-Id: Ia128c3cc97dd77b3d5c4b7bd9537c19427a9ac3f
Reviewed-on: https://swiftshader-review.googlesource.com/c/25548
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
src/Pipeline/SpirvShader.cpp
src/Pipeline/SpirvShader.hpp

index bfdf462..96f88f4 100644 (file)
@@ -548,20 +548,20 @@ namespace sw
                VisitInterfaceInner<F>(def.word(1), d, f);
        }
 
-       Int4 SpirvShader::WalkAccessChain(ObjectID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const
+       SIMD::Int SpirvShader::WalkAccessChain(ObjectID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const
        {
                // TODO: think about explicit layout (UBO/SSBO) storage classes
                // TODO: avoid doing per-lane work in some cases if we can?
 
                int constantOffset = 0;
-               Int4 dynamicOffset = Int4(0);
+               SIMD::Int dynamicOffset = SIMD::Int(0);
                auto &baseObject = getObject(id);
                TypeID typeId = getType(baseObject.type).element;
 
                // The <base> operand is an intermediate value itself, ie produced by a previous OpAccessChain.
                // Start with its offset and build from there.
                if (baseObject.kind == Object::Kind::Value)
-                       dynamicOffset += As<Int4>(routine->getIntermediate(id)[0]);
+                       dynamicOffset += As<SIMD::Int>(routine->getIntermediate(id)[0]);
 
                for (auto i = 0u; i < numIndexes; i++)
                {
@@ -590,7 +590,7 @@ namespace sw
                                if (obj.kind == Object::Kind::Constant)
                                        constantOffset += stride * GetConstantInt(indexIds[i]);
                                else
-                                       dynamicOffset += Int4(stride) * As<Int4>(routine->getIntermediate(indexIds[i])[0]);
+                                       dynamicOffset += SIMD::Int(stride) * As<SIMD::Int>(routine->getIntermediate(indexIds[i])[0]);
                                typeId = type.element;
                                break;
                        }
@@ -600,7 +600,7 @@ namespace sw
                        }
                }
 
-               return dynamicOffset + Int4(constantOffset);
+               return dynamicOffset + SIMD::Int(constantOffset);
        }
 
        uint32_t SpirvShader::WalkLiteralAccessChain(TypeID typeId, uint32_t numIndexes, uint32_t const *indexes) const
@@ -853,12 +853,12 @@ namespace sw
 
                                if (pointer.kind == Object::Kind::Value)
                                {
-                                       auto offsets = As<Int4>(routine->getIntermediate(insn.word(3))[0]);
+                                       auto offsets = As<SIMD::Int>(routine->getIntermediate(insn.word(3))[0]);
                                        for (auto i = 0u; i < objectTy.sizeInComponents; i++)
                                        {
                                                // i wish i had a Float,Float,Float,Float constructor here..
-                                               Float4 v;
-                                               for (int j = 0; j < 4; j++)
+                                               SIMD::Float v;
+                                               for (int j = 0; j < SIMD::Width; j++)
                                                {
                                                        Int offset = Int(i) + Extract(offsets, j);
                                                        v = Insert(v, Extract(ptrBase[offset], j), j);
@@ -895,7 +895,7 @@ namespace sw
                                        UNIMPLEMENTED("Descriptor-backed OpAccessChain not yet implemented");
                                }
                                auto &dst = routine->createIntermediate(objectId, type.sizeInComponents);
-                               dst.emplace(0, As<Float4>(WalkAccessChain(baseId, insn.wordCount() - 4, insn.wordPointer(4), routine)));
+                               dst.emplace(0, As<SIMD::Float>(WalkAccessChain(baseId, insn.wordCount() - 4, insn.wordPointer(4), routine)));
                                break;
                        }
                        case spv::OpStore:
@@ -924,11 +924,11 @@ namespace sw
 
                                        if (pointer.kind == Object::Kind::Value)
                                        {
-                                               auto offsets = As<Int4>(routine->getIntermediate(pointerId)[0]);
+                                               auto offsets = As<SIMD::Int>(routine->getIntermediate(pointerId)[0]);
                                                for (auto i = 0u; i < elementTy.sizeInComponents; i++)
                                                {
                                                        // Scattered store
-                                                       for (int j = 0; j < 4; j++)
+                                                       for (int j = 0; j < SIMD::Width; j++)
                                                        {
                                                                auto dst = ptrBase[Int(i) + Extract(offsets, j)];
                                                                dst = Insert(dst, Float(src[i]), j);
@@ -940,7 +940,7 @@ namespace sw
                                                // no divergent offsets
                                                for (auto i = 0u; i < elementTy.sizeInComponents; i++)
                                                {
-                                                       ptrBase[i] = RValue<Float4>(src[i]);
+                                                       ptrBase[i] = RValue<SIMD::Float>(src[i]);
                                                }
                                        }
                                }
@@ -950,11 +950,11 @@ namespace sw
 
                                        if (pointer.kind == Object::Kind::Value)
                                        {
-                                               auto offsets = As<Int4>(routine->getIntermediate(pointerId)[0]);
+                                               auto offsets = As<SIMD::Int>(routine->getIntermediate(pointerId)[0]);
                                                for (auto i = 0u; i < elementTy.sizeInComponents; i++)
                                                {
                                                        // Scattered store
-                                                       for (int j = 0; j < 4; j++)
+                                                       for (int j = 0; j < SIMD::Width; j++)
                                                        {
                                                                auto dst = ptrBase[Int(i) + Extract(offsets, j)];
                                                                dst = Insert(dst, Extract(src[i], j), j);
@@ -1041,7 +1041,7 @@ namespace sw
                                        {
                                                // Undefined value. Until we decide to do real undef values, zero is as good
                                                // a value as any
-                                               dst.emplace(i, RValue<Float4>(0.0f));
+                                               dst.emplace(i, RValue<SIMD::Float>(0.0f));
                                        }
                                        else if (selector < type.sizeInComponents)
                                        {
index 6d4a8e4..96302d7 100644 (file)
 
 namespace sw
 {
+       // Forward declarations.
+       class SpirvRoutine;
+
+       // SIMD contains types that represent multiple scalars packed into a single
+       // vector data type. Types in the SIMD namespace provide a semantic hint
+       // that the data should be treated as a per-execution-lane scalar instead of
+       // a typical euclidean-style vector type.
+       namespace SIMD
+       {
+               // Width is the number of per-lane scalars packed into each SIMD vector.
+               static constexpr int Width = 4;
+
+               using Float = rr::Float4;
+               using Int = rr::Int4;
+       }
+
        // Incrementally constructed complex bundle of rvalues
        // Effectively a restricted vector, supporting only:
        // - allocation to a (runtime-known) fixed size
@@ -39,7 +55,7 @@ namespace sw
        class Intermediate
        {
        public:
-               using Scalar = RValue<Float4>;
+               using Scalar = RValue<SIMD::Float>;
 
                Intermediate(uint32_t size) : contents(new ContentsType[size]), size(size) {}
 
@@ -56,6 +72,12 @@ namespace sw
                        new (&contents[n]) Scalar(value);
                }
 
+               void emplace(uint32_t n, const Scalar& value)
+               {
+                       assert(n < size);
+                       new (&contents[n]) Scalar(value);
+               }
+
                Scalar const & operator[](uint32_t n) const
                {
                        assert(n < size);
@@ -75,8 +97,6 @@ namespace sw
                uint32_t size;
        };
 
-       class SpirvRoutine;
-
        class SpirvShader
        {
        public:
@@ -348,14 +368,15 @@ namespace sw
 
                void ProcessInterfaceVariable(Object &object);
 
-               Int4 WalkAccessChain(ObjectID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const;
+               SIMD::Int WalkAccessChain(ObjectID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const;
                uint32_t WalkLiteralAccessChain(TypeID id, uint32_t numIndexes, uint32_t const *indexes) const;
        };
 
        class SpirvRoutine
        {
        public:
-               using Value = Array<Float4>;
+               using Value = Array<SIMD::Float>;
+
                std::unordered_map<SpirvShader::ObjectID, Value> lvalues;
 
                std::unordered_map<SpirvShader::ObjectID, Intermediate> intermediates;
@@ -406,13 +427,13 @@ namespace sw
                                obj(shader->getObject(objId)),
                                intermediate(obj.kind == SpirvShader::Object::Kind::Value ? &routine->getIntermediate(objId) : nullptr) {}
 
-               RValue<Float4> operator[](uint32_t i) const
+               RValue<SIMD::Float> operator[](uint32_t i) const
                {
                        if (intermediate)
                                return (*intermediate)[i];
 
                        auto constantValue = reinterpret_cast<float *>(obj.constantValue.get());
-                       return RValue<Float4>(constantValue[i]);
+                       return RValue<SIMD::Float>(constantValue[i]);
                }
        };