Commit 77f0b68a by Nicolas Capens Committed by Nicolas Capens

Fix cube texture gradient calculation.

Cube texture sampling functions which take explicit gradients require the gradients to divided by the same factor used to project the texture coordinates onto the cube. Previously we assumed they were already in the projected coordinate space. Change-Id: I2825df17bee74b551b8d7491c050b7766653a65c Reviewed-on: https://swiftshader-review.googlesource.com/13552Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent a0b5783f
...@@ -74,11 +74,6 @@ namespace sw ...@@ -74,11 +74,6 @@ namespace sw
} }
#endif #endif
Float4 uuuu = u;
Float4 vvvv = v;
Float4 wwww = w;
Float4 qqqq = q;
if(state.textureType == TEXTURE_NULL) if(state.textureType == TEXTURE_NULL)
{ {
c.x = Short4(0x0000); c.x = Short4(0x0000);
...@@ -96,16 +91,12 @@ namespace sw ...@@ -96,16 +91,12 @@ namespace sw
} }
else else
{ {
Int face[4]; Float4 uuuu = u;
Float4 lodX; Float4 vvvv = v;
Float4 lodY; Float4 wwww = w;
Float4 lodZ; Float4 qqqq = q;
if(state.textureType == TEXTURE_CUBE)
{
cubeFace(face, uuuu, vvvv, lodX, lodY, lodZ, u, v, w);
}
Int face[4];
Float lod; Float lod;
Float anisotropy; Float anisotropy;
Float4 uDelta; Float4 uDelta;
...@@ -119,7 +110,9 @@ namespace sw ...@@ -119,7 +110,9 @@ namespace sw
} }
else else
{ {
computeLodCube(texture, lod, lodX, lodY, lodZ, bias.x, dsx, dsy, function); Float4 M;
cubeFace(face, uuuu, vvvv, u, v, w, M);
computeLodCube(texture, lod, u, v, w, bias.x, dsx, dsy, M, function);
} }
} }
else else
...@@ -331,15 +324,6 @@ namespace sw ...@@ -331,15 +324,6 @@ namespace sw
Float4 qqqq = q; Float4 qqqq = q;
Int face[4]; Int face[4];
Float4 lodX;
Float4 lodY;
Float4 lodZ;
if(state.textureType == TEXTURE_CUBE)
{
cubeFace(face, uuuu, vvvv, lodX, lodY, lodZ, u, v, w);
}
Float lod; Float lod;
Float anisotropy; Float anisotropy;
Float4 uDelta; Float4 uDelta;
...@@ -353,7 +337,9 @@ namespace sw ...@@ -353,7 +337,9 @@ namespace sw
} }
else else
{ {
computeLodCube(texture, lod, lodX, lodY, lodZ, bias.x, dsx, dsy, function); Float4 M;
cubeFace(face, uuuu, vvvv, u, v, w, M);
computeLodCube(texture, lod, u, v, w, bias.x, dsx, dsy, M, function);
} }
} }
else else
...@@ -1500,15 +1486,36 @@ namespace sw ...@@ -1500,15 +1486,36 @@ namespace sw
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod))); lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
} }
void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &s, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function) void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function)
{ {
if(function != Lod && function != Fetch) if(function != Lod && function != Fetch)
{ {
Float4 dudxy, dvdxy, dsdxy;
if(function != Grad) if(function != Grad)
{ {
Float4 dudxy = u.ywyw - u; Float4 U = u * M;
Float4 dvdxy = v.ywyw - v; Float4 V = v * M;
Float4 dsdxy = s.ywyw - s; Float4 W = w * M;
dudxy = U.ywyw - U;
dvdxy = V.ywyw - V;
dsdxy = W.ywyw - W;
}
else
{
dudxy = Float4(dsx.x.xx, dsy.x.xx);
dvdxy = Float4(dsx.y.xx, dsy.y.xx);
dsdxy = Float4(dsx.z.xx, dsy.z.xx);
dudxy = Float4(dudxy.xz, dudxy.xz);
dvdxy = Float4(dvdxy.xz, dvdxy.xz);
dsdxy = Float4(dsdxy.xz, dsdxy.xz);
dudxy *= Float4(M.x);
dvdxy *= Float4(M.x);
dsdxy *= Float4(M.x);
}
// Scale by texture dimensions and LOD // Scale by texture dimensions and LOD
dudxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD)); dudxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
...@@ -1523,22 +1530,6 @@ namespace sw ...@@ -1523,22 +1530,6 @@ namespace sw
dudxy += dsdxy; dudxy += dsdxy;
lod = Max(Float(dudxy.x), Float(dudxy.y)); // FIXME: Max(dudxy.x, dudxy.y); lod = Max(Float(dudxy.x), Float(dudxy.y)); // FIXME: Max(dudxy.x, dudxy.y);
}
else
{
Float4 dudxy = Float4(dsx.x.xx, dsy.x.xx);
Float4 dvdxy = Float4(dsx.y.xx, dsy.y.xx);
Float4 duvdxy = Float4(dudxy.xz, dvdxy.xz);
// Scale by texture dimensions and LOD
Float4 dUVdxy = duvdxy * *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
Float4 dUV2dxy = dUVdxy * dUVdxy;
Float4 dUV2 = dUV2dxy.xy + dUV2dxy.zw;
lod = Max(Float(dUV2.x), Float(dUV2.y)); // Square length of major axis
}
lod = log2sqrt(lod); // log2(sqrt(lod)) lod = log2sqrt(lod); // log2(sqrt(lod))
...@@ -1635,7 +1626,7 @@ namespace sw ...@@ -1635,7 +1626,7 @@ namespace sw
} }
} }
void SamplerCore::cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z) void SamplerCore::cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M)
{ {
Int4 xn = CmpLT(x, Float4(0.0f)); // x < 0 Int4 xn = CmpLT(x, Float4(0.0f)); // x < 0
Int4 yn = CmpLT(y, Float4(0.0f)); // y < 0 Int4 yn = CmpLT(y, Float4(0.0f)); // y < 0
...@@ -1673,7 +1664,7 @@ namespace sw ...@@ -1673,7 +1664,7 @@ namespace sw
face[3] = (face[0] >> 12) & 0x7; face[3] = (face[0] >> 12) & 0x7;
face[0] &= 0x7; face[0] &= 0x7;
Float4 M = Max(Max(absX, absY), absZ); M = Max(Max(absX, absY), absZ);
// U = xMajor ? (neg ^ -z) : (zMajor & neg) ^ x) // U = xMajor ? (neg ^ -z) : (zMajor & neg) ^ x)
U = As<Float4>((xMajor & (n ^ As<Int4>(-z))) | (~xMajor & ((zMajor & n) ^ As<Int4>(x)))); U = As<Float4>((xMajor & (n ^ As<Int4>(-z))) | (~xMajor & ((zMajor & n) ^ As<Int4>(x))));
...@@ -1684,10 +1675,6 @@ namespace sw ...@@ -1684,10 +1675,6 @@ namespace sw
M = reciprocal(M) * Float4(0.5f); M = reciprocal(M) * Float4(0.5f);
U = U * M + Float4(0.5f); U = U * M + Float4(0.5f);
V = V * M + Float4(0.5f); V = V * M + Float4(0.5f);
lodX = x * M;
lodY = y * M;
lodZ = z * M;
} }
Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode) Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode)
......
...@@ -72,9 +72,9 @@ namespace sw ...@@ -72,9 +72,9 @@ namespace sw
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);
void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &x, Float4 &y, Float4 &z, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function); void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function);
void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function); void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z); void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M);
Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode); Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function); void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function);
void computeIndices(UInt index[4], Int4& uuuu, Int4& vvvv, Int4& wwww, const Pointer<Byte> &mipmap, SamplerFunction function); void computeIndices(UInt index[4], Int4& uuuu, Int4& vvvv, Int4& wwww, const Pointer<Byte> &mipmap, SamplerFunction function);
......
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