OSDN Git Service

Support bitcasts between scalars and short vectors.
authorNicolas Capens <capn@google.com>
Tue, 25 Jul 2017 17:56:46 +0000 (13:56 -0400)
committerNicolas Capens <nicolascapens@google.com>
Wed, 26 Jul 2017 19:28:11 +0000 (19:28 +0000)
Subzero only supports 128-bit vectors currently, but we need to support
bitcasting between scalars and (emulated) short vectors of the same
size. Subzero implicitly supports it on x86 by using movd instructions,
but on ARM we have to emulate it in Reactor until support for it is
added in Subzero.

Bug swiftshader:48

Change-Id: I95accbc3665815a46dac8e52ce30939ac64aaf44
Reviewed-on: https://swiftshader-review.googlesource.com/10929
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/Reactor/SubzeroReactor.cpp
src/Shader/SamplerCore.cpp

index 23bcedc..6fbd7a5 100644 (file)
@@ -123,6 +123,7 @@ namespace
        const bool CPUID::ARM = CPUID::detectARM();
        const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
        const bool emulateIntrinsics = CPUID::ARM;
+       const bool emulateMismatchedBitCast = CPUID::ARM;
 }
 
 namespace sw
@@ -981,6 +982,25 @@ namespace sw
 
        Value *Nucleus::createBitCast(Value *v, Type *destType)
        {
+               // Bitcasts must be between types of the same logical size. But with emulated narrow vectors we need
+               // support for casting between scalars and wide vectors. For platforms where this is not supported,
+               // emulate them by writing to the stack and reading back as the destination type.
+               if(emulateMismatchedBitCast)
+               {
+                       if(!Ice::isVectorType(v->getType()) && Ice::isVectorType(T(destType)))
+                       {
+                               Value *address = allocateStackVariable(destType);
+                               createStore(v, address, T(v->getType()));
+                               return createLoad(address, destType);
+                       }
+                       else if(Ice::isVectorType(v->getType()) && !Ice::isVectorType(T(destType)))
+                       {
+                               Value *address = allocateStackVariable(T(v->getType()));
+                               createStore(v, address, T(v->getType()));
+                               return createLoad(address, destType);
+                       }
+               }
+
                return createCast(Ice::InstCast::Bitcast, v, destType);
        }
 
index 0ee9014..9c58e70 100644 (file)
@@ -1937,16 +1937,16 @@ namespace sw
                                        {
                                        case FORMAT_R8I:
                                        case FORMAT_R8UI:
-                                       {
-                                               Int zero(0);
-                                               c.x = Unpack(As<Byte4>(c0), As<Byte4>(zero));
-                                               // Propagate sign bit
-                                               if(state.textureFormat == FORMAT_R8I)
                                                {
-                                                       c.x = (c.x << 8) >> 8;
+                                                       Int zero(0);
+                                                       c.x = Unpack(As<Byte4>(c0), As<Byte4>(zero));
+                                                       // Propagate sign bit
+                                                       if(state.textureFormat == FORMAT_R8I)
+                                                       {
+                                                               c.x = (c.x << 8) >> 8;
+                                                       }
                                                }
-                                       }
-                                       break;
+                                               break;
                                        default:
                                                c.x = Unpack(As<Byte4>(c0));
                                                break;