summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-01-05 14:27:41 -0800
committerEric Anholt <[email protected]>2011-01-05 14:50:24 -0800
commit973e821a633031fe5a8608b50beabb10af21430e (patch)
treef34b48728ec175caa1570ba366918ad112dc8f31
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!
-rw-r--r--src/mesa/drivers/dri/i915/i830_reg.h2
-rw-r--r--src/mesa/drivers/dri/i915/i830_texstate.c26
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_validate.c29
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 ae1317029a2..41442490706 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 b3bb8837cca..8340cd8c333 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 9465279111b..8383c974c38 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 */