Fix computing anisotropy factor for single-level mipmap
When anisotropic filtering is enabled, we need to compute the anisotropy
factor. This computation is part of the LOD computation, so don't skip
it even when there's only a single mipmap level.
The computation of the LOD and anisotropy are a bit intertwined because
we need to adjust the LOD according to the anisotropy, but we could
still skip a few calculations in the single-level mipmap case. This
change does not perform this micro-optimization yet.
Bug: swiftshader:163
Bug: b/151263485
Change-Id: Ib250cfd9ec2d784761887c1c1f58c4127fa6d92e
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/56108
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Sean Risser <srisser@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 3d5521d..2239ca9 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -54,12 +54,14 @@
w = As<Float4>(face);
}
- bool singleMipLevel = (state.minLod == state.maxLod) && (function != Query) && (function != Fetch);
+ // Determine if we can skip the LOD computation. This is the case when the mipmap has only one level, except for LOD query,
+ // where we have to return the computed value. Anisotropic filtering requires computing the anisotropy factor even for a single mipmap level.
+ bool singleMipLevel = (state.minLod == state.maxLod);
+ bool requiresLodComputation = (function == Query) || (function == Fetch) || (state.textureFilter == FILTER_ANISOTROPIC);
+ bool skipLodComputation = singleMipLevel && !requiresLodComputation;
- // We can't skip the LOD computation for LOD query, where we have to return the proper value
- if(singleMipLevel)
+ if(skipLodComputation)
{
- // Skip costly LOD computation if there's only 1 possible outcome
lod = state.minLod;
}
else if(function == Implicit || function == Bias || function == Grad || function == Query)
@@ -116,7 +118,7 @@
c.y = Float4(lod); // Unclamped LOD.
}
- if (!singleMipLevel)
+ if(!skipLodComputation)
{
lod = Max(lod, state.minLod);
lod = Min(lod, state.maxLod);
@@ -1240,6 +1242,8 @@
anisotropy = lod * Rcp(det, Precision::Relaxed);
anisotropy = Min(anisotropy, state.maxAnisotropy);
+ // TODO(b/151263485): While we always need `lod` above, when there's only
+ // a single mipmap level the following calculations could be skipped.
lod *= Rcp(anisotropy * anisotropy, Precision::Relaxed);
}