OSDN Git Service

Refactor lvalue() to return the root node.
authorNicolas Capens <capn@google.com>
Wed, 15 Nov 2017 21:39:47 +0000 (16:39 -0500)
committerNicolas Capens <nicolascapens@google.com>
Thu, 16 Nov 2017 22:28:20 +0000 (22:28 +0000)
This will enable reusing it to determine the root node of rvalues as
well. The only functional change is that struct indexing no longer
overrides the register type. This is of no effect here since lvalue
intermediates already inherited their type from the root node, but for
rvalues the intermediates are considered temporary registers, while
instead the root's type should be used.

Change-Id: I2dbd1b0f8886c3f111a2ed3ef7fe4e9a5b480085
Reviewed-on: https://swiftshader-review.googlesource.com/13930
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/OpenGL/compiler/OutputASM.cpp
src/OpenGL/compiler/OutputASM.h
src/Shader/Shader.hpp

index 56fde3d..d3a0184 100644 (file)
@@ -614,7 +614,7 @@ namespace glsl
                                                if(left->totalRegisterCount() > 1)
                                                {
                                                        sw::Shader::SourceParameter relativeRegister;
-                                                       argument(relativeRegister, right);
+                                                       source(relativeRegister, right);
 
                                                        mov->src[0].rel.type = relativeRegister.type;
                                                        mov->src[0].rel.index = relativeRegister.index;
@@ -1887,9 +1887,7 @@ namespace glsl
 
                if(dst)
                {
-                       instruction->dst.type = registerType(dst);
-                       instruction->dst.index = registerIndex(dst) + dstIndex;
-                       instruction->dst.mask = writeMask(dst);
+                       destination(instruction->dst, dst, dstIndex);
                }
 
                if(src0)
@@ -1898,11 +1896,11 @@ namespace glsl
                        instruction->dst.partialPrecision = src && (src->getPrecision() <= EbpLow);
                }
 
-               argument(instruction->src[0], src0, index0);
-               argument(instruction->src[1], src1, index1);
-               argument(instruction->src[2], src2, index2);
-               argument(instruction->src[3], src3, index3);
-               argument(instruction->src[4], src4, index4);
+               source(instruction->src[0], src0, index0);
+               source(instruction->src[1], src1, index1);
+               source(instruction->src[2], src2, index2);
+               source(instruction->src[3], src3, index3);
+               source(instruction->src[4], src4, index4);
 
                shader->append(instruction);
 
@@ -2176,7 +2174,7 @@ namespace glsl
                return argumentInfo;
        }
 
-       void OutputASM::argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index)
+       void OutputASM::source(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index)
        {
                if(argument)
                {
@@ -2286,6 +2284,13 @@ namespace glsl
                }
        }
 
+       void OutputASM::destination(sw::Shader::DestinationParameter &parameter, TIntermTyped *arg, int index)
+       {
+               parameter.type = registerType(arg);
+               parameter.index = registerIndex(arg) + index;
+               parameter.mask = writeMask(arg);
+       }
+
        void OutputASM::copy(TIntermTyped *dst, TIntermNode *src, int offset)
        {
                for(int index = 0; index < dst->totalRegisterCount(); index++)
@@ -2328,8 +2333,8 @@ namespace glsl
                        insert->src[0].type = insert->dst.type;
                        insert->src[0].index = insert->dst.index;
                        insert->src[0].rel = insert->dst.rel;
-                       argument(insert->src[1], src);
-                       argument(insert->src[2], binary->getRight());
+                       source(insert->src[1], src);
+                       source(insert->src[2], binary->getRight());
 
                        shader->append(insert);
                }
@@ -2340,7 +2345,7 @@ namespace glsl
                        Temporary address(this);
                        int swizzle = lvalue(mov1->dst, address, dst);
 
-                       argument(mov1->src[0], src);
+                       source(mov1->src[0], src);
                        mov1->src[0].swizzle = swizzleSwizzle(mov1->src[0].swizzle, swizzle);
 
                        shader->append(mov1);
@@ -2353,7 +2358,7 @@ namespace glsl
                                mov->dst.index += offset;
                                mov->dst.mask = writeMask(dst, offset);
 
-                               argument(mov->src[0], src, offset);
+                               source(mov->src[0], src, offset);
 
                                shader->append(mov);
                        }
