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);
 	}