i915: Implement min/max lod clamping in hardware on 8xx.
authorEric Anholt <eric@anholt.net>
Wed, 5 Jan 2011 22:27:41 +0000 (14:27 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 5 Jan 2011 22:50:24 +0000 (14:50 -0800)
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
src/mesa/drivers/dri/i915/i830_texstate.c
src/mesa/drivers/dri/intel/intel_tex_validate.c

index ae1317029a23c455818f82d9e84456c62bb9d3b9..4144249070639e3cbbd7ddc8609693b214a03887 100644 (file)
 #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)
index b3bb8837ccadcb943a067d836f0607c402af6ec0..8340cd8c3332f281475b7f412d2a04c8a2898bb2 100644 (file)
 #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));
index 9465279111b12b2d16013e6c449dc04b18caf08c..8383c974c388fb86c6bcc1b5c9e40139e414754a 100644 (file)
@@ -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 */