[Intel-gfx] [PATCH] drm/i915: fix tiling limits for i915 class hw

Daniel Vetter daniel.vetter at ffwll.ch
Thu Apr 15 09:08:16 CEST 2010


Current code is definitely crap: Largest pitch allowed spills into
the TILING_Y bit of the fence registers ... :(

I've rewritten the limits check under the assumption that 3rd gen hw
has a 3d pitch limit of 8kb (like 2nd gen). This is supported by an
otherwise totally misleading XXX comment.

This bug mostly resulted in tiling-corrupted pixmaps because the kernel
allowed too wide buffers to be tiled. Bug brought to the light by the
xf86-video-intel 2.11 release because that unconditionally enabled
tiling for pixmaps, relying on the kernel to check things. Tiling for
the framebuffer was not affected because the ddx does some additional
checks there ensure the buffer is within hw-limits.

Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27449
Tested-by: Alexander Lam <lambchop468 at gmail.com>
Cc: stable at kernel.org
---
 drivers/gpu/drm/i915/i915_gem_tiling.c |   15 ++++++++++-----
 drivers/gpu/drm/i915/i915_reg.h        |    2 +-
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 449157f..b0c9a79 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -205,11 +205,16 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
 	} else if (IS_I9XX(dev)) {
 		uint32_t pitch_val = ffs(stride / tile_width) - 1;
 
-		/* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
-		 * instead of 4 (2KB) on 945s.
-		 */
-		if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
-		    size > (I830_FENCE_MAX_SIZE_VAL << 20))
+		if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+			return false;
+
+		/* 128 byte wide tiles use the old i830 limit to again
+		 * allow 8kb pitches */
+		if (tiling_mode == I915_TILING_Y
+				&& HAS_128_BYTE_Y_TILING(dev)) {
+			if (pitch_val > I830_FENCE_MAX_PITCH_VAL)
+				return false;
+		} else if (pitch_val > I915_FENCE_MAX_PITCH_VAL)
 			return false;
 	} else {
 		uint32_t pitch_val = ffs(stride / tile_width) - 1;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index cbbf59f..773c1ad 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -241,7 +241,7 @@
 #define   I830_FENCE_SIZE_BITS(size)	((ffs((size) >> 19) - 1) << 8)
 #define   I830_FENCE_PITCH_SHIFT	4
 #define   I830_FENCE_REG_VALID		(1<<0)
-#define   I915_FENCE_MAX_PITCH_VAL	0x10
+#define   I915_FENCE_MAX_PITCH_VAL	4
 #define   I830_FENCE_MAX_PITCH_VAL	6
 #define   I830_FENCE_MAX_SIZE_VAL	(1<<8)
 
-- 
1.6.6.1




More information about the Intel-gfx mailing list