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
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
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