Only perform LOD computation when it is necessary

If an image has a single mip level, and filtering isn't LOD dependent,
as is the case when using FILTER_MIN_POINT_MAG_LINEAR or
FILTER_MIN_LINEAR_MAG_POINT, LOD computation is not necessary in
order to perform image sampling and can be bypassed entirely.

Bug: b/179889245
Change-Id: Ic69fe0c45211ccbb66c88c502c2dba1c50630aa7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/52688
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 646d875..3d5521d 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -54,7 +54,15 @@
 		w = As<Float4>(face);
 	}
 
-	if(function == Implicit || function == Bias || function == Grad || function == Query)
+	bool singleMipLevel = (state.minLod == state.maxLod) && (function != Query) && (function != Fetch);
+
+	// We can't skip the LOD computation for LOD query, where we have to return the proper value
+	if(singleMipLevel)
+	{
+		// Skip costly LOD computation if there's only 1 possible outcome
+		lod = state.minLod;
+	}
+	else if(function == Implicit || function == Bias || function == Grad || function == Query)
 	{
 		if(state.is1D())
 		{
@@ -108,8 +116,11 @@
 			c.y = Float4(lod);  // Unclamped LOD.
 		}
 
-		lod = Max(lod, state.minLod);
-		lod = Min(lod, state.maxLod);
+		if (!singleMipLevel)
+		{
+			lod = Max(lod, state.minLod);
+			lod = Min(lod, state.maxLod);
+		}
 
 		if(function == Query)
 		{