@@ -2362,6 +2367,20 @@ namespace glsl
 
        int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node)
        {
+               TIntermTyped *root = nullptr;
+               unsigned int offset = 0;
+               unsigned char mask = 0xF;
+               int swizzle = lvalue(root, offset, dst.rel, mask, address, node);
+
+               dst.type = registerType(root);
+               dst.index = registerIndex(root) + offset;
+               dst.mask = mask;
+
+               return swizzle;
+       }
+
+       int OutputASM::lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node)
+       {
                TIntermTyped *result = node;
                TIntermBinary *binary = node->getAsBinaryNode();
                TIntermSymbol *symbol = node->getAsSymbolNode();
@@ -2371,7 +2390,7 @@ namespace glsl
                        TIntermTyped *left = binary->getLeft();
                        TIntermTyped *right = binary->getRight();
 
-                       int leftSwizzle = lvalue(dst, address, left);   // Resolve the l-value of the left side
+                       int leftSwizzle = lvalue(root, offset, rel, mask, address, left);   // Resolve the l-value of the left side
 
                        switch(binary->getOp())
                        {
@@ -2381,22 +2400,22 @@ namespace glsl
 
                                        if(left->isRegister())
                                        {
-                                               int leftMask = dst.mask;
+                                               int leftMask = mask;
 
-                                               dst.mask = 1;
-                                               while((leftMask & dst.mask) == 0)
+                                               mask = 1;
+                                               while((leftMask & mask) == 0)
                                                {
-                                                       dst.mask = dst.mask << 1;
+                                                       mask = mask << 1;
                                                }
 
                                                int element = swizzleElement(leftSwizzle, rightIndex);
-                                               dst.mask = 1 << element;
+                                               mask = 1 << element;
 
                                                return element;
                                        }
                                        else if(left->isArray() || left->isMatrix())
                                        {
-                                               dst.index += rightIndex * result->totalRegisterCount();
+                                               offset += rightIndex * result->totalRegisterCount();
                                                return 0xE4;
                                        }
                                        else UNREACHABLE(0);
@@ -2414,42 +2433,42 @@ namespace glsl
                                        {
                                                int scale = result->totalRegisterCount();
 
-                                               if(dst.rel.type == sw::Shader::PARAMETER_VOID)   // Use the index register as the relative address directly
+                                               if(rel.type == sw::Shader::PARAMETER_VOID)   // Use the index register as the relative address directly
                                                {
                                                        if(left->totalRegisterCount() > 1)
                                                        {
                                                                sw::Shader::SourceParameter relativeRegister;
-                                                               argument(relativeRegister, right);
+                                                               source(relativeRegister, right);
 
-                                                               dst.rel.index = relativeRegister.index;
-                                                               dst.rel.type = relativeRegister.type;
-                                                               dst.rel.scale = scale;
-                                                               dst.rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
+                                                               rel.index = relativeRegister.index;
+                                                               rel.type = relativeRegister.type;
+                                                               rel.scale = scale;
+                                                               rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
                                                        }
                                                }
-                                               else if(dst.rel.index != registerIndex(&address))   // Move the previous index register to the address register
+                                               else if(rel.index != registerIndex(&address))   // Move the previous index register to the address register
                                                {
                                                        if(scale == 1)
                                                        {
-                                                               Constant oldScale((int)dst.rel.scale);
+                                                               Constant oldScale((int)rel.scale);
                                                                Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);
-                                                               mad->src[0].index = dst.rel.index;
-                                                               mad->src[0].type = dst.rel.type;
+                                                               mad->src[0].index = rel.index;
+                                                               mad->src[0].type = rel.type;
                                                        }
                                                        else
                                                        {
-                                                               Constant oldScale((int)dst.rel.scale);
+                                                               Constant oldScale((int)rel.scale);
                                                                Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);
-                                                               mul->src[0].index = dst.rel.index;
-                                                               mul->src[0].type = dst.rel.type;
+                                                               mul->src[0].index = rel.index;
+                                                               mul->src[0].type = rel.type;
 
                                                                Constant newScale(scale);
                                                                emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);
                                                        }
 
-                                                       dst.rel.type = sw::Shader::PARAMETER_TEMP;
-                                                       dst.rel.index = registerIndex(&address);
-                                                       dst.rel.scale = 1;
+                                                       rel.type = sw::Shader::PARAMETER_TEMP;
+                                                       rel.index = registerIndex(&address);
+                                                       rel.scale = 1;
                                                }
                                                else   // Just add the new index to the address register
                                                {
@@ -2481,9 +2500,8 @@ namespace glsl
                                                fieldOffset += fields[i]->type()->totalRegisterCount();
                                        }
 
-                                       dst.type = registerType(left);
-                                       dst.index += fieldOffset;
-                                       dst.mask = writeMask(result);
+                                       offset += fieldOffset;
+                                       mask = writeMask(result);
 
                                        return 0xE4;
                                }
