OSDN Git Service

Fixed array constructors
authorAlexis Hetu <sugoi@google.com>
Wed, 28 Sep 2016 00:50:45 +0000 (20:50 -0400)
committerAlexis Hétu <sugoi@google.com>
Wed, 28 Sep 2016 18:40:06 +0000 (18:40 +0000)
Fixed first class array constructors by allowing basic type
arrays and structure arrays to be handled properly for the
EOpConstruct* operations.

This fixes all dEQP.functional.shaders.arrays.* tests.

Change-Id: I4fe99ec5256abf6483d3595890ba9c426abc97f8
Reviewed-on: https://swiftshader-review.googlesource.com/7351
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/compiler/OutputASM.cpp
src/OpenGL/compiler/ParseHelper.cpp

index 4cc379a..d88ce14 100644 (file)
@@ -1337,17 +1337,20 @@ namespace glsl
                        if(visit == PostVisit)
                        {
                                int component = 0;
-
+                               int arrayMaxIndex = result->isArray() ? result->getArraySize() - 1 : 0;
+                               int arrayComponents = result->getType().getElementSize();
                                for(size_t i = 0; i < argumentCount; i++)
                                {
                                        TIntermTyped *argi = arg[i]->getAsTyped();
                                        int size = argi->getNominalSize();
+                                       int arrayIndex = std::min(component / arrayComponents, arrayMaxIndex);
+                                       int swizzle = component - (arrayIndex * arrayComponents);
 
                                        if(!argi->isMatrix())
                                        {
-                                               Instruction *mov = emitCast(result, argi);
-                                               mov->dst.mask = (0xF << component) & 0xF;
-                                               mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);
+                                               Instruction *mov = emitCast(result, arrayIndex, argi, 0);
+                                               mov->dst.mask = (0xF << swizzle) & 0xF;
+                                               mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
 
                                                component += size;
                                        }
@@ -1357,9 +1360,9 @@ namespace glsl
 
                                                while(component < resultType.getNominalSize())
                                                {
-                                                       Instruction *mov = emitCast(result, 0, argi, column);
-                                                       mov->dst.mask = (0xF << component) & 0xF;
-                                                       mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);
+                                                       Instruction *mov = emitCast(result, arrayIndex, argi, column);
+                                                       mov->dst.mask = (0xF << swizzle) & 0xF;
+                                                       mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
 
                                                        column++;
                                                        component += size;
@@ -1395,22 +1398,28 @@ namespace glsl
                                }
                                else if(arg0->isMatrix())
                                {
-                                       const int inCols = arg0->getNominalSize();
-                                       const int inRows = arg0->getSecondarySize();
+                                       int arraySize = result->isArray() ? result->getArraySize() : 1;
 
-                                       for(int i = 0; i < outCols; i++)
+                                       for(int n = 0; n < arraySize; n++)
                                        {
-                                               if(i >= inCols || outRows > inRows)
-                                               {
-                                                       // Initialize to identity matrix
-                                                       Constant col((i == 0 ? 1.0f : 0.0f), (i == 1 ? 1.0f : 0.0f), (i == 2 ? 1.0f : 0.0f), (i == 3 ? 1.0f : 0.0f));
-                                                       emitCast(result, i, &col, 0);
-                                               }
+                                               TIntermTyped *argi = arg[n]->getAsTyped();
+                                               const int inCols = argi->getNominalSize();
+                                               const int inRows = argi->getSecondarySize();
 
-                                               if(i < inCols)
+                                               for(int i = 0; i < outCols; i++)
                                                {
-                                                       Instruction *mov = emitCast(result, i, arg0, i);
-                                                       mov->dst.mask = 0xF >> (4 - inRows);
+                                                       if(i >= inCols || outRows > inRows)
+                                                       {
+                                                               // Initialize to identity matrix
+                                                               Constant col((i == 0 ? 1.0f : 0.0f), (i == 1 ? 1.0f : 0.0f), (i == 2 ? 1.0f : 0.0f), (i == 3 ? 1.0f : 0.0f));
+                                                               emitCast(result, i + n * outCols, &col, 0);
+                                                       }
+
+                                                       if(i < inCols)
+                                                       {
+                                                               Instruction *mov = emitCast(result, i + n * outCols, argi, i);
+                                                               mov->dst.mask = 0xF >> (4 - inRows);
+                                                       }
                                                }
                                        }
                                }
index a15fb0f..645f490 100644 (file)
@@ -2076,7 +2076,23 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType*
                aggregateArguments->getSequence().push_back(arguments);
        }
 
-       if(op == EOpConstructStruct)
+       if(type->isArray())
+       {
+               // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
+               // the array.
+               for(TIntermNode *&argNode : aggregateArguments->getSequence())
+               {
+                       const TType &argType = argNode->getAsTyped()->getType();
+                       // It has already been checked that the argument is not an array.
+                       ASSERT(!argType.isArray());
+                       if(!argType.sameElementType(*type))
+                       {
+                               error(line, "Array constructor argument has an incorrect type", "Error");
+                               return false;
+                       }
+               }
+       }
+       else if(op == EOpConstructStruct)
        {
                const TFieldList &fields = type->getStruct()->fields();
                TIntermSequence &args = aggregateArguments->getSequence();