xf86-video-intel: src/i830_uxa.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jun 23 13:35:17 PDT 2010


 src/i830_uxa.c |   53 +++++++++++++++++++++++++++--------------------------
 1 file changed, 27 insertions(+), 26 deletions(-)

New commits:
commit 6d33e578de4e23336ac69cc3c5d0935a65d4dda1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 23 21:28:50 2010 +0100

    Limit maximum tiled stride to 8k and untiled to 32k.
    
    Tiling on gen 2/3 hardware is only supported for pitches up to 8192
    bytes, so above this limit the surface will be untiled and we will no
    longer have to comply with the power-of-two pitch alignment. So
    disabling tiling for these too wide surface should ~halve the memory
    requirement for the full surface.
    
    Also the absolute limit for the 2D blitter is 32,768 bytes. The
    documentation says "up to 32,768 bytes" and my PineView box was
    malfunction with a surface stride of 32,768 so set the limit to be
    32,767.
    
    References:
    
      Bug 28497 - Graphics corruption after opening a specific website
      https://bugs.freedesktop.org/show_bug.cgi?id=28497
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 1ec7ab8..61e857f 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -152,14 +152,13 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
 {
 	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
 	intel_screen_private *intel = intel_get_screen_private(scrn);
-	int pitch, pitch_align;
-	int size;
+	int pitch, size;
 
 	if (*tiling != I915_TILING_NONE) {
 		/* First check whether tiling is necessary. */
-		pitch_align = intel->accel_pixmap_pitch_alignment;
-		size = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
-				pitch_align) * ALIGN (h, 2);
+		pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
+		pitch = ROUND_TO(pitch, intel->accel_pixmap_pitch_alignment);
+		size = pitch * ALIGN (h, 2);
 		if (!IS_I965G(intel)) {
 			/* Older hardware requires fences to be pot size
 			 * aligned with a minimum of 1 MiB, so causes
@@ -167,6 +166,12 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
 			 */
 			if (size < 1024*1024/2)
 				*tiling = I915_TILING_NONE;
+
+			/* Gen 2/3 has a maximum stride for tiling of
+			 * 8192 bytes.
+			 */
+			if (pitch > KB(8))
+				*tiling = I915_TILING_NONE;
 		} else if (size <= 4096) {
 			/* Disable tiling beneath a page size, we will not see
 			 * any benefit from reducing TLB misses and instead
@@ -179,29 +184,19 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
 	pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
 	if (pitch <= 256)
 		*tiling = I915_TILING_NONE;
-  repeat:
-	if (*tiling == I915_TILING_NONE) {
-		pitch_align = intel->accel_pixmap_pitch_alignment;
-	} else {
-		pitch_align = 512;
-	}
-
-	*stride = ROUND_TO(pitch, pitch_align);
 
-	if (*tiling == I915_TILING_NONE) {
-		/* Round the height up so that the GPU's access to a 2x2 aligned
-		 * subspan doesn't address an invalid page offset beyond the
-		 * end of the GTT.
-		 */
-		size = *stride * ALIGN(h, 2);
-	} else {
+	if (*tiling != I915_TILING_NONE) {
 		int aligned_h;
+
 		if (*tiling == I915_TILING_X)
 			aligned_h = ALIGN(h, 8);
 		else
 			aligned_h = ALIGN(h, 32);
 
-		*stride = i830_get_fence_pitch(intel, *stride, *tiling);
+		*stride = i830_get_fence_pitch(intel,
+					       ROUND_TO(pitch, 512),
+					       *tiling);
+
 		/* Round the object up to the size of the fence it will live in
 		 * if necessary.  We could potentially make the kernel allocate
 		 * a larger aperture space and just bind the subset of pages in,
@@ -209,12 +204,18 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
 		 * with drm_intel_bufmgr_check_aperture().
 		 */
 		size = i830_get_fence_size(intel, *stride * aligned_h);
-		assert(size >= *stride * aligned_h);
+
+		if (size > intel->max_tiling_size)
+			*tiling = I915_TILING_NONE;
 	}
 
-	if (*tiling != I915_TILING_NONE && size > intel->max_tiling_size) {
-		*tiling = I915_TILING_NONE;
-		goto repeat;
+	if (*tiling == I915_TILING_NONE) {
+		/* Round the height up so that the GPU's access to a 2x2 aligned
+		 * subspan doesn't address an invalid page offset beyond the
+		 * end of the GTT.
+		 */
+		*stride = ROUND_TO(pitch, intel->accel_pixmap_pitch_alignment);
+		size = *stride * ALIGN(h, 2);
 	}
 
 	return size;
@@ -987,7 +988,7 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		 * frequently, and also will tend to fail to successfully map when doing
 		 * SW fallbacks because we overcommit address space for BO access.
 		 */
-		if (size > intel->max_bo_size) {
+		if (size > intel->max_bo_size || stride >= KB(32)) {
 			fbDestroyPixmap(pixmap);
 			return fbCreatePixmap(screen, w, h, depth, usage);
 		}


More information about the xorg-commit mailing list