xf86-video-intel: 4 commits - src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna.h src/sna/sna_present.c src/uxa/intel_present.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Feb 5 00:50:44 PST 2015


 src/sna/sna.h           |    1 +
 src/sna/sna_accel.c     |    3 ++-
 src/sna/sna_display.c   |   36 +++++++++++++++++++++++++-----------
 src/sna/sna_present.c   |   35 ++++++++++++++++++++++++++++++-----
 src/uxa/intel_present.c |   24 ++++++++++++++----------
 5 files changed, 72 insertions(+), 27 deletions(-)

New commits:
commit ca71ee06851058b86405c677c204790d0fb94e36
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 5 08:40:01 2015 +0000

    uxa/present: Do not allow the unflip to fail
    
    As we cannot propagate the failure for unflipping back to the caller, we
    must ensure that the CRTCs are correctly reset if the attempt to flip
    back to normality fails.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/uxa/intel_present.c b/src/uxa/intel_present.c
index d20043f..2e57e7a 100644
--- a/src/uxa/intel_present.c
+++ b/src/uxa/intel_present.c
@@ -343,29 +343,33 @@ intel_present_unflip(ScreenPtr screen, uint64_t event_id)
 {
 	ScrnInfoPtr                             scrn = xf86ScreenToScrn(screen);
 	intel_screen_private                    *intel = intel_get_screen_private(scrn);
-	struct intel_present_vblank_event       *event;
 	PixmapPtr                               pixmap = screen->GetScreenPixmap(screen);
+	struct intel_present_vblank_event       *event = NULL;
 	dri_bo                                  *bo;
-	Bool                                    ret;
 
 	if (!intel_present_check_flip(NULL, screen->root, pixmap, true))
-		return;
+		goto fail;
 
 	bo = intel_get_pixmap_bo(pixmap);
 	if (!bo)
-		return;
+		goto fail;
 
 	event = calloc(1, sizeof(struct intel_present_vblank_event));
 	if (!event)
-		return;
+		goto fail;
 
 	event->event_id = event_id;
 
-	ret = intel_do_pageflip(intel, bo, -1, FALSE, event, intel_present_flip_event, intel_present_flip_abort);
-	if (!ret) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "present unflip failed\n");
-	}
+	if (intel_do_pageflip(intel, bo, -1, FALSE, event,
+			      intel_present_flip_event,
+			      intel_present_flip_abort))
+		goto fail;
+
+	return;
+fail:
+	xf86SetDesiredModes(scrn);
+	present_event_notify(event_id, 0, 0);
+	free(event);
 }
 
 static present_screen_info_rec intel_present_screen_info = {
commit cec34132a7884a5b5b02bae0096b560f522fffb8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Feb 4 22:02:37 2015 +0000

    sna: Add some DBG for why a DoCopy might be skipped
    
    This captures a bug in transitioning from gdm to gnome-shell where the
    present_unflip copy back onto the Screen Pixmap fails.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c11ddee..b4115d7 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -6953,7 +6953,8 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 	/* Short cut for unmapped windows */
 	if (dst->type == DRAWABLE_WINDOW && !((WindowPtr)dst)->realized) {
-		DBG(("%s: unmapped\n", __FUNCTION__));
+		DBG(("%s: unmapped/unrealized dst (pixmap=%ld)\n",
+		     __FUNCTION__, get_window_pixmap((WindowPtr)dst)));
 		return NULL;
 	}
 
commit 7dd16e56841e4b79eab88df06938f7766d8b7206
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 5 08:12:56 2015 +0000

    sna: Clear the resized framebuffer if wedged
    
    We always try to make sure the scanout is initialised before use, but if
    the GPU is wedged we need to fallback to use the CPU to do the clears.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a37362f..fa2970f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4282,12 +4282,19 @@ static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
 		return;
 
 	if (old_priv->clear) {
-		(void)sna->render.fill_one(sna, new, new_priv->gpu_bo,
-					   old_priv->clear_color,
-					   0, 0,
-					   new->drawable.width,
-					   new->drawable.height,
-					   GXcopy);
+		bool ok = false;
+		if (!wedged(sna))
+			ok = sna->render.fill_one(sna, new, new_priv->gpu_bo,
+						  old_priv->clear_color,
+						  0, 0,
+						  new->drawable.width,
+						  new->drawable.height,
+						  GXcopy);
+		if (!ok) {
+			void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo);
+			if (ptr)
+				memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height);
+		}
 		new_priv->clear = true;
 		new_priv->clear_color = old_priv->clear_color;
 	} else {
@@ -4343,11 +4350,18 @@ static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
 			     __FUNCTION__, box.x2, box.y2, sx, sy, dx, dy));
 
 			if (box.x2 != new->drawable.width || box.y2 != new->drawable.height) {
-				(void)sna->render.fill_one(sna, new, new_priv->gpu_bo, 0,
-							   0, 0,
-							   new->drawable.width,
-							   new->drawable.height,
-							   GXclear);
+				bool ok = false;
+				if (!wedged(sna))
+					ok = sna->render.fill_one(sna, new, new_priv->gpu_bo, 0,
+								  0, 0,
+								  new->drawable.width,
+								  new->drawable.height,
+								  GXclear);
+				if (!ok) {
+					void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo);
+					if (ptr)
+						memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height);
+				}
 			}
 			(void)sna->render.copy_boxes(sna, GXcopy,
 						     &old->drawable, old_priv->gpu_bo, sx, sy,
commit f93aab9bbc3ecc64533a2eb646b7a6209ddd492f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 5 07:55:08 2015 +0000

    sna/present: Queue the unflip if we have flips outstanding
    
    Rather than synchronously wait in the unflip for the pageflips to complete
    by forcing the modeset, try to queue the unflip to happen after the pending
    flip completes.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 74a03f3..3f01d55 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -354,6 +354,7 @@ struct sna {
 		bool available;
 		bool open;
 #if HAVE_PRESENT
+		uint64_t unflip;
 #endif
 	} present;
 
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 035a54b..90d08b5 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -42,6 +42,8 @@ struct sna_present_event {
 	xf86CrtcPtr crtc;
 };
 
+static void sna_present_unflip(ScreenPtr screen, uint64_t event_id);
+
 static inline struct sna_present_event *
 to_present_event(uintptr_t  data)
 {
@@ -201,11 +203,21 @@ check_flip__crtc(struct sna *sna,
 
 	assert(sna->scrn->vtSema);
 
+	if (!sna->mode.front_active) {
+		DBG(("%s: DPMS off, no flips\n", __FUNCTION__));
+		return FALSE;
+	}
+
 	if (sna->mode.shadow_active) {
 		DBG(("%s: shadow buffer active\n", __FUNCTION__));
 		return false;
 	}
 
+	if (sna->mode.flip_active) {
+		DBG(("%s: flips still pending\n", __FUNCTION__));
+		return false;
+	}
+
 	return true;
 }
 
@@ -229,11 +241,6 @@ sna_present_check_flip(RRCrtcPtr crtc,
 		return FALSE;
 	}
 
-	if (!sna->mode.front_active) {
-		DBG(("%s: DPMS off, no flips\n", __FUNCTION__));
-		return FALSE;
-	}
-
 	if (sna->flags & SNA_NO_FLIP) {
 		DBG(("%s: flips not suported\n", __FUNCTION__));
 		return FALSE;
@@ -312,6 +319,7 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
 {
 	struct sna_present_event *info = data;
 	struct ust_msc swap;
+	struct sna *sna;
 
 	DBG(("%s(sequence=%d)\n", __FUNCTION__, event->sequence));
 
@@ -327,6 +335,14 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
 	     swap.tv_sec, swap.tv_usec, (long long)swap.msc,
 	     (long long)info->event_id));
 	present_event_notify(info->event_id, ust64(swap.tv_sec, swap.tv_usec), swap.msc);
+
+	sna = info->crtc ? to_sna(info->crtc->scrn) : NULL;
+	if (sna && sna->present.unflip) {
+		DBG(("%s: executing queued unflip\n", __FUNCTION__));
+		sna_present_unflip(xf86ScrnToScreen(sna->scrn),
+				   sna->present.unflip);
+		sna->present.unflip = 0;
+	}
 	free(info);
 }
 
@@ -412,6 +428,8 @@ sna_present_flip(RRCrtcPtr crtc,
 		return FALSE;
 	}
 
+	assert(to_sna_from_pixmap(pixmap)->present.unflip == 0);
+
 	bo = get_flip_bo(pixmap);
 	if (bo == NULL) {
 		DBG(("%s: flip invalid bo\n", __FUNCTION__));
@@ -448,6 +466,13 @@ notify:
 		return;
 	}
 
+	if (sna->mode.flip_active) {
+		DBG(("%s: outstanding flips, queueing unflip\n", __FUNCTION__));
+		assert(sna->present.unflip == 0);
+		sna->present.unflip = event_id;
+		return;
+	}
+
 	bo = get_flip_bo(screen->GetScreenPixmap(screen));
 	if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) {
 		DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__));


More information about the xorg-commit mailing list