xf86-video-intel: 3 commits - src/sna/sna_accel.c src/sna/sna_display.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Jun 22 09:57:57 PDT 2014


 src/sna/sna_accel.c   |   13 +++++++++---
 src/sna/sna_display.c |   54 +++++++++++++++++++++++++++-----------------------
 2 files changed, 40 insertions(+), 27 deletions(-)

New commits:
commit dca0f1c2ccf14df38764ed12b971dc491cf22608
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jun 22 17:53:59 2014 +0100

    sna: Track CRTC mode changes and discard old flips
    
    If we have a pending flip across a modeset we must be careful to drop
    the stale flip_bo after the modeset.
    
    Reported-by: Sree Harsha Totakura <freedesktop at h.totakura.in>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=80355#c8
    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 91ec2cd..0cee970 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -121,6 +121,8 @@ struct sna_crtc {
 		uint32_t current;
 	} primary_rotation, sprite_rotation;
 
+	uint32_t mode_serial, flip_serial;
+
 	uint32_t last_seq, wrap_seq;
 	struct ust_msc swap;
 
@@ -969,7 +971,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 
 	DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->bo->handle));
 
-	assert(config->num_output < ARRAY_SIZE(output_ids));
+	assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
 
 	if (!rotation_set(sna, &sna_crtc->primary_rotation, sna_crtc->rotation)) {
 		ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
@@ -979,7 +981,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n",
 	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation));
 
-	for (i = 0; i < config->num_output; i++) {
+	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 
 		/* Make sure we mark the output as off (and save the backlight)
@@ -1038,6 +1040,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
 		return false;
 
+	sna_crtc->mode_serial++;
 	sna_crtc_force_outputs_on(crtc);
 	return true;
 }
@@ -1398,6 +1401,8 @@ sna_crtc_disable(xf86CrtcPtr crtc)
 	arg.crtc_id = sna_crtc->id;
 	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
 
+	sna_crtc->mode_serial++;
+
 	rotation_set(sna, &sna_crtc->primary_rotation, RR_Rotate_0);
 
 	sna_crtc_disable_shadow(sna, sna_crtc);
@@ -1927,10 +1932,11 @@ sna_crtc_damage(xf86CrtcPtr crtc)
 
 static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max)
 {
+	struct sna *sna = to_sna(crtc->scrn);
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	int len, i;
 
-	for (i = len = 0; i < config->num_output; i++) {
+	for (i = len = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 
 		if (output->crtc != crtc)
@@ -4563,9 +4569,9 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x,
 
 	DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, crtc->id, crtc->pipe, bo->handle));
 
-	assert(config->num_output < ARRAY_SIZE(output_ids));
+	assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
 
-	for (i = 0; i < config->num_output; i++) {
+	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 
 		if (output->crtc != crtc->base)
@@ -4713,6 +4719,7 @@ fixup_flip:
 			crtc->flip_data = data;
 			crtc->flip_bo = kgem_bo_reference(bo);
 			crtc->flip_bo->active_scanout++;
+			crtc->flip_serial = crtc->mode_serial;
 			sna->mode.flip_active++;
 		}
 
@@ -4919,7 +4926,7 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 	}
 
 	/* First scan through all outputs and look for user overrides */
-	for (i = 0; i < config->num_output; i++) {
+	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 
 		for (j = 0; j < ARRAY_SIZE(user_overrides); j++) {
@@ -4965,14 +4972,11 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 	}
 
 	/* Reconstruct outputs pointing to active CRTC */
-	for (i = 0; i < config->num_output; i++) {
+	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 		uint32_t crtc_id;
 
-		if (to_sna_output(output) == NULL) {
-			assert(output->crtc == NULL);
-			continue;
-		}
+		assert(to_sna_output(output));
 
 		crtc_id = (uintptr_t)output->crtc;
 		output->crtc = NULL;
@@ -6287,6 +6291,7 @@ disable1:
 				sna_crtc->flip_handler = shadow_flip_handler;
 				sna_crtc->flip_bo = bo;
 				sna_crtc->flip_bo->active_scanout++;
+				sna_crtc->flip_serial = sna_crtc->mode_serial;
 
 				sna_crtc->shadow_bo = kgem_bo_reference(sna_crtc->bo);
 			} else {
@@ -6414,6 +6419,7 @@ fixup_flip:
 			crtc->flip_handler = shadow_flip_handler;
 			crtc->flip_bo = kgem_bo_reference(flip_bo);
 			crtc->flip_bo->active_scanout++;
+			crtc->flip_serial = crtc->mode_serial;
 
 			{
 				struct drm_i915_gem_busy busy = { flip_bo->handle };
@@ -6483,7 +6489,7 @@ void sna_mode_wakeup(struct sna *sna)
 				assert(crtc->flip_bo->active_scanout);
 				assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout);
 
-				if (crtc->bo) {
+				if (crtc->flip_serial == crtc->mode_serial) {
 					DBG(("%s: removing handle=%d from scanout, installing handle=%d\n",
 					     __FUNCTION__, crtc->bo->handle, crtc->flip_bo->handle));
 					assert(crtc->bo->active_scanout);
commit dae370423ad85b9d9c576277da5a9fb92ab3d3df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jun 22 11:45:35 2014 +0100

    sna: Clean up CRTC on CloseScreen
    
    We need to do this to stop any stray references escaping through kernel
    events now that we are passing the CRTC through the event.
    
    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 305bccf..91ec2cd 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -203,6 +203,10 @@ static inline bool event_pending(int fd)
 
 static bool sna_mode_has_pending_events(struct sna *sna)
 {
+	/* In order to workaround a kernel bug in not honouring O_NONBLOCK,
+	 * check that the fd is readable before attempting to read the next
+	 * event from drm.
+	 */
 	return event_pending(sna->kgem.fd);
 }
 
@@ -5266,26 +5270,18 @@ sna_mode_wants_tear_free(struct sna *sna)
 void
 sna_mode_close(struct sna *sna)
 {
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
-	int i;
-
-	/* In order to workaround a kernel bug in not honouring O_NONBLOCK,
-	 * check that the fd is readable before attempting to read the next
-	 * event from drm.
-	 */
 	while (sna_mode_has_pending_events(sna))
 		sna_mode_wakeup(sna);
 
 	if (sna->flags & SNA_IS_HOSTED)
 		return;
 
-	sna_backlight_close(sna);
-	sna_cursor_close(sna);
-
-	for (i = 0; i < sna->mode.num_real_crtc; i++)
-		sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i]));
+	sna_mode_reset(sna);
 
+	sna_cursor_close(sna);
 	sna_cursors_fini(sna);
+
+	sna_backlight_close(sna);
 }
 
 void
@@ -5801,6 +5797,10 @@ void sna_mode_reset(struct sna *sna)
 		sna_output_backlight_set(sna_output,
 					 sna_output->backlight.max);
 	}
+
+	/* drain the event queue */
+	while (sna_mode_has_pending_events(sna))
+		sna_mode_wakeup(sna);
 }
 
 static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
