Commit a0b5783f by Nicolas Capens Committed by Nicolas Capens

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/13551Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 89a218b4
...@@ -1233,6 +1233,7 @@ namespace glsl ...@@ -1233,6 +1233,7 @@ namespace glsl
else else
{ {
const TextureFunction textureFunction(node->getName()); const TextureFunction textureFunction(node->getName());
TIntermTyped *s = arg[0]->getAsTyped();
TIntermTyped *t = arg[1]->getAsTyped(); TIntermTyped *t = arg[1]->getAsTyped();
Temporary coord(this); Temporary coord(this);
...@@ -1245,73 +1246,88 @@ namespace glsl ...@@ -1245,73 +1246,88 @@ namespace glsl
Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord); Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
mul->dst.mask = 0x7; 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 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) switch(textureFunction.method)
{ {
case TextureFunction::IMPLICIT: case TextureFunction::IMPLICIT:
if(!textureFunction.offset)
{ {
TIntermNode* offset = textureFunction.offset ? arg[2] : 0; if(argumentCount == 2)
if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))
{ {
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX, emit(sw::Shader::OPCODE_TEX, result, &coord, s);
result, &coord, arg[0], offset);
} }
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]); emit(sw::Shader::OPCODE_TEXBIAS, result, &coord, s, arg[2]);
bias->dst.mask = 0x8; }
else UNREACHABLE(argumentCount);
Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX, }
result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction else // Offset
tex->bias = true; {
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); else UNREACHABLE(argumentCount);
} }
break; break;
case TextureFunction::LOD: case TextureFunction::LOD:
if(!textureFunction.offset && argumentCount == 3)
{ {
Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]); emit(sw::Shader::OPCODE_TEXLOD, result, &coord, s, 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);
} }
else if(argumentCount == 4) // Offset
{
emit(sw::Shader::OPCODE_TEXLODOFFSET, result, &coord, s, arg[3], arg[2]);
}
else UNREACHABLE(argumentCount);
break; break;
case TextureFunction::FETCH: case TextureFunction::FETCH:
if(!textureFunction.offset && argumentCount == 3)
{ {
if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) emit(sw::Shader::OPCODE_TEXELFETCH, result, &coord, s, arg[2]);
{
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);
} }
else if(argumentCount == 4) // Offset
{
emit(sw::Shader::OPCODE_TEXELFETCHOFFSET, result, &coord, s, arg[3], arg[2]);
}
else UNREACHABLE(argumentCount);
break; break;
case TextureFunction::GRAD: case TextureFunction::GRAD:
if(!textureFunction.offset && argumentCount == 4)
{ {
if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5)) emit(sw::Shader::OPCODE_TEXGRAD, result, &coord, s, arg[2], arg[3]);
{ }
TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr; else if(argumentCount == 5) // Offset
{
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD, emit(sw::Shader::OPCODE_TEXGRADOFFSET, result, &coord, s, arg[2], arg[3], arg[4]);
result, &coord, arg[0], arg[2], arg[3], offset);
}
else UNREACHABLE(argumentCount);
} }
else UNREACHABLE(argumentCount);
break; break;
case TextureFunction::SIZE: case TextureFunction::SIZE:
emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], arg[0]); emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], s);
break; break;
default: default:
UNREACHABLE(textureFunction.method); UNREACHABLE(textureFunction.method);
......
...@@ -1240,7 +1240,7 @@ namespace sw ...@@ -1240,7 +1240,7 @@ namespace sw
if(!project) if(!project)
{ {
c = SamplerCore(constants, state.sampler[stage]).sampleTexture(texture, u, v, w, q, dsx, dsy); c = SamplerCore(constants, state.sampler[stage]).sampleTexture(texture, u, v, w, q, q, dsx, dsy);
} }
else else
{ {
...@@ -1250,7 +1250,7 @@ namespace sw ...@@ -1250,7 +1250,7 @@ namespace sw
Float4 v_q = v * rq; Float4 v_q = v * rq;
Float4 w_q = w * rq; Float4 w_q = w * rq;
c = SamplerCore(constants, state.sampler[stage]).sampleTexture(texture, u_q, v_q, w_q, q, dsx, dsy); c = SamplerCore(constants, state.sampler[stage]).sampleTexture(texture, u_q, v_q, w_q, q, q, dsx, dsy);
} }
#if PERF_PROFILE #if PERF_PROFILE
......
...@@ -281,17 +281,20 @@ namespace sw ...@@ -281,17 +281,20 @@ namespace sw
case Shader::OPCODE_M3X4: M3X4(d, s0, src1); break; case Shader::OPCODE_M3X4: M3X4(d, s0, src1); break;
case Shader::OPCODE_M3X3: M3X3(d, s0, src1); break; case Shader::OPCODE_M3X3: M3X3(d, s0, src1); break;
case Shader::OPCODE_M3X2: M3X2(d, s0, src1); break; case Shader::OPCODE_M3X2: M3X2(d, s0, src1); break;
case Shader::OPCODE_TEX: TEXLD(d, s0, src1, project, bias); break; case Shader::OPCODE_TEX: TEX(d, s0, src1, project, bias); break;
case Shader::OPCODE_TEXLDD: TEXLDD(d, s0, src1, s2, s3); break; case Shader::OPCODE_TEXLDD: TEXGRAD(d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1); break; case Shader::OPCODE_TEXLDL: TEXLOD(d, s0, src1, s0.w); break;
case Shader::OPCODE_TEXLOD: TEXLOD(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break; case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break;
case Shader::OPCODE_TEXKILL: TEXKILL(cMask, d, dst.mask); break; case Shader::OPCODE_TEXKILL: TEXKILL(cMask, d, dst.mask); break;
case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2, bias); break; case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2); break;
case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2, bias); break; case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1); break; case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2); break; case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break; case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRADOFFSET: TEXGRAD(d, s0, src1, s2, s3, s4); break; case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_TEXBIAS: TEXBIAS(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEXOFFSETBIAS: TEXOFFSETBIAS(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_DISCARD: DISCARD(cMask, instruction); break; case Shader::OPCODE_DISCARD: DISCARD(cMask, instruction); break;
case Shader::OPCODE_DFDX: DFDX(d, s0); break; case Shader::OPCODE_DFDX: DFDX(d, s0); break;
case Shader::OPCODE_DFDY: DFDY(d, s0); break; case Shader::OPCODE_DFDY: DFDY(d, s0); break;
...@@ -678,13 +681,13 @@ namespace sw ...@@ -678,13 +681,13 @@ namespace sw
} }
} }
Vector4f PixelProgram::sampleTexture(const Src &sampler, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function) Vector4f PixelProgram::sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{ {
Vector4f tmp; Vector4f tmp;
if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID) if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID)
{ {
tmp = sampleTexture(sampler.index, uvwq, dsx, dsy, offset, function); tmp = sampleTexture(sampler.index, uvwq, bias, dsx, dsy, offset, function);
} }
else else
{ {
...@@ -696,7 +699,7 @@ namespace sw ...@@ -696,7 +699,7 @@ namespace sw
{ {
If(index == i) If(index == i)
{ {
tmp = sampleTexture(i, uvwq, dsx, dsy, offset, function); tmp = sampleTexture(i, uvwq, bias, dsx, dsy, offset, function);
// FIXME: When the sampler states are the same, we could use one sampler and just index the texture // FIXME: When the sampler states are the same, we could use one sampler and just index the texture
} }
} }
...@@ -712,14 +715,14 @@ namespace sw ...@@ -712,14 +715,14 @@ namespace sw
return c; return c;
} }
Vector4f PixelProgram::sampleTexture(int samplerIndex, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function) Vector4f PixelProgram::sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{ {
#if PERF_PROFILE #if PERF_PROFILE
Long texTime = Ticks(); Long texTime = Ticks();
#endif #endif
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture); Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture);
Vector4f c = SamplerCore(constants, state.sampler[samplerIndex]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, function); Vector4f c = SamplerCore(constants, state.sampler[samplerIndex]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, bias, dsx, dsy, offset, function);
#if PERF_PROFILE #if PERF_PROFILE
cycles[PERF_TEX] += Ticks() - texTime; cycles[PERF_TEX] += Ticks() - texTime;
...@@ -1113,7 +1116,7 @@ namespace sw ...@@ -1113,7 +1116,7 @@ namespace sw
dst.w = dot4(src0, row3); dst.w = dot4(src0, row3);
} }
void PixelProgram::TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias) void PixelProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias)
{ {
if(project) if(project)
{ {
...@@ -1123,52 +1126,57 @@ namespace sw ...@@ -1123,52 +1126,57 @@ namespace sw
proj.y = src0.y * rw; proj.y = src0.y * rw;
proj.z = src0.z * rw; proj.z = src0.z * rw;
dst = sampleTexture(src1, proj, src0, src0, src0, Implicit); dst = sampleTexture(src1, proj, src0.x, (src0), (src0), (src0), Implicit);
} }
else else
{ {
dst = sampleTexture(src1, src0, src0, src0, src0, bias ? Bias : Implicit); dst = sampleTexture(src1, src0, src0.x, (src0), (src0), (src0), bias ? Bias : Implicit);
} }
} }
void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias) void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset)
{ {
dst = sampleTexture(src1, src0, src0, src0, src2, {bias ? Bias : Implicit, Offset}); dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Implicit, Offset});
} }
void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool bias) void PixelProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, src0, src0, offset, {Lod, Offset}); dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
} }
void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1) void PixelProgram::TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias)
{ {
dst = sampleTexture(src1, src0, src0, src0, src0, Fetch); dst = sampleTexture(src1, src0, bias, (src0), (src0), (src0), Bias);
}
void PixelProgram::TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias)
{
dst = sampleTexture(src1, src0, bias, (src0), (src0), offset, {Bias, Offset});
} }
void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset) void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, src0, src0, offset, {Fetch, Offset}); dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
} }
void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3) void PixelProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, src2, src3, src0, Grad); dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
} }
void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset) void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
{ {
dst = sampleTexture(src1, src0, src2, src3, offset, {Grad, Offset}); dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, (src0), Grad);
} }
void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3) void PixelProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
{ {
dst = sampleTexture(src1, src0, src2, src3, src0, Grad); dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
} }
void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1) void PixelProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, src0, src0, src0, Lod); dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
} }
void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1) void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
......
...@@ -82,8 +82,8 @@ namespace sw ...@@ -82,8 +82,8 @@ namespace sw
Int4 enableContinue; Int4 enableContinue;
Int4 enableLeave; Int4 enableLeave;
Vector4f sampleTexture(const Src &sampler, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
Vector4f sampleTexture(int samplerIndex, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
// Raster operations // Raster operations
void clampColor(Vector4f oC[RENDERTARGETS]); void clampColor(Vector4f oC[RENDERTARGETS]);
...@@ -106,17 +106,18 @@ namespace sw ...@@ -106,17 +106,18 @@ namespace sw
void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1); void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1); void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1); void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias); void TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3); void TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod);
void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1); void TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1); void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask); void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias); void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset);
void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias); void TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias);
void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&); void TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod);
void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2); void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src &, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3); void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &offset, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4); void TEXGRAD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &dsx, Vector4f &dsy);
void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void DISCARD(Int cMask[4], const Shader::Instruction *instruction); void DISCARD(Int cMask[4], const Shader::Instruction *instruction);
void DFDX(Vector4f &dst, Vector4f &src); void DFDX(Vector4f &dst, Vector4f &src);
void DFDY(Vector4f &dst, Vector4f &src); void DFDY(Vector4f &dst, Vector4f &src);
......
...@@ -314,8 +314,11 @@ namespace sw ...@@ -314,8 +314,11 @@ namespace sw
case Shader::OPCODE_TEX: case Shader::OPCODE_TEX:
case Shader::OPCODE_TEXLDD: case Shader::OPCODE_TEXLDD:
case Shader::OPCODE_TEXLDL: case Shader::OPCODE_TEXLDL:
case Shader::OPCODE_TEXLOD:
case Shader::OPCODE_TEXBIAS:
case Shader::OPCODE_TEXOFFSET: case Shader::OPCODE_TEXOFFSET:
case Shader::OPCODE_TEXLDLOFFSET: case Shader::OPCODE_TEXOFFSETBIAS:
case Shader::OPCODE_TEXLODOFFSET:
case Shader::OPCODE_TEXELFETCH: case Shader::OPCODE_TEXELFETCH:
case Shader::OPCODE_TEXELFETCHOFFSET: case Shader::OPCODE_TEXELFETCHOFFSET:
case Shader::OPCODE_TEXGRAD: case Shader::OPCODE_TEXGRAD:
......
...@@ -22,17 +22,18 @@ namespace sw ...@@ -22,17 +22,18 @@ namespace sw
{ {
enum SamplerMethod enum SamplerMethod
{ {
Implicit, Implicit, // Compute gradients (pixel shader only).
Bias, Bias, // Compute gradients and add provided bias.
Lod, Lod, // Use provided LOD.
Grad, Grad, // Use provided gradients.
Fetch Fetch, // Use provided integer coordinates.
Base // Sample base level.
}; };
enum SamplerOption enum SamplerOption
{ {
None, None,
Offset Offset // Offset sample location by provided integer coordinates.
}; };
struct SamplerFunction struct SamplerFunction
...@@ -49,12 +50,12 @@ namespace sw ...@@ -49,12 +50,12 @@ namespace sw
public: public:
SamplerCore(Pointer<Byte> &constants, const Sampler::State &state); SamplerCore(Pointer<Byte> &constants, const Sampler::State &state);
Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy); Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy);
Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
static Vector4f textureSize(Pointer<Byte> &mipmap, Float4 &lod); static Vector4f textureSize(Pointer<Byte> &mipmap, Float4 &lod);
private: private:
Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12); Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12);
void border(Short4 &mask, Float4 &coordinates); void border(Short4 &mask, Float4 &coordinates);
void border(Int4 &mask, Float4 &coordinates); void border(Int4 &mask, Float4 &coordinates);
...@@ -64,10 +65,10 @@ namespace sw ...@@ -64,10 +65,10 @@ namespace sw
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function); Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function); Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function); Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function); Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(Float lod); Float log2sqrt(Float lod);
void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function); void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
......
...@@ -118,7 +118,6 @@ namespace sw ...@@ -118,7 +118,6 @@ namespace sw
OPCODE_CMP, // D3DSIO_SETP OPCODE_CMP, // D3DSIO_SETP
OPCODE_TEXLDL, OPCODE_TEXLDL,
OPCODE_BREAKP, OPCODE_BREAKP,
OPCODE_TEXSIZE,
OPCODE_PHASE = 0xFFFD, OPCODE_PHASE = 0xFFFD,
OPCODE_COMMENT = 0xFFFE, OPCODE_COMMENT = 0xFFFE,
...@@ -207,11 +206,15 @@ namespace sw ...@@ -207,11 +206,15 @@ namespace sw
OPCODE_ISNAN, OPCODE_ISNAN,
OPCODE_ISINF, OPCODE_ISINF,
OPCODE_TEXOFFSET, OPCODE_TEXOFFSET,
OPCODE_TEXLDLOFFSET, OPCODE_TEXLODOFFSET,
OPCODE_TEXELFETCH, OPCODE_TEXELFETCH,
OPCODE_TEXELFETCHOFFSET, OPCODE_TEXELFETCHOFFSET,
OPCODE_TEXGRAD, OPCODE_TEXGRAD,
OPCODE_TEXGRADOFFSET, OPCODE_TEXGRADOFFSET,
OPCODE_TEXBIAS,
OPCODE_TEXLOD,
OPCODE_TEXOFFSETBIAS,
OPCODE_TEXSIZE,
OPCODE_FLOATBITSTOINT, OPCODE_FLOATBITSTOINT,
OPCODE_FLOATBITSTOUINT, OPCODE_FLOATBITSTOUINT,
OPCODE_INTBITSTOFLOAT, OPCODE_INTBITSTOFLOAT,
......
...@@ -326,14 +326,15 @@ namespace sw ...@@ -326,14 +326,15 @@ namespace sw
case Shader::OPCODE_AND: bitwise_and(d, s0, s1); break; case Shader::OPCODE_AND: bitwise_and(d, s0, s1); break;
case Shader::OPCODE_EQ: equal(d, s0, s1); break; case Shader::OPCODE_EQ: equal(d, s0, s1); break;
case Shader::OPCODE_NE: notEqual(d, s0, s1); break; case Shader::OPCODE_NE: notEqual(d, s0, s1); break;
case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1); break; case Shader::OPCODE_TEXLDL: TEXLOD(d, s0, src1, s0.w); break;
case Shader::OPCODE_TEXLOD: TEXLOD(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEX: TEX(d, s0, src1); break; case Shader::OPCODE_TEX: TEX(d, s0, src1); break;
case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2); break; case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2); break;
case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2); break; case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1); break; case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2); break; case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break; case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRADOFFSET: TEXGRAD(d, s0, src1, s2, s3, s4); break; case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break; case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break;
case Shader::OPCODE_END: break; case Shader::OPCODE_END: break;
default: default:
...@@ -1556,46 +1557,44 @@ namespace sw ...@@ -1556,46 +1557,44 @@ namespace sw
// FIXME: Use enableLeave in other control-flow constructs // FIXME: Use enableLeave in other control-flow constructs
} }
void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1) void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1)
{ {
dst = sampleTexture(src1, src0, a0, a0, src0, Lod); dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), (src0), Base);
} }
void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1) void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
{ {
src0.w = Float(0.0f); dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Base, Offset});
dst = sampleTexture(src1, src0, a0, a0, src0, Lod);
} }
void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2) void VertexProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
{ {
src0.w = Float(0.0f); dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
dst = sampleTexture(src1, src0, a0, a0, src2, {Lod, Offset});
} }
void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset) void VertexProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, a0, a0, offset, {Lod, Offset}); dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
} }
void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1) void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, src0, src0, src0, Fetch); dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
} }
void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset) void VertexProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
{ {
dst = sampleTexture(src1, src0, src0, src0, offset, {Fetch, Offset}); dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
} }
void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3) void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
{ {
dst = sampleTexture(src1, src0, src2, src3, src0, Grad); dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, src0, Grad);
} }
void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset) void VertexProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
{ {
dst = sampleTexture(src1, src0, src2, src3, offset, {Grad, Offset}); dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
} }
void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1) void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
...@@ -1604,13 +1603,13 @@ namespace sw ...@@ -1604,13 +1603,13 @@ namespace sw
dst = SamplerCore::textureSize(texture, lod); dst = SamplerCore::textureSize(texture, lod);
} }
Vector4f VertexProgram::sampleTexture(const Src &s, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function) Vector4f VertexProgram::sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{ {
Vector4f tmp; Vector4f tmp;
if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID) if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID)
{ {
tmp = sampleTexture(s.index, uvwq, dsx, dsy, offset, function); tmp = sampleTexture(s.index, uvwq, lod, dsx, dsy, offset, function);
} }
else else
{ {
...@@ -1622,7 +1621,7 @@ namespace sw ...@@ -1622,7 +1621,7 @@ namespace sw
{ {
If(index == i) If(index == i)
{ {
tmp = sampleTexture(i, uvwq, dsx, dsy, offset, function); tmp = sampleTexture(i, uvwq, lod, dsx, dsy, offset, function);
// FIXME: When the sampler states are the same, we could use one sampler and just index the texture // FIXME: When the sampler states are the same, we could use one sampler and just index the texture
} }
} }
...@@ -1638,9 +1637,9 @@ namespace sw ...@@ -1638,9 +1637,9 @@ namespace sw
return c; return c;
} }
Vector4f VertexProgram::sampleTexture(int sampler, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function) Vector4f VertexProgram::sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{ {
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + sampler * sizeof(Texture); Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + sampler * sizeof(Texture);
return SamplerCore(constants, state.sampler[sampler]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, function); return SamplerCore(constants, state.sampler[sampler]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, lod, dsx, dsy, offset, function);
} }
} }
...@@ -107,18 +107,18 @@ namespace sw ...@@ -107,18 +107,18 @@ namespace sw
void SWITCH(); void SWITCH();
void RET(); void RET();
void LEAVE(); void LEAVE();
void TEXLDL(Vector4f &dst, Vector4f &src, const Src&);
void TEX(Vector4f &dst, Vector4f &src, const Src&); void TEX(Vector4f &dst, Vector4f &src, const Src&);
void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2); void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset);
void TEXLDL(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2); void TEXLOD(Vector4f &dst, Vector4f &src, const Src&, Float4 &lod);
void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&); void TEXLODOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2); void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3); void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4); void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy);
void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src&); void TEXSIZE(Vector4f &dst, Float4 &lod, const Src&);
Vector4f sampleTexture(const Src &s, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
Vector4f sampleTexture(int sampler, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
int ifDepth; int ifDepth;
int loopRepDepth; int loopRepDepth;
......
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