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