Commit 53463f75 by Nicolas Capens

Perform texture coordinate projection at shader assembly level.

Change-Id: Ia94eb950d8d3ec4562f9f2e57d8d7ba27a41d16c Reviewed-on: https://swiftshader-review.googlesource.com/5044Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent c2534f4b
...@@ -1223,63 +1223,42 @@ namespace glsl ...@@ -1223,63 +1223,42 @@ namespace glsl
else else
{ {
const TextureFunction textureFunction(node->getName()); const TextureFunction textureFunction(node->getName());
TIntermTyped *t = arg[1]->getAsTyped();
Temporary coord(this);
if(textureFunction.proj)
{
Instruction *rcp = emit(sw::Shader::OPCODE_RCPX, &coord, arg[1]);
rcp->src[0].swizzle = 0x55 * (t->getNominalSize() - 1);
rcp->dst.mask = 0x7;
Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
mul->dst.mask = 0x7;
}
else
{
emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);
}
switch(textureFunction.method) switch(textureFunction.method)
{ {
case TextureFunction::IMPLICIT: case TextureFunction::IMPLICIT:
{ {
TIntermTyped *t = arg[1]->getAsTyped();
TIntermNode* offset = textureFunction.offset ? arg[2] : 0; TIntermNode* offset = textureFunction.offset ? arg[2] : 0;
if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3)) if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))
{ {
Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX, Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
result, arg[1], arg[0], offset); result, &coord, arg[0], offset);
if(textureFunction.proj)
{
tex->project = true;
switch(t->getNominalSize())
{
case 2: tex->src[0].swizzle = 0x54; break; // xyyy
case 3: tex->src[0].swizzle = 0xA4; break; // xyzz
case 4: break; // xyzw
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
} }
else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) // bias else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) // bias
{ {
Temporary proj(this); Instruction *bias = emit(sw::Shader::OPCODE_MOV, &coord, arg[textureFunction.offset ? 3 : 2]);
if(textureFunction.proj)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->dst.mask = 0x3;
switch(t->getNominalSize())
{
case 2:
case 3:
case 4:
div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);
break;
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
else
{
emit(sw::Shader::OPCODE_MOV, &proj, arg[1]);
}
Instruction *bias = emit(sw::Shader::OPCODE_MOV, &proj, arg[textureFunction.offset ? 3 : 2]);
bias->dst.mask = 0x8; bias->dst.mask = 0x8;
Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX, Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
result, &proj, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction
tex->bias = true; tex->bias = true;
} }
else UNREACHABLE(argumentCount); else UNREACHABLE(argumentCount);
...@@ -1287,45 +1266,18 @@ namespace glsl ...@@ -1287,45 +1266,18 @@ namespace glsl
break; break;
case TextureFunction::LOD: case TextureFunction::LOD:
{ {
TIntermTyped *t = arg[1]->getAsTyped(); Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);
Temporary proj(this);
if(textureFunction.proj)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->dst.mask = 0x3;
switch(t->getNominalSize())
{
case 2:
case 3:
case 4:
div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);
break;
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
else
{
emit(sw::Shader::OPCODE_MOV, &proj, arg[1]);
}
Instruction *lod = emit(sw::Shader::OPCODE_MOV, &proj, arg[2]);
lod->dst.mask = 0x8; lod->dst.mask = 0x8;
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL, emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,
result, &proj, arg[0], textureFunction.offset ? arg[3] : 0); result, &coord, arg[0], textureFunction.offset ? arg[3] : nullptr);
} }
break; break;
case TextureFunction::FETCH: case TextureFunction::FETCH:
{ {
TIntermTyped *t = arg[1]->getAsTyped();
if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))
{ {
TIntermNode* offset = textureFunction.offset ? arg[3] : 0; TIntermNode *offset = textureFunction.offset ? arg[3] : nullptr;
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH, emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,
result, arg[1], arg[0], arg[2], offset); result, arg[1], arg[0], arg[2], offset);
...@@ -1335,38 +1287,12 @@ namespace glsl ...@@ -1335,38 +1287,12 @@ namespace glsl
break; break;
case TextureFunction::GRAD: case TextureFunction::GRAD:
{ {
TIntermTyped *t = arg[1]->getAsTyped();
if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5)) if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))
{ {
Temporary uvwb(this); TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr;
if(textureFunction.proj)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &uvwb, arg[1], arg[1]);
div->dst.mask = 0x3;
switch(t->getNominalSize())
{
case 2:
case 3:
case 4:
div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);
break;
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
else
{
emit(sw::Shader::OPCODE_MOV, &uvwb, arg[1]);
}
TIntermNode* offset = textureFunction.offset ? arg[4] : 0;
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD, emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,
result, &uvwb, arg[0], arg[2], arg[3], offset); result, &coord, arg[0], arg[2], arg[3], offset);
} }
else UNREACHABLE(argumentCount); else UNREACHABLE(argumentCount);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment