Pass the sampling lod/bias as a separate parameter.
This is necessary for cube or 2D array shadow texture sampling
functions which need the fourth texture coordinate component for
depth comparison while also taking a lod or bias parameter.
Change-Id: I1e1399f134e22cecaff97a224df2c13c57ba3a40
Reviewed-on: https://swiftshader-review.googlesource.com/13551
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 6e2e6e8..889f44e 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1233,6 +1233,7 @@
else
{
const TextureFunction textureFunction(node->getName());
+ TIntermTyped *s = arg[0]->getAsTyped();
TIntermTyped *t = arg[1]->getAsTyped();
Temporary coord(this);
@@ -1245,73 +1246,88 @@
Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
mul->dst.mask = 0x7;
+
+ if(IsShadowSampler(s->getBasicType()))
+ {
+ ASSERT(s->getBasicType() == EbtSampler2DShadow);
+ Instruction *mov = emit(sw::Shader::OPCODE_MOV, &coord, &coord);
+ mov->src[0].swizzle = 0xA4;
+ }
}
else
{
- emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);
+ Instruction *mov = emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);
+
+ if(IsShadowSampler(s->getBasicType()) && t->getNominalSize() == 3)
+ {
+ ASSERT(s->getBasicType() == EbtSampler2DShadow);
+ mov->src[0].swizzle = 0xA4;
+ }
}
switch(textureFunction.method)
{
case TextureFunction::IMPLICIT:
+ if(!textureFunction.offset)
{
- TIntermNode* offset = textureFunction.offset ? arg[2] : 0;
-
- if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))
+ if(argumentCount == 2)
{
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
- result, &coord, arg[0], offset);
+ emit(sw::Shader::OPCODE_TEX, result, &coord, s);
}
- else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) // bias
+ else if(argumentCount == 3) // Bias
{
- Instruction *bias = emit(sw::Shader::OPCODE_MOV, &coord, arg[textureFunction.offset ? 3 : 2]);
- bias->dst.mask = 0x8;
-
- Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
- result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction
- tex->bias = true;
+ emit(sw::Shader::OPCODE_TEXBIAS, result, &coord, s, arg[2]);
+ }
+ else UNREACHABLE(argumentCount);
+ }
+ else // Offset
+ {
+ if(argumentCount == 3)
+ {
+ emit(sw::Shader::OPCODE_TEXOFFSET, result, &coord, s, arg[2]);
+ }
+ else if(argumentCount == 4) // Bias
+ {
+ emit(sw::Shader::OPCODE_TEXOFFSETBIAS, result, &coord, s, arg[2], arg[3]);
}
else UNREACHABLE(argumentCount);
}
break;
case TextureFunction::LOD:
+ if(!textureFunction.offset && argumentCount == 3)
{
- Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);
- lod->dst.mask = 0x8;
-
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,
- result, &coord, arg[0], textureFunction.offset ? arg[3] : nullptr);
+ emit(sw::Shader::OPCODE_TEXLOD, result, &coord, s, arg[2]);
}
+ else if(argumentCount == 4) // Offset
+ {
+ emit(sw::Shader::OPCODE_TEXLODOFFSET, result, &coord, s, arg[3], arg[2]);
+ }
+ else UNREACHABLE(argumentCount);
break;
case TextureFunction::FETCH:
+ if(!textureFunction.offset && argumentCount == 3)
{
- if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))
- {
- Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);
- lod->dst.mask = 0x8;
-
- TIntermNode *offset = textureFunction.offset ? arg[3] : nullptr;
-
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,
- result, &coord, arg[0], offset);
- }
- else UNREACHABLE(argumentCount);
+ emit(sw::Shader::OPCODE_TEXELFETCH, result, &coord, s, arg[2]);
}
+ else if(argumentCount == 4) // Offset
+ {
+ emit(sw::Shader::OPCODE_TEXELFETCHOFFSET, result, &coord, s, arg[3], arg[2]);
+ }
+ else UNREACHABLE(argumentCount);
break;
case TextureFunction::GRAD:
+ if(!textureFunction.offset && argumentCount == 4)
{
- if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))
- {
- TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr;
-
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,
- result, &coord, arg[0], arg[2], arg[3], offset);
- }
- else UNREACHABLE(argumentCount);
+ emit(sw::Shader::OPCODE_TEXGRAD, result, &coord, s, arg[2], arg[3]);
}
+ else if(argumentCount == 5) // Offset
+ {
+ emit(sw::Shader::OPCODE_TEXGRADOFFSET, result, &coord, s, arg[2], arg[3], arg[4]);
+ }
+ else UNREACHABLE(argumentCount);
break;
case TextureFunction::SIZE:
- emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], arg[0]);
+ emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], s);
break;
default:
UNREACHABLE(textureFunction.method);