@@ -2492,7 +2510,7 @@ namespace glsl
                                {
                                        ASSERT(left->isRegister());
 
-                                       int leftMask = dst.mask;
+                                       int leftMask = mask;
 
                                        int swizzle = 0;
                                        int rightMask = 0;
@@ -2508,7 +2526,7 @@ namespace glsl
                                                swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2);
                                        }
 
-                                       dst.mask = leftMask & rightMask;
+                                       mask = leftMask & rightMask;
 
                                        return swizzle;
                                }
@@ -2520,9 +2538,20 @@ namespace glsl
                }
                else if(symbol)
                {
-                       dst.type = registerType(symbol);
-                       dst.index = registerIndex(symbol);
-                       dst.mask = writeMask(symbol);
+                       root = symbol;
+                       offset = 0;
+                       mask = writeMask(symbol);
+
+                       return 0xE4;
+               }
+               else
+               {
+                       node->traverse(this);
+
+                       root = node;
+                       offset = 0;
+                       mask = writeMask(node);
+
                        return 0xE4;
                }
 
@@ -2537,10 +2566,10 @@ namespace glsl
                }
 
                const TQualifier qualifier = operand->getQualifier();
-               if((EvqFragColor == qualifier) || (EvqFragData == qualifier))
+               if((qualifier == EvqFragColor) || (qualifier == EvqFragData))
                {
-                       if(((EvqFragData == qualifier) && (EvqFragColor == outputQualifier)) ||
-                          ((EvqFragColor == qualifier) && (EvqFragData == outputQualifier)))
+                       if(((qualifier == EvqFragData) && (outputQualifier == EvqFragColor)) ||
+                          ((qualifier == EvqFragColor) && (outputQualifier == EvqFragData)))
                        {
                                mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", "");
                        }
index f59380e..2d04e38 100644 (file)
@@ -251,14 +251,14 @@ namespace glsl
                void emitShader(Scope scope);
 
                // Visit AST nodes and output their code to the body stream
-               virtual void visitSymbol(TIntermSymbol*);
-               virtual bool visitBinary(Visit visit, TIntermBinary*);
-               virtual bool visitUnary(Visit visit, TIntermUnary*);
-               virtual bool visitSelection(Visit visit, TIntermSelection*);
-               virtual bool visitAggregate(Visit visit, TIntermAggregate*);
-               virtual bool visitLoop(Visit visit, TIntermLoop*);
-               virtual bool visitBranch(Visit visit, TIntermBranch*);
-               virtual bool visitSwitch(Visit, TIntermSwitch*);
+               void visitSymbol(TIntermSymbol*) override;
+               bool visitBinary(Visit visit, TIntermBinary*) override;
+               bool visitUnary(Visit visit, TIntermUnary*) override;
+               bool visitSelection(Visit visit, TIntermSelection*) override;
+               bool visitAggregate(Visit visit, TIntermAggregate*) override;
+               bool visitLoop(Visit visit, TIntermLoop*) override;
+               bool visitBranch(Visit visit, TIntermBranch*) override;
+               bool visitSwitch(Visit, TIntermSwitch*) override;
 
                sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
                Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0);
@@ -270,10 +270,12 @@ namespace glsl
                void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
                void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
                void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
-               void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);
+               void source(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);
+               void destination(sw::Shader::DestinationParameter &parameter, TIntermTyped *argument, int index = 0);
                void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
                void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
                int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
+               int lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node);
                sw::Shader::ParameterType registerType(TIntermTyped *operand);
                bool hasFlatQualifier(TIntermTyped *operand);
                unsigned int registerIndex(TIntermTyped *operand);
index 7f89359..695f72e 100644 (file)
@@ -396,6 +396,15 @@ namespace sw
                        ANALYSIS_LEAVE    = 0x00000008,
                };
 
+               struct Relative
+               {
+                       ParameterType type : 8;
+                       unsigned int index;
+                       unsigned int swizzle : 8;
+                       unsigned int scale;
+                       bool deterministic;   // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
+               };
+
                struct Parameter
                {
                        union
@@ -404,14 +413,7 @@ namespace sw
                                {
                                        unsigned int index;   // For registers types
 
-                                       struct
-                                       {
-                                               ParameterType type : 8;
-                                               unsigned int index;
-                                               unsigned int swizzle : 8;
-                                               unsigned int scale;
-                                               bool deterministic;   // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
-                                       } rel;
+                                       Relative rel;
                                };
 
                                float value[4];       // For float constants