Optimize mipmap base level.
We can avoid adding the base level to the computed lod by putting the
base level at index 0 of the mipmap array.
Change-Id: I0bdebec3e4d0a3617dea9e3d28fdeb5dae40444b
Reviewed-on: https://swiftshader-review.googlesource.com/15329
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 6d6be82..00351e1 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3192,13 +3192,9 @@
for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
{
- int surfaceLevel = mipmapLevel;
+ int surfaceLevel = mipmapLevel + baseLevel;
- if(surfaceLevel < baseLevel)
- {
- surfaceLevel = baseLevel;
- }
- else if(surfaceLevel > maxLevel)
+ if(surfaceLevel > maxLevel)
{
surfaceLevel = maxLevel;
}
@@ -3213,13 +3209,9 @@
for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
{
- int surfaceLevel = mipmapLevel;
+ int surfaceLevel = mipmapLevel + baseLevel;
- if(surfaceLevel < baseLevel)
- {
- surfaceLevel = baseLevel;
- }
- else if(surfaceLevel > maxLevel)
+ if(surfaceLevel > maxLevel)
{
surfaceLevel = maxLevel;
}
@@ -3234,13 +3226,9 @@
for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
{
- int surfaceLevel = mipmapLevel;
+ int surfaceLevel = mipmapLevel + baseLevel;
- if(surfaceLevel < baseLevel)
- {
- surfaceLevel = baseLevel;
- }
- else if(surfaceLevel > maxLevel)
+ if(surfaceLevel > maxLevel)
{
surfaceLevel = maxLevel;
}
@@ -3259,13 +3247,9 @@
for(int face = 0; face < 6; face++)
{
- int surfaceLevel = mipmapLevel;
+ int surfaceLevel = mipmapLevel + baseLevel;
- if(surfaceLevel < baseLevel)
- {
- surfaceLevel = baseLevel;
- }
- else if(surfaceLevel > maxLevel)
+ if(surfaceLevel > maxLevel)
{
surfaceLevel = maxLevel;
}
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp
index 53383cd..5686f04 100644
--- a/src/Shader/SamplerCore.cpp
+++ b/src/Shader/SamplerCore.cpp
@@ -525,17 +525,17 @@
mask = As<Int4>(CmpLT(Abs(coordinates - Float4(0.5f)), Float4(0.5f)));
}
- Short4 SamplerCore::offsetSample(Pointer<Byte> &texture, Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod)
+ Short4 SamplerCore::offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod)
{
Short4 offset = *Pointer<Short4>(mipmap + halfOffset);
if(state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
{
- offset &= Short4(CmpNLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel))))));
+ offset &= Short4(CmpNLE(Float4(lod), Float4(0.0f)));
}
else if(state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR)
{
- offset &= Short4(CmpLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel))))));
+ offset &= Short4(CmpLE(Float4(lod), Float4(0.0f)));
}
if(wrap)
@@ -759,10 +759,10 @@
}
else
{
- Short4 uuuu0 = offsetSample(texture, uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 0 : -1, lod);
- Short4 vvvv0 = offsetSample(texture, vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 0 : -1, lod);
- Short4 uuuu1 = offsetSample(texture, uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 2 : +1, lod);
- Short4 vvvv1 = offsetSample(texture, vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 2 : +1, lod);
+ Short4 uuuu0 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 0 : -1, lod);
+ Short4 vvvv0 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 0 : -1, lod);
+ Short4 uuuu1 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 2 : +1, lod);
+ Short4 vvvv1 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 2 : +1, lod);
Vector4s c0 = sampleTexel(uuuu0, vvvv0, wwww, offset, mipmap, buffer, function);
Vector4s c1 = sampleTexel(uuuu1, vvvv0, wwww, offset, mipmap, buffer, function);
@@ -966,9 +966,9 @@
{
for(int k = 0; k < 2; k++)
{
- u[i][j][k] = offsetSample(texture, uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, i * 2 - 1, lod);
- v[i][j][k] = offsetSample(texture, vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, j * 2 - 1, lod);
- s[i][j][k] = offsetSample(texture, wwww, mipmap, OFFSET(Mipmap,wHalf), state.addressingModeW == ADDRESSING_WRAP, k * 2 - 1, lod);
+ u[i][j][k] = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, i * 2 - 1, lod);
+ v[i][j][k] = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, j * 2 - 1, lod);
+ s[i][j][k] = offsetSample(wwww, mipmap, OFFSET(Mipmap,wHalf), state.addressingModeW == ADDRESSING_WRAP, k * 2 - 1, lod);
}
}
}
@@ -1219,7 +1219,7 @@
Int4 x0, x1, y0, y1, z0;
Float4 fu, fv;
- Int4 filter = computeFilterOffset(texture, lod);
+ Int4 filter = computeFilterOffset(lod);
address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU, function);
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(w, z0, z0, fv, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
@@ -1288,7 +1288,7 @@
Int4 x0, x1, y0, y1, z0, z1;
Float4 fu, fv, fw;
- Int4 filter = computeFilterOffset(texture, lod);
+ Int4 filter = computeFilterOffset(lod);
address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU, function);
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(w, z0, z1, fw, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
@@ -1444,9 +1444,6 @@
}
else assert(false);
- // TODO: Avoid float conversion.
- lod += Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
-
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
@@ -1513,9 +1510,6 @@
}
else assert(false);
- // TODO: Avoid float conversion.
- lod += Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
-
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
@@ -1580,9 +1574,6 @@
}
else assert(false);
- // TODO: Avoid float conversion.
- lod += Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
-
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
@@ -2286,7 +2277,7 @@
}
}
- Int4 SamplerCore::computeFilterOffset(Pointer<Byte> &texture, Float &lod)
+ Int4 SamplerCore::computeFilterOffset(Float &lod)
{
Int4 filter = -1;
@@ -2296,11 +2287,11 @@
}
else if(state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
{
- filter = CmpNLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)))));
+ filter = CmpNLE(Float4(lod), Float4(0.0f));
}
else if(state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR)
{
- filter = CmpLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)))));
+ filter = CmpLE(Float4(lod), Float4(0.0f));
}
return filter;
diff --git a/src/Shader/SamplerCore.hpp b/src/Shader/SamplerCore.hpp
index 31d6668..684c1a7 100644
--- a/src/Shader/SamplerCore.hpp
+++ b/src/Shader/SamplerCore.hpp
@@ -59,7 +59,7 @@
void border(Short4 &mask, Float4 &coordinates);
void border(Int4 &mask, Float4 &coordinates);
- Short4 offsetSample(Pointer<Byte> &texture, Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
+ Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
Vector4s sampleAniso(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);
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
@@ -85,7 +85,7 @@
void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);
void address(Float4 &uw, Int4& xyz0, Int4& xyz1, Float4& f, Pointer<Byte>& mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function);
- Int4 computeFilterOffset(Pointer<Byte> &texture, Float &lod);
+ Int4 computeFilterOffset(Float &lod);
void convertFixed12(Short4 &ci, Float4 &cf);
void convertFixed12(Vector4s &cs, Vector4f &cf);