OSDN Git Service

Implement implicit casting support for constructors.
authorNicolas Capens <capn@google.com>
Thu, 12 Jun 2014 18:05:19 +0000 (14:05 -0400)
committerNicolas Capens <nicolascapens@google.com>
Sun, 15 Jun 2014 23:37:44 +0000 (23:37 +0000)
BUG=15415045

Change-Id: Ib6ec56f545ff37b5711bdf22bca1b33429521937
Reviewed-on: https://swiftshader-review.googlesource.com/1111
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/GLES2/compiler/OutputASM.cpp
src/GLES2/compiler/OutputASM.h

index 90e634d..a34a0ef 100644 (file)
@@ -707,8 +707,8 @@ namespace sh
                case EOpFunctionCall:\r
                        if(visit == PostVisit)\r
                        {\r
-                if(node->isUserDefined())\r
-                {\r
+                               if(node->isUserDefined())\r
+                               {\r
                                        const TString &name = node->getName();\r
                                        const Function &function = findFunction(name);\r
                                        TIntermSequence &arguments = *function.arg;\r
@@ -716,7 +716,7 @@ namespace sh
                                        for(int i = 0; i < argumentCount; i++)\r
                                        {\r
                                                TIntermTyped *in = arguments[i]->getAsTyped();\r
-                                                               \r
+\r
                                                if(in->getQualifier() == EvqIn ||\r
                                                   in->getQualifier() == EvqInOut ||\r
                                                   in->getQualifier() == EvqConstReadOnly)\r
@@ -769,10 +769,10 @@ namespace sh
                                                else UNREACHABLE();\r
                                        }\r
                                        else if(name == "texture2DProj")\r
-                    {\r
+                                       {\r
                                                TIntermTyped *t = arg[1]->getAsTyped();\r
 \r
-                        if(argumentCount == 2)\r
+                                               if(argumentCount == 2)\r
                                                {\r
                                                        Instruction *tex = emit(sw::Shader::OPCODE_TEX, result, arg[1], arg[0]);\r
                                                        tex->project = true;\r
@@ -808,19 +808,19 @@ namespace sh
                                                        tex->bias = true;\r
                                                }\r
                                                else UNREACHABLE();\r
-                    }\r
-                    else if(name == "texture2DLod" || name == "textureCubeLod")\r
-                    {\r
+                                       }\r
+                                       else if(name == "texture2DLod" || name == "textureCubeLod")\r
+                                       {\r
                                                Temporary uvwb(this);\r
                                                emit(sw::Shader::OPCODE_MOV, &uvwb, arg[1]);\r
                                                Instruction *lod = emit(sw::Shader::OPCODE_MOV, &uvwb, arg[2]);\r
                                                lod->dst.mask = 0x8;\r
 \r
                                                emit(sw::Shader::OPCODE_TEXLDL, result, &uvwb, arg[0]);\r
-                    }\r
-                    else if(name == "texture2DProjLod")\r
-                    {\r
-                        TIntermTyped *t = arg[1]->getAsTyped();\r
+                                       }\r
+                                       else if(name == "texture2DProjLod")\r
+                                       {\r
+                                               TIntermTyped *t = arg[1]->getAsTyped();\r
                                                Temporary proj(this);\r
 \r
                                                if(t->getNominalSize() == 3)\r
@@ -841,12 +841,13 @@ namespace sh
                                                lod->dst.mask = 0x8;\r
 \r
                                                emit(sw::Shader::OPCODE_TEXLDL, result, &proj, arg[0]);\r
-                    }\r
+                                       }\r
                                        else UNREACHABLE();\r
                                }\r
                        }\r
                        break;\r
-               case EOpParameters: break;\r
+               case EOpParameters:\r
+                       break;\r
                case EOpConstructFloat:\r
                case EOpConstructVec2:\r
                case EOpConstructVec3:\r
@@ -864,12 +865,12 @@ namespace sh
                                int component = 0;\r
 \r
                                for(int i = 0; i < argumentCount; i++)\r
-                {\r
-                    TIntermTyped *argi = arg[i]->getAsTyped();\r
+                               {\r
+                                       TIntermTyped *argi = arg[i]->getAsTyped();\r
                                        int size = argi->getNominalSize();\r
                                        ASSERT(!argi->isMatrix());\r
 \r
-                                       Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, argi);\r
+                                       Instruction *mov = emitCast(result, argi);\r
                                        mov->dst.mask = (0xF << component) & 0xF;\r
                                        mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);\r
 \r
@@ -893,13 +894,13 @@ namespace sh
                                                {\r
                                                        // Initialize to identity matrix\r
                                                        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));\r
