summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2007-12-17 22:43:48 -0800
committerKeith Packard <keithp@keithp.com>2007-12-18 10:22:04 -0800
commita183efc132c8db1bb42525ac177ffff96f69a59b (patch)
treee4106d93ea70e4b9fbe635704983e34b1dd24a78 /src/mesa/drivers/dri/intel
parent6f1bfdc4bf5b72ac705b8cbb2dc431e133dcb5b8 (diff)
[Intel] Centralize mipmap pitch computations.
mipmap pitches must account for the device alignment requirements, which used to be fairly simple; just align to a 4-byte boundary. However, to allow textures to be drawn to under TTM, they now need to be aligned to a 64-byte boundary. Placing all of the alignment constraints in a single function allows this new constraint to be applied uniformly. There was some pitch constraining code in intel_miptree_create, but that was modifying the pitch long after the miptree had been layed out, so it only served to wreck the mipmap and cause rendering errors.
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c81
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h13
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.h2
4 files changed, 64 insertions, 36 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 3517939066..6610771b6e 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -78,44 +78,19 @@ intel_miptree_create(struct intel_context *intel,
mt->cpp = compress_byte ? compress_byte : cpp;
mt->compressed = compress_byte ? 1 : 0;
mt->refcount = 1;
+ mt->pitch = 0;
#ifdef I915
if (IS_945(intel->intelScreen->deviceID))
- ok = i945_miptree_layout(mt);
+ ok = i945_miptree_layout(intel, mt);
else
- ok = i915_miptree_layout(mt);
+ ok = i915_miptree_layout(intel, mt);
#else
- ok = brw_miptree_layout(mt);
+ ok = brw_miptree_layout(intel, mt);
#endif
if (ok) {
-#ifdef I915
- if (!mt->compressed) {
- int align;
-
- if (intel->ttm) {
- /* XXX: Align pitch to multiple of 64 bytes for now to allow
- * render-to-texture to work in all cases. This should probably be
- * replaced at some point by some scheme to only do this when really
- * necessary.
- */
- align = 63;
- } else {
- align = 3;
- }
-
- mt->pitch = (mt->pitch * cpp + align) & ~align;
-
- /* XXX: At least the i915 seems very upset when the pitch is a multiple
- * of 1024 and sometimes 512 bytes - performance can drop by several
- * times. Go to the next multiple of the required alignment for now.
- */
- if (!(mt->pitch & 511))
- mt->pitch += align + 1;
-
- mt->pitch /= cpp;
- }
-#endif /* I915 */
+ assert (mt->pitch);
mt->region = intel_region_alloc(intel,
mt->cpp, mt->pitch, mt->total_height);
@@ -129,6 +104,52 @@ intel_miptree_create(struct intel_context *intel,
return mt;
}
+/**
+ * intel_miptree_pitch_align:
+ *
+ * @intel: intel context pointer
+ *
+ * @mt: the miptree to compute pitch alignment for
+ *
+ * @pitch: the natural pitch value
+ *
+ * Given @pitch, compute a larger value which accounts for
+ * any necessary alignment required by the device
+ */
+
+int intel_miptree_pitch_align (struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ int pitch)
+{
+ if (!mt->compressed) {
+ int pitch_align;
+
+ if (intel->ttm) {
+ /* XXX: Align pitch to multiple of 64 bytes for now to allow
+ * render-to-texture to work in all cases. This should probably be
+ * replaced at some point by some scheme to only do this when really
+ * necessary.
+ */
+ pitch_align = 64;
+ } else {
+ pitch_align = 4;
+ }
+
+ pitch = ALIGN(pitch * mt->cpp, pitch_align);
+
+#ifdef I915
+ /* XXX: At least the i915 seems very upset when the pitch is a multiple
+ * of 1024 and sometimes 512 bytes - performance can drop by several
+ * times. Go to the next multiple of the required alignment for now.
+ */
+ if (!(pitch & 511))
+ pitch += pitch_align;
+#endif
+
+ pitch /= mt->cpp;
+ }
+ return pitch;
+}
void
intel_miptree_reference(struct intel_mipmap_tree **dst,
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 4a76717688..968eec4fec 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -123,6 +123,10 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
GLuint cpp,
GLuint compress_byte);
+int intel_miptree_pitch_align (struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ int pitch);
+
void intel_miptree_reference(struct intel_mipmap_tree **dst,
struct intel_mipmap_tree *src);
@@ -190,8 +194,11 @@ void intel_miptree_image_copy(struct intel_context *intel,
/* i915_mipmap_tree.c:
*/
-GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt);
-GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt);
-GLboolean brw_miptree_layout(struct intel_mipmap_tree *mt);
+GLboolean i915_miptree_layout(struct intel_context *intel,
+ struct intel_mipmap_tree *mt);
+GLboolean i945_miptree_layout(struct intel_context *intel,
+ struct intel_mipmap_tree *mt);
+GLboolean brw_miptree_layout(struct intel_context *intel,
+ struct intel_mipmap_tree *mt);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index 4da636021b..edc3a2eaa4 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -52,7 +52,7 @@ GLuint intel_compressed_alignment(GLenum internalFormat)
return alignment;
}
-void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
+void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt )
{
GLint align_h = 2, align_w = 4;
GLuint level;
@@ -92,7 +92,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = ALIGN(mt->pitch * mt->cpp, 4) / mt->cpp;
+ mt->pitch = intel_miptree_pitch_align (intel, mt, mt->pitch);
mt->total_height = 0;
for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h
index 99d41c3629..193699d3f7 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h
@@ -38,5 +38,5 @@ static GLuint minify( GLuint d )
return MAX2(1, d>>1);
}
-extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt );
+extern void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt );
extern GLuint intel_compressed_alignment(GLenum);