Mesa (master): i915: Implement min/max lod clamping in hardware on 8xx.

Eric Anholt anholt at kemper.freedesktop.org
Wed Jan 5 23:13:42 UTC 2011


Module: Mesa
Branch: master
Commit: 973e821a633031fe5a8608b50beabb10af21430e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=973e821a633031fe5a8608b50beabb10af21430e

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan  5 14:27:41 2011 -0800

i915: Implement min/max lod clamping in hardware on 8xx.

This avoids 8xx-specific texture relayout for min/max lod changes.
One step closer to avoiding relayout for base/maxlevel changes!

---

 src/mesa/drivers/dri/i915/i830_reg.h            |    2 +
 src/mesa/drivers/dri/i915/i830_texstate.c       |   26 ++++++++++++++++----
 src/mesa/drivers/dri/intel/intel_tex_validate.c |   29 +++++++---------------
 3 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h
index ae13170..4144249 100644
--- a/src/mesa/drivers/dri/i915/i830_reg.h
+++ b/src/mesa/drivers/dri/i915/i830_reg.h
@@ -605,6 +605,8 @@
 #define TM0S3_MAX_MIP_MASK		(0xff<<9)
 #define TM0S3_MIN_MIP_SHIFT		3
 #define TM0S3_MIN_MIP_MASK		(0x3f<<3)
+#define TM0S3_MIN_MIP_SHIFT_830		5
+#define TM0S3_MIN_MIP_MASK_830		(0x3f<<5)
 #define TM0S3_KILL_PIXEL		(1<<2)
 #define TM0S3_KEYED_FILTER		(1<<1)
 #define TM0S3_CHROMA_KEY		(1<<0)
diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
index b3bb883..8340cd8 100644
--- a/src/mesa/drivers/dri/i915/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915/i830_texstate.c
@@ -28,13 +28,14 @@
 #include "main/mtypes.h"
 #include "main/enums.h"
 #include "main/colormac.h"
+#include "main/macros.h"
 
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
 
 #include "i830_context.h"
 #include "i830_reg.h"
-
+#include "intel_chipset.h"
 
 
 static GLuint
@@ -189,6 +190,8 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
 
    {
       GLuint minFilt, mipFilt, magFilt;
+      float maxlod;
+      uint32_t minlod_fixed, maxlod_fixed;
 
       switch (tObj->MinFilter) {
       case GL_NEAREST:
@@ -252,10 +255,23 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
          state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION;
 #endif
 
-      state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel -
-                                    intelObj->firstLevel) *
-                                   4) << TM0S3_MIN_MIP_SHIFT;
-
+      /* We get one field with fraction bits for the maximum
+       * addressable (smallest resolution) LOD.  Use it to cover both
+       * MAX_LEVEL and MAX_LOD.
+       */
+      minlod_fixed = U_FIXED(CLAMP(tObj->MinLod, 0.0, 11), 4);
+      maxlod = MIN2(tObj->MaxLod, tObj->_MaxLevel - tObj->BaseLevel);
+      if (intel->intelScreen->deviceID == PCI_CHIP_I855_GM ||
+	  intel->intelScreen->deviceID == PCI_CHIP_I865_G) {
+	 maxlod_fixed = U_FIXED(CLAMP(maxlod, 0.0, 11.75), 2);
+	 maxlod_fixed = MAX2(maxlod_fixed, (minlod_fixed + 3) >> 2);
+	 state[I830_TEXREG_TM0S3] |= maxlod_fixed << TM0S3_MIN_MIP_SHIFT;
+      } else {
+	 maxlod_fixed = U_FIXED(CLAMP(maxlod, 0.0, 11), 0);
+	 maxlod_fixed = MAX2(maxlod_fixed, (minlod_fixed + 15) >> 4);
+	 state[I830_TEXREG_TM0S3] |= maxlod_fixed << TM0S3_MIN_MIP_SHIFT_830;
+      }
+      state[I830_TEXREG_TM0S3] |= minlod_fixed << TM0S3_MAX_MIP_SHIFT;
       state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) |
                                    (mipFilt << TM0S3_MIP_FILTER_SHIFT) |
                                    (magFilt << TM0S3_MAG_FILTER_SHIFT));
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index 9465279..8383c97 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -34,26 +34,15 @@ intel_calculate_first_last_level(struct intel_context *intel,
        */
       lastLevel = tObj->BaseLevel;
    } else {
-      if (intel->gen == 2) {
-	 firstLevel += (GLint) (tObj->MinLod + 0.5);
-	 firstLevel = MAX2(firstLevel, tObj->BaseLevel);
-	 firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
-	 lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
-	 lastLevel = MAX2(lastLevel, tObj->BaseLevel);
-	 lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
-	 lastLevel = MIN2(lastLevel, tObj->MaxLevel);
-	 lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
-      } else {
-	 /* Min/max LOD are taken into account in sampler state.  We don't
-	  * want to re-layout textures just because clamping has been applied
-	  * since it means a bunch of blitting around and probably no memory
-	  * savings (since we have to keep the other levels around anyway).
-	  */
-	 lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
-			  tObj->MaxLevel);
-	 /* need at least one level */
-	 lastLevel = MAX2(firstLevel, lastLevel);
-      }
+      /* Min/max LOD are taken into account in sampler state.  We don't
+       * want to re-layout textures just because clamping has been applied
+       * since it means a bunch of blitting around and probably no memory
+       * savings (since we have to keep the other levels around anyway).
+       */
+      lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
+		       tObj->MaxLevel);
+      /* need at least one level */
+      lastLevel = MAX2(firstLevel, lastLevel);
    }
 
    /* save these values */




More information about the mesa-commit mailing list