-                                                       Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, &col);\r
+                                                       Instruction *mov = emitCast(result, &col);\r
                                                        mov->dst.index += i;\r
                                                }\r
 \r
                                                if(i < dim2(arg0))\r
                                                {\r
-                                                       Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, arg0);\r
+                                                       Instruction *mov = emitCast(result, arg0);\r
                                                        mov->dst.index += i;\r
                                                        mov->dst.mask = 0xF >> (4 - dim2(arg0));\r
                                                        argument(mov->src[0], arg0, i);\r
@@ -919,11 +920,11 @@ namespace sh
 \r
                                                while(element < size)\r
                                                {\r
-                                                       Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, argi);\r
+                                                       Instruction *mov = emitCast(result, argi);\r
                                                        mov->dst.index += column;\r
                                                        mov->dst.mask = (0xF << row) & 0xF;\r
                                                        mov->src[0].swizzle = (readSwizzle(argi, size) << (row * 2)) + 0x55 * element;\r
-                                       \r
+\r
                                                        int end = row + size - element;\r
                                                        column = end >= dim ? column + 1 : column;\r
                                                        element = element + dim - row;\r
@@ -987,7 +988,7 @@ namespace sh
                                ASSERT(dim2(arg[0]) == dim2(arg[1]));\r
 \r
                                for(int i = 0; i < dim2(arg[0]); i++)\r
-                {\r
+                               {\r
                                        Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, arg[0], arg[1]);\r
                                        mul->dst.index += i;\r
                                        argument(mul->src[0], arg[0], i);\r
@@ -1208,8 +1209,8 @@ namespace sh
 \r
                switch(node->getFlowOp())\r
                {\r
-               case EOpKill:      if(visit == PostVisit) emit(sw::Shader::OPCODE_DISCARD); break;\r
-               case EOpBreak:     if(visit == PostVisit) emit(sw::Shader::OPCODE_BREAK); break;\r
+               case EOpKill:      if(visit == PostVisit) emit(sw::Shader::OPCODE_DISCARD);  break;\r
+               case EOpBreak:     if(visit == PostVisit) emit(sw::Shader::OPCODE_BREAK);    break;\r
                case EOpContinue:  if(visit == PostVisit) emit(sw::Shader::OPCODE_CONTINUE); break;\r
                case EOpReturn:\r
                        if(visit == PostVisit)\r
@@ -1256,6 +1257,25 @@ namespace sh
                return instruction;\r
        }\r
 \r
+       Instruction *OutputASM::emitCast(TIntermTyped *dst, TIntermTyped *src)\r
+       {\r
+               // Integers are implemented as float\r
+               if((dst->getBasicType() == EbtFloat || dst->getBasicType() == EbtInt) && src->getBasicType() == EbtBool)\r
+               {\r
+                       return emit(sw::Shader::OPCODE_B2F, dst, src);\r
+               }\r
+               if(dst->getBasicType() == EbtBool && (src->getBasicType() == EbtFloat || src->getBasicType() == EbtInt))\r
+               {\r
+                       return emit(sw::Shader::OPCODE_F2B, dst, src);\r
+               }\r
+               if(dst->getBasicType() == EbtInt && src->getBasicType() == EbtFloat)\r
+               {\r
+                       return emit(sw::Shader::OPCODE_TRUNC, dst, src);\r
+               }\r
+\r
+               return emit(sw::Shader::OPCODE_MOV, dst, src);\r
+       }\r
+\r
        void OutputASM::emitBinary(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2)\r
        {\r
                for(int index = 0; index < dst->elementRegisterCount(); index++)\r
@@ -2281,10 +2301,10 @@ namespace sh
                {\r
                        return GL_SAMPLER_CUBE;\r
                }\r
-        else if(type.getBasicType() == EbtSamplerExternalOES)\r
-        {\r
-            return GL_SAMPLER_EXTERNAL_OES;\r
-        }\r
+               else if(type.getBasicType() == EbtSamplerExternalOES)\r
+               {\r
+                       return GL_SAMPLER_EXTERNAL_OES;\r
+               }\r
                else UNREACHABLE();\r
 \r
                return GL_NONE;\r
@@ -2382,7 +2402,7 @@ namespace sh
                if(index && node->getCondition())\r
                {\r
                        TIntermBinary *test = node->getCondition()->getAsBinaryNode();\r
-        \r
+\r
                        if(test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())\r
                        {\r
                                TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();\r
@@ -2403,7 +2423,7 @@ namespace sh
                {\r
                        TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();\r
                        TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();\r
-        \r
+\r
                        if(binaryTerminal)\r
                        {\r
                                TOperator op = binaryTerminal->getOp();\r
index 7130c18..f47f4ba 100644 (file)
@@ -107,6 +107,7 @@ namespace sh
                virtual bool visitBranch(Visit visit, TIntermBranch*);\r
 \r
                Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, int index = 0);\r
+               Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);\r
                void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);\r
                void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);\r
                void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);\r