commit 923dc207df7b05c138c628983ccaf2493dd63b62
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 19 10:17:11 2014 +0100

    sna: Discard write hint from a couple more move-to-gpu
    
    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 27bbc06..78f5fed 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -481,8 +481,10 @@ static void sna_pixmap_free_gpu(struct sna *sna, struct sna_pixmap *priv)
 		sna_pixmap_undo_cow(sna, priv, MOVE_WRITE);
 	assert(priv->cow == NULL);
 
-	if (priv->move_to_gpu)
+	if (priv->move_to_gpu) {
+		sna_pixmap_discard_shadow_damage(priv, NULL);
 		priv->move_to_gpu(sna, priv, MOVE_WRITE);
+	}
 
 	sna_damage_destroy(&priv->gpu_damage);
 	priv->clear = false;
@@ -3170,13 +3172,18 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 	if (priv->move_to_gpu) {
 		unsigned int hint;
 
-		hint = flags | MOVE_READ | (priv->cpu_damage ? MOVE_WRITE : 0);
+		hint = flags | MOVE_READ;
 		if ((flags & MOVE_READ) == 0) {
 			RegionRec region;
 
 			region.extents = *box;
 			region.data = NULL;
 			sna_pixmap_discard_shadow_damage(priv, &region);
+			if (region_subsumes_pixmap(&region, pixmap))
+				hint &= ~MOVE_READ;
+		} else {
+			if (priv->cpu_damage)
+				hint |= MOVE_WRITE;
 		}
 		if (!priv->move_to_gpu(sna, priv, hint)) {
 			DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
@@ -3947,7 +3954,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 	assert_pixmap_damage(pixmap);
 
 	if (priv->move_to_gpu &&
-	    !priv->move_to_gpu(sna, priv, flags | (priv->cpu_damage ? MOVE_WRITE : 0))) {
+	    !priv->move_to_gpu(sna, priv, flags | ((priv->cpu_damage && (flags & MOVE_READ)) ? MOVE_WRITE : 0))) {
 		DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
 		return NULL;
 	}


More information about the xorg-commit mailing list