summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2009-10-29 11:52:28 -0700
committerEric Anholt <[email protected]>2009-10-29 12:06:04 -0700
commitf8f40b53a6a4551630e25bfd7f6e12334bb0f3f8 (patch)
tree439a6e62c435a4b9594a20ca6d34009f5ffe9895
parent374447244165b3b79892cb6840a76ea4c2f21f1e (diff)
i915: Implement min/max LOD clamping with the hardware.
This gets us expected behavior for clamping between mipmap levels, and avoids relayout of textures for doing clamping. Fixes piglit lodclamp-between.
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c12
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_sampler_state.c13
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h13
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_validate.c48
4 files changed, 46 insertions, 40 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 3a20e9c3aba..1397f04a59e 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -27,6 +27,7 @@
#include "main/mtypes.h"
#include "main/enums.h"
+#include "main/macros.h"
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
@@ -200,10 +201,10 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
}
state[I915_TEXREG_MS4] =
- ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK |
- ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) <<
- MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - 1) <<
- MS4_VOLUME_DEPTH_SHIFT));
+ ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
+ MS4_CUBE_FACE_ENA_MASK |
+ (U_FIXED(CLAMP(tObj->MaxLod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
+ ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
{
@@ -333,6 +334,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
(translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
+ state[I915_TEXREG_SS3] |= (U_FIXED(CLAMP(tObj->MinLod, 0.0, 11.0), 4) <<
+ SS3_MIN_LOD_SHIFT);
+
}
/* convert border color from float to ubyte */
diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
index 416ffc97615..0acb0274313 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
@@ -66,19 +66,6 @@ static GLuint translate_wrap_mode( GLenum wrap )
}
}
-
-static GLuint U_FIXED(GLfloat value, GLuint frac_bits)
-{
- value *= (1<<frac_bits);
- return value < 0 ? 0 : value;
-}
-
-static GLint S_FIXED(GLfloat value, GLuint frac_bits)
-{
- return value * (1<<frac_bits);
-}
-
-
static dri_bo *upload_default_color( struct brw_context *brw,
const GLfloat *color )
{
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 2778cc0136d..356fa4d1e58 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -353,6 +353,19 @@ extern char *__progname;
#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
#define IS_POWER_OF_TWO(val) (((val) & (val - 1)) == 0)
+static inline uint32_t
+U_FIXED(float value, uint32_t frac_bits)
+{
+ value *= (1 << frac_bits);
+ return value < 0 ? 0 : value;
+}
+
+static inline uint32_t
+S_FIXED(float value, uint32_t frac_bits)
+{
+ return value * (1 << frac_bits);
+}
+
#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index d5b562f5e57..504993989ae 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -5,6 +5,7 @@
#include "intel_batchbuffer.h"
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
+#include "intel_chipset.h"
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
@@ -14,7 +15,8 @@
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
*/
static void
-intel_calculate_first_last_level(struct intel_texture_object *intelObj)
+intel_calculate_first_last_level(struct intel_context *intel,
+ struct intel_texture_object *intelObj)
{
struct gl_texture_object *tObj = &intelObj->base;
const struct gl_texture_image *const baseImage =
@@ -40,27 +42,27 @@ intel_calculate_first_last_level(struct intel_texture_object *intelObj)
firstLevel = lastLevel = tObj->BaseLevel;
}
else {
-#ifdef I915
- firstLevel = tObj->BaseLevel + (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
- /* Currently not taking min/max lod into account here, those
- * values are programmed as sampler state elsewhere and we
- * upload the same mipmap levels regardless. Not sure if
- * this makes sense as it means it isn't possible for the app
- * to use min/max lod to reduce texture memory pressure:
- */
- firstLevel = tObj->BaseLevel;
- lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
- tObj->MaxLevel);
- lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
-#endif
+ if (!IS_9XX(intel->intelScreen->deviceID)) {
+ firstLevel = tObj->BaseLevel + (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).
+ */
+ firstLevel = tObj->BaseLevel;
+ lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
+ tObj->MaxLevel);
+ /* need at least one level */
+ lastLevel = MAX2(firstLevel, lastLevel);
+ }
}
break;
case GL_TEXTURE_RECTANGLE_NV:
@@ -135,7 +137,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
/* What levels must the tree include at a minimum?
*/
- intel_calculate_first_last_level(intelObj);
+ intel_calculate_first_last_level(intel, intelObj);
firstImage =
intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]);