xf86-video-intel: src/drmmode_display.c src/i830.h src/i830_memory.c src/i830_uxa.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Nov 30 14:23:20 PST 2009


 src/drmmode_display.c |    1 +
 src/i830.h            |    2 ++
 src/i830_memory.c     |   23 +++++++++++++++++++++++
 src/i830_uxa.c        |    6 ++++++
 4 files changed, 32 insertions(+)

New commits:
commit 00aa4f7a45a318af5b651f9f3928e9da4443233a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 30 20:50:31 2009 +0000

    uxa: Limit maximum size of tiled objects
    
    On older chipsets (i.e. pre-i965) tiling is very restrictive and imposes
    severe size and alignment constraints. Combine that with relatively
    small apertures and it is very easy to create a batch buffer that
    cannot be mapped into the aperture (but would otherwise fit based purely
    on total object size). To prevent this we need to not use tiling for large
    buffers (the very same buffers where tiling would be of most benefit!).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 3417cab..a469f6c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -396,6 +396,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	}
 
 	i830_set_max_gtt_map_size(scrn);
+	i830_set_max_tiling_size(scrn);
 
 	if (scrn->pScreen)
 		xf86_reload_cursors(scrn->pScreen);
diff --git a/src/i830.h b/src/i830.h
index 91ea1c1..c895021 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -311,6 +311,7 @@ typedef struct intel_screen_private {
 	int accel_max_x;
 	int accel_max_y;
 	int max_gtt_map_size;
+	int max_tiling_size;
 
 	Bool XvDisabled;	/* Xv disabled in PreInit. */
 	Bool XvEnabled;		/* Xv enabled for this generation. */
@@ -467,6 +468,7 @@ unsigned long i830_get_fence_size(intel_screen_private *intel, unsigned long siz
 unsigned long i830_get_fence_pitch(intel_screen_private *intel, unsigned long pitch,
 				   uint32_t tiling_mode);
 void i830_set_max_gtt_map_size(ScrnInfoPtr scrn);
+void i830_set_max_tiling_size(ScrnInfoPtr scrn);
 
 i830_memory *i830_allocate_framebuffer(ScrnInfoPtr scrn);
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index f6ed71c..ea4922a 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -525,6 +525,7 @@ i830_memory *i830_allocate_framebuffer(ScrnInfoPtr scrn)
 	}
 
 	i830_set_max_gtt_map_size(scrn);
+	i830_set_max_tiling_size(scrn);
 
 	return front_buffer;
 }
@@ -595,6 +596,7 @@ Bool i830_bind_all_memory(ScrnInfoPtr scrn)
 					   intel->cursor_mem_argb[i]->bo);
 
 	i830_set_max_gtt_map_size(scrn);
+	i830_set_max_tiling_size(scrn);
 
 	if (intel->front_buffer)
 		scrn->fbOffset = intel->front_buffer->offset;
@@ -663,3 +665,24 @@ void i830_set_max_gtt_map_size(ScrnInfoPtr scrn)
 		    aperture.aper_available_size * 3 / 4 / 2;
 	}
 }
+
+void i830_set_max_tiling_size(ScrnInfoPtr scrn)
+{
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	struct drm_i915_gem_get_aperture aperture;
+	int ret;
+
+	/* Default low value in case it gets used during server init. */
+	intel->max_tiling_size = 4 * 1024 * 1024;
+
+	ret =
+	    ioctl(intel->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+	if (ret == 0) {
+		/* Let objects be tiled up to the size where only 4 would fit in
+		 * the aperture, presuming worst case alignment.
+		 */
+		intel->max_tiling_size = aperture.aper_available_size / 4;
+		if (!IS_I965G(intel))
+			intel->max_tiling_size /= 2;
+	}
+}
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 89da5d0..801c2c7 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -138,6 +138,7 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
 			*tiling = I915_TILING_NONE;
 	}
 
+  repeat:
 	if (*tiling == I915_TILING_NONE) {
 		pitch_align = intel->accel_pixmap_pitch_alignment;
 	} else {
@@ -171,6 +172,11 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
 		assert(size >= *stride * aligned_h);
 	}
 
+	if (*tiling != I915_TILING_NONE && size > intel->max_tiling_size) {
+		*tiling = I915_TILING_NONE;
+		goto repeat;
+	}
+
 	return size;
 }
 


More information about the xorg-commit mailing list