OSDN Git Service

Don't treat SIMD::Float preferentially
authorNicolas Capens <capn@google.com>
Tue, 19 Mar 2019 18:28:18 +0000 (14:28 -0400)
committerNicolas Capens <nicolascapens@google.com>
Wed, 20 Mar 2019 14:38:30 +0000 (14:38 +0000)
Intermediate::Scalar was defined as RValue<SIMD::Float>, even though it
can hold integers as well. Use abstract Reactor values instead which
don't have a statically defined type.

This change does not yet avoid bitcasting on access. The EmitLoad()
implementation still assumes values come in as float.

Bug b/128539387

Change-Id: I18f449ebf68db7ddd81679d6d028911e6c02fc38
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26868
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
src/Pipeline/SpirvShader.hpp

index c3bd154..ebce2bd 100644 (file)
@@ -66,49 +66,46 @@ namespace sw
        class Intermediate
        {
        public:
-               using Scalar = RValue<SIMD::Float>;
-
-               Intermediate(uint32_t size) : contents(new ContentsType[size]), size(size) {
+               Intermediate(uint32_t size) : scalar(new rr::Value*[size]), size(size) {
 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
-                       memset(contents, 0, sizeof(ContentsType) * size);
+                       memset(scalar, 0, sizeof(rr::Value*) * size);
 #endif
                }
 
                ~Intermediate()
                {
-                       for (auto i = 0u; i < size; i++)
-                               reinterpret_cast<Scalar *>(&contents[i])->~Scalar();
-                       delete [] contents;
+                       delete[] scalar;
                }
 
-               void emplace(uint32_t n, Scalar&& value)
+               void emplace(uint32_t i, RValue<SIMD::Float> &&scalar) { emplace(i, scalar.value); }
+               void emplace(uint32_t i, RValue<SIMD::Int> &&scalar)   { emplace(i, scalar.value); }
+               void emplace(uint32_t i, RValue<SIMD::UInt> &&scalar)  { emplace(i, scalar.value); }
+
+               void emplace(uint32_t i, const RValue<SIMD::Float> &scalar) { emplace(i, scalar.value); }
+               void emplace(uint32_t i, const RValue<SIMD::Int> &scalar)   { emplace(i, scalar.value); }
+               void emplace(uint32_t i, const RValue<SIMD::UInt> &scalar)  { emplace(i, scalar.value); }
+
+               // Value retrieval functions.
+               RValue<SIMD::Float> Float(uint32_t i) const
                {
-                       ASSERT(n < size);
-                       ASSERT(reinterpret_cast<Scalar const *>(&contents[n])->value == nullptr);
-                       new (&contents[n]) Scalar(value);
+                       ASSERT(i < size);
+                       ASSERT(scalar[i] != nullptr);
+                       return As<SIMD::Float>(scalar[i]);  // TODO(b/128539387): RValue<SIMD::Float>(scalar)
                }
 
-               void emplace(uint32_t n, const Scalar& value)
+               RValue<SIMD::Int> Int(uint32_t i) const
                {
-                       ASSERT(n < size);
-                       ASSERT(reinterpret_cast<Scalar const *>(&contents[n])->value == nullptr);
-                       new (&contents[n]) Scalar(value);
+                       ASSERT(i < size);
+                       ASSERT(scalar[i] != nullptr);
+                       return As<SIMD::Int>(scalar[i]);  // TODO(b/128539387): RValue<SIMD::Int>(scalar)
                }
 
-               // Emplace with cast helpers.
-               void emplace(uint32_t n, const RValue<SIMD::Int>& value) { emplace(n, As<SIMD::Float>(value)); }
-               void emplace(uint32_t n, const RValue<SIMD::UInt>& value) { emplace(n, As<SIMD::Float>(value)); }
-
-               // Value retrieval functions.
-               RValue<SIMD::Float> Float(uint32_t i) const
+               RValue<SIMD::UInt> UInt(uint32_t i) const
                {
                        ASSERT(i < size);
-                       auto scalar = reinterpret_cast<Scalar const *>(&contents[i]);
-                       ASSERT(scalar->value != nullptr);
-                       return *scalar;
+                       ASSERT(scalar[i] != nullptr);
+                       return As<SIMD::UInt>(scalar[i]);  // TODO(b/128539387): RValue<SIMD::UInt>(scalar)
                }
-               RValue<SIMD::Int> Int(uint32_t i) const { return As<SIMD::Int>(Float(i)); }
-               RValue<SIMD::UInt> UInt(uint32_t i) const { return As<SIMD::UInt>(Float(i)); }
 
                // No copy/move construction or assignment
                Intermediate(Intermediate const &) = delete;
@@ -117,9 +114,14 @@ namespace sw
                Intermediate & operator=(Intermediate &&) = delete;
 
        private:
-               using ContentsType = std::aligned_storage<sizeof(Scalar), alignof(Scalar)>::type;
+               void emplace(uint32_t i, rr::Value *value)
+               {
+                       ASSERT(i < size);
+                       ASSERT(scalar[i] == nullptr);
+                       scalar[i] = value;
+               }
 
-               ContentsType *contents;
+               rr::Value **const scalar;
                uint32_t size;
        };