OSDN Git Service

Perform texture coordinate projection at shader assembly level.
authorNicolas Capens <capn@google.com>
Mon, 4 Apr 2016 21:04:58 +0000 (17:04 -0400)
committerNicolas Capens <capn@google.com>
Tue, 5 Apr 2016 18:37:05 +0000 (18:37 +0000)
Change-Id: Ia94eb950d8d3ec4562f9f2e57d8d7ba27a41d16c
Reviewed-on: https://swiftshader-review.googlesource.com/5044
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/compiler/OutputASM.cpp

index eec58d9..15bb374 100644 (file)
@@ -1223,63 +1223,42 @@ namespace glsl
                                else\r
                                {\r
                                        const TextureFunction textureFunction(node->getName());\r
+                                       TIntermTyped *t = arg[1]->getAsTyped();\r
+\r
+                                       Temporary coord(this);\r
+\r
+                                       if(textureFunction.proj)\r
+                                       {\r
+                                               Instruction *rcp = emit(sw::Shader::OPCODE_RCPX, &coord, arg[1]);\r
+                                               rcp->src[0].swizzle = 0x55 * (t->getNominalSize() - 1);\r
+                                               rcp->dst.mask = 0x7;\r
+\r
+                                               Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);\r
+                                               mul->dst.mask = 0x7;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);\r
+                                       }\r
+\r
                                        switch(textureFunction.method)\r
                                        {\r
                                        case TextureFunction::IMPLICIT:\r
                                                {\r
-                                                       TIntermTyped *t = arg[1]->getAsTyped();\r
-\r
                                                        TIntermNode* offset = textureFunction.offset ? arg[2] : 0;\r
 \r
                                                        if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))\r
                                                        {\r
                                                                Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,\r
-                                                                                       result, arg[1], arg[0], offset);\r
-                                                               if(textureFunction.proj)\r
-                                                               {\r
-                                                                       tex->project = true;\r
-\r
-                                                                       switch(t->getNominalSize())\r
-                                                                       {\r
-                                                                       case 2: tex->src[0].swizzle = 0x54; break; // xyyy\r
-                                                                       case 3: tex->src[0].swizzle = 0xA4; break; // xyzz\r
-                                                                       case 4: break; // xyzw\r
-                                                                       default:\r
-                                                                               UNREACHABLE(t->getNominalSize());\r
-                                                                               break;\r
-                                                                       }\r
-                                                               }\r
+                                                                                       result, &coord, arg[0], offset);\r
                                                        }\r
                                                        else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))   // bias\r
                                                        {\r
-                                                               Temporary proj(this);\r
-                                                               if(textureFunction.proj)\r
-                                                               {\r
-                                                                       Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);\r
-                                                                       div->dst.mask = 0x3;\r
-\r
-                                                                       switch(t->getNominalSize())\r
-                                                                       {\r
-                                                                       case 2:\r
-                                                                       case 3:\r
-                                                                       case 4:\r
-                                                                               div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);\r
-                                                                               break;\r
-                                                                       default:\r
-                                                                               UNREACHABLE(t->getNominalSize());\r
-                                                                               break;\r
-                                                                       }\r
-                                                               }\r
-                                                               else\r
-                                                               {\r
-                                                                       emit(sw::Shader::OPCODE_MOV, &proj, arg[1]);\r
-                                                               }\r
-\r
-                                                               Instruction *bias = emit(sw::Shader::OPCODE_MOV, &proj, arg[textureFunction.offset ? 3 : 2]);\r
+                                                               Instruction *bias = emit(sw::Shader::OPCODE_MOV, &coord, arg[textureFunction.offset ? 3 : 2]);\r
                                                                bias->dst.mask = 0x8;\r
 \r
                                                                Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,\r
-                                                                                       result, &proj, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction\r
+                                                                                       result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction\r
                                                                tex->bias = true;\r
                                                        }\r
                                                        else UNREACHABLE(argumentCount);\r
@@ -1287,45 +1266,18 @@ namespace glsl
                                                break;\r
                                        case TextureFunction::LOD:\r
                                                {\r
-                                                       TIntermTyped *t = arg[1]->getAsTyped();\r
-                                                       Temporary proj(this);\r
-\r
-                                                       if(textureFunction.proj)\r
-                                                       {\r
-                                                               Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);\r
-                                                               div->dst.mask = 0x3;\r
-\r
-                                                               switch(t->getNominalSize())\r
-                                                               {\r
-                                                               case 2:\r
-                                                               case 3:\r
-                                                               case 4:\r
-                                                                       div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);\r
-                                                                       break;\r
-                                                               default:\r
-                                                                       UNREACHABLE(t->getNominalSize());\r
-                                                                       break;\r
-                                                               }\r
-                                                       }\r
-                                                       else\r
-                                                       {\r
-                                                               emit(sw::Shader::OPCODE_MOV, &proj, arg[1]);\r
-                                                       }\r
-\r
-                                                       Instruction *lod = emit(sw::Shader::OPCODE_MOV, &proj, arg[2]);\r
+                                                       Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);\r
                                                        lod->dst.mask = 0x8;\r
 \r
                                                        emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,\r
-                                                            result, &proj, arg[0], textureFunction.offset ? arg[3] : 0);\r
+                                                            result, &coord, arg[0], textureFunction.offset ? arg[3] : nullptr);\r
                                                }\r
                                                break;\r
                                        case TextureFunction::FETCH:\r
                                                {\r
-                                                       TIntermTyped *t = arg[1]->getAsTyped();\r
-\r
                                                        if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))\r
                                                        {\r
-                                                               TIntermNode* offset = textureFunction.offset ? arg[3] : 0;\r
+                                                               TIntermNode *offset = textureFunction.offset ? arg[3] : nullptr;\r
 \r
                                                                emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,\r
                                                                     result, arg[1], arg[0], arg[2], offset);\r
@@ -1335,38 +1287,12 @@ namespace glsl
                                                break;\r
                                        case TextureFunction::GRAD:\r
                                                {\r
-                                                       TIntermTyped *t = arg[1]->getAsTyped();\r
-\r
                                                        if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))\r
                                                        {\r
-                                                               Temporary uvwb(this);\r
-\r
-                                                               if(textureFunction.proj)\r
-                                                               {\r
-                                                                       Instruction *div = emit(sw::Shader::OPCODE_DIV, &uvwb, arg[1], arg[1]);\r
-                                                                       div->dst.mask = 0x3;\r
-\r
-                                                                       switch(t->getNominalSize())\r
-                                                                       {\r
-                                                                       case 2:\r
-                                                                       case 3:\r
-                                                                       case 4:\r
-                                                                               div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);\r
-                                                                               break;\r
-                                                                       default:\r
-                                                                               UNREACHABLE(t->getNominalSize());\r
-                                                                               break;\r
-                                                                       }\r
-                                                               }\r
-                                                               else\r
-                                                               {\r
-                                                                       emit(sw::Shader::OPCODE_MOV, &uvwb, arg[1]);\r
-                                                               }\r
-\r
-                                                               TIntermNode* offset = textureFunction.offset ? arg[4] : 0;\r
+                                                               TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr;\r
 \r
                                                                emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,\r
-                                                                    result, &uvwb, arg[0], arg[2], arg[3], offset);\r
+                                                                    result, &coord, arg[0], arg[2], arg[3], offset);\r
                                                        }\r
                                                        else UNREACHABLE(argumentCount);\r
                                                }\r