xf86-video-intel: 2 commits - src/drmmode_display.c src/i830_exa.c src/i830.h src/i830_memory.c src/i830_video.c

Eric Anholt anholt at kemper.freedesktop.org
Tue May 19 10:09:52 PDT 2009


 src/drmmode_display.c |    2 ++
 src/i830.h            |    2 ++
 src/i830_exa.c        |   20 ++++++++++++++++----
 src/i830_memory.c     |   26 ++++++++++++++++++++++++++
 src/i830_video.c      |   16 +++++++++-------
 5 files changed, 55 insertions(+), 11 deletions(-)

New commits:
commit 09beee378cecd1079e7a9fa6eee8f084d680d37e
Author: Eric Anholt <eric at anholt.net>
Date:   Mon May 18 18:01:05 2009 -0700

    Don't do GTT maps on objects bigger than half the available aperture size.
    
    The basic problem is that software fallbacks will do single instructions that
    copy from one GTT-mapped BO into another GTT-mapped BO.  If we can't get both
    of them bound simultanously, we fault one in, retry the instruction, fault the
    other in (kicking out #1), retry the instruction, fault #1 back in
    (kicking out #2), etc.
    
    Note that we'll still get into a nasty spot if you do a composite operation
    with a mask where all 3 are big-but-less-than-half-available-aperture, where
    you'll thrash.  It at least means you'll make progress, though, since each
    instruction will only be operating on two BOs at at time, and the situation
    seems unlikely.
    
    Bug #20152 (3/3)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 7df7b6f..24e0e26 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -232,6 +232,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		drmmode_output_dpms(output, DPMSModeOn);
 	}
 
+	i830_set_max_gtt_map_size(pScrn);
+
 done:
 	if (!ret) {
 		crtc->x = saved_x;
diff --git a/src/i830.h b/src/i830.h
index 0969c48..7c260de 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -437,6 +437,7 @@ typedef struct _I830Rec {
    int accel_pixmap_offset_alignment;
    int accel_max_x;
    int accel_max_y;
+   int max_gtt_map_size;
 
    I830WriteIndexedByteFunc writeControl;
    I830ReadIndexedByteFunc readControl;
@@ -748,6 +749,7 @@ Bool i830_bind_all_memory(ScrnInfoPtr pScrn);
 Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
 unsigned long i830_get_fence_size(I830Ptr pI830, unsigned long size);
 unsigned long i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format);
+void i830_set_max_gtt_map_size(ScrnInfoPtr pScrn);
 
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 824f032..3ca7933 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -506,9 +506,18 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 
 	/* Kernel manages fences at GTT map/fault time */
 	if (i830->kernel_exec_fencing) {
-	    if (drm_intel_gem_bo_map_gtt(bo)) {
-		xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
-			   __FUNCTION__);
+	    if (bo->size < i830->max_gtt_map_size) {
+		if (drm_intel_gem_bo_map_gtt(bo)) {
+		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			       "%s: bo map failed\n",
+			       __FUNCTION__);
+		    return FALSE;
+		}
+	    } else {
+		if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
+		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			       "%s: bo map failed\n",
+			       __FUNCTION__);
 		return FALSE;
 	    }
 	    pixmap->devPrivate.ptr = bo->virtual;
@@ -542,7 +551,10 @@ i830_uxa_finish_access (PixmapPtr pixmap)
 	}
 
 	if (i830->kernel_exec_fencing)
-	    drm_intel_gem_bo_unmap_gtt(bo);
+	    if (bo->size < i830->max_gtt_map_size)
+		drm_intel_gem_bo_unmap_gtt(bo);
+	    else
+		dri_bo_unmap(bo);
 	else
 	    drm_intel_bo_unpin(bo);
 	pixmap->devPrivate.ptr = NULL;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2a697a7..99b9fc8 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1128,6 +1128,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn)
     if (!pI830->use_drm_mode && pI830->FbBase && front_buffer->bound)
 	memset (pI830->FbBase + front_buffer->offset, 0, size);
 
+    i830_set_max_gtt_map_size(pScrn);
+
     return front_buffer;
 }
 
@@ -1588,6 +1590,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn)
     }
     if (!pI830->use_drm_mode)
 	i830_update_cursor_offsets(pScrn);
+    i830_set_max_gtt_map_size(pScrn);
 
     return TRUE;
 }
@@ -1672,3 +1675,26 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
     return TRUE;
 }
 #endif
+
+void
+i830_set_max_gtt_map_size(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    struct drm_i915_gem_get_aperture aperture;
+    int ret;
+
+    /* Default low value in case it gets used during server init. */
+    pI830->max_gtt_map_size = 16 * 1024 * 1024;
+
+    if (!pI830->have_gem)
+	return;
+
+    ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+    if (ret == 0) {
+	/* Let objects up get bound up to the size where only 2 would fit in
+	 * the aperture, but then leave slop to account for alignment like
+	 * libdrm does.
+	 */
+	pI830->max_gtt_map_size = aperture.aper_available_size * 3 / 4 / 2;
+    }
+}
commit 34660fd2df5d61b77ed7041d32ac29053fc94f5a
Author: Eric Anholt <eric at anholt.net>
Date:   Fri May 15 23:21:05 2009 -0700

    Only sync XV to vblank when drawing to the frontbuffer.
    
    This fixes emitting syncs to random pipes with boxes bigger than that
    pipe's vertical, leading to GPU hangs.
    
    Bug #21738

diff --git a/src/i830_video.c b/src/i830_video.c
index 1c3a5b7..6fec8ff 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2495,13 +2495,15 @@ I830PutImage(ScrnInfoPtr pScrn,
         if (sync) {
 	    BoxPtr box;
 	    int y1, y2;
-            int pipe, event, load_scan_lines_pipe;
-
-	    if (pI830->use_drm_mode)
-		pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
-	    else {
-		I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
-		pipe = intel_crtc->pipe;
+	    int pipe = -1, event, load_scan_lines_pipe;
+
+	    if (pPixmap != pScreen->GetScreenPixmap(pScreen)) {
+		if (pI830->use_drm_mode)
+		    pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
+		else {
+		    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+		    pipe = intel_crtc->pipe;
+		}
 	    }
 
 	    if (pipe >= 0) {


More information about the xorg-commit mailing list