summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i915
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2011-01-05 14:27:41 -0800
committerEric Anholt <eric@anholt.net>2011-01-05 14:50:24 -0800
commit973e821a633031fe5a8608b50beabb10af21430e (patch)
treef34b48728ec175caa1570ba366918ad112dc8f31 /src/mesa/drivers/dri/i915
parent6f31da584fd0c65095c325e60728f8230c66385a (diff)
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!
Diffstat (limited to 'src/mesa/drivers/dri/i915')
-rw-r--r--src/mesa/drivers/dri/i915/i830_reg.h2
-rw-r--r--src/mesa/drivers/dri/i915/i830_texstate.c26
2 files changed, 23 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h
index ae1317029a..4144249070 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 b3bb8837cc..8340cd8c33 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));