xf86-video-intel: 7 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_present.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jan 9 08:49:27 PST 2015


 src/sna/kgem.c        |    2 -
 src/sna/sna.h         |    1 
 src/sna/sna_accel.c   |   52 ++++++++++++++++++++++++++++++--------
 src/sna/sna_display.c |   23 ++++++++++++++++-
 src/sna/sna_driver.c  |   67 +++++++++++++++++++++++++++++++++++++++-----------
 src/sna/sna_present.c |   10 +++++++
 6 files changed, 128 insertions(+), 27 deletions(-)

New commits:
commit 05ca3bc1cb068567c2fd1321e89a438d7648cc38
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 9 16:47:54 2015 +0000

    sna: Wrap mmap accessors with sigtrap to catch oom SIGBUS
    
    Accessing a mmap'ed pointer (especially our shmemfs backed bo) can throw
    SIGBUS when out of memory, for which we use sigtrap for graceful
    failure.
    
    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 f1c028c..45f744c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -6108,6 +6108,9 @@ sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
 
 	kgem_bo_sync__cpu_full(&sna->kgem, src_priv->gpu_bo, FORCE_FULL_SYNC);
 
+	if (sigtrap_get())
+		return false;
+
 	box = region_rects(region);
 	n = region_num_rects(region);
 	if (src_priv->gpu_bo->tiling) {
@@ -6147,6 +6150,8 @@ sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
 		}
 	}
 
+	sigtrap_put();
+
 	return true;
 
 upload_inplace:
@@ -6244,6 +6249,9 @@ upload_inplace:
 
 	assert(has_coherent_ptr(sna, src_priv, MOVE_READ));
 
+	if (sigtrap_get())
+		return false;
+
 	box = region_rects(region);
 	n = region_num_rects(region);
 	if (dst_priv->gpu_bo->tiling) {
@@ -6286,6 +6294,8 @@ upload_inplace:
 		}
 	}
 
+	sigtrap_put();
+
 	return true;
 }
 
commit e0463036bbd4e5f0201e122f9b29dd776ba4446f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 9 16:45:32 2015 +0000

    sna: Replace assert with conditional setting of sna_pixmap->mapped
    
    The status of sna_pixmap->mapped was changed with the introduction of
    mmap(wc), but the code was still asserting that the mmap could only be
    cached.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=88112#c20
    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 bc93674..f1c028c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4873,6 +4873,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
 	pixmap->devPrivate.ptr = dst;
 	pixmap->devKind = priv->gpu_bo->pitch;
 	priv->mapped = dst == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT;
+	priv->cpu &= priv->mapped == MAPPED_CPU;
 	assert(has_coherent_ptr(sna, priv, MOVE_WRITE));
 
 	box = region_rects(region);
@@ -6274,12 +6275,14 @@ upload_inplace:
 		} while (--n);
 
 		if (!dst_priv->shm) {
-			assert(ptr == MAP(dst_priv->gpu_bo->map__cpu));
 			dst_pixmap->devPrivate.ptr = ptr;
 			dst_pixmap->devKind = dst_priv->gpu_bo->pitch;
-			dst_priv->mapped = MAPPED_CPU;
+			if (ptr == MAP(dst_priv->gpu_bo->map__cpu)) {
+				dst_priv->mapped = MAPPED_CPU;
+				dst_priv->cpu = true;
+			} else
+				dst_priv->cpu = false;
 			assert_pixmap_map(dst_pixmap, dst_priv);
-			dst_priv->cpu = true;
 		}
 	}
 
@@ -16855,7 +16858,7 @@ sna_get_image__inplace(PixmapPtr pixmap,
 			pixmap->devKind = priv->gpu_bo->pitch;
 			priv->mapped = src == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT;
 			assert_pixmap_map(pixmap, priv);
-			priv->cpu = true;
+			priv->cpu &= priv->mapped == MAPPED_CPU;
 		}
 	}
 
commit d49e6ad6ef93c9f91a0c6265d9e827b2c5b0c30d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 9 14:28:25 2015 +0000

    sna: Add a couple of guards against using the GPU to write into snooped bo
    
    Since gen2 cannot rendering into a snooped bo, we have to be careful
    before trusting the CPU bo as a GPU target.
    
    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 0de83db..bc93674 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2336,6 +2336,7 @@ skip_inplace_map:
 
 			if (priv->cpu_bo) {
 				if ((flags & MOVE_ASYNC_HINT || priv->cpu_bo->exec) &&
+				    sna->kgem.can_blt_cpu &&
 				    sna->render.fill_one(sna,
 							  pixmap, priv->cpu_bo, priv->clear_color,
 							  0, 0,
@@ -2536,6 +2537,9 @@ static bool cpu_clear_boxes(struct sna *sna,
 {
 	struct sna_fill_op fill;
 
+	if (!sna->kgem.can_blt_cpu)
+		return false;
+
 	if (!sna_fill_init_blt(&fill, sna,
 			       pixmap, priv->cpu_bo,
 			       GXcopy, priv->clear_color,
commit 3d85fa8027e5fb2a607521d2e28648fb4d63a598
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 9 13:44:15 2015 +0000

    sna: Capitlize log message "display hotplut detection"
    
    It looks out of place starting with a lower case letter when the
    surrounding messages are sentence captilized.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index dcd74ec..59abc03 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -899,7 +899,8 @@ sna_uevent_init(struct sna *sna)
 
 	sna->uevent_monitor = mon;
 out:
-	xf86DrvMsg(sna->scrn->scrnIndex, from, "display hotplug detection %s\n",
+	xf86DrvMsg(sna->scrn->scrnIndex, from,
+		   "Display hotplug detection %s\n",
 		   sna->uevent_monitor ? "enabled" : "disabled");
 	return;
 
commit e53087e48b5a9fe795be120ca72e465ca470ccc9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jan 8 14:27:35 2015 +0000

    sna: Allow use of mmap(wc) for inplace GetImage
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index aba6881..fb6a289 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -6314,7 +6314,6 @@ void *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo)
 	     bo->handle, (long)bo->presumed_offset, bo->tiling, bo->map__gtt, bo->map__cpu, bo->domain));
 
 	assert(bo->proxy == NULL);
-	assert(bo->exec == NULL);
 	assert(list_is_empty(&bo->list));
 	assert_tiling(kgem, bo);
 	assert(!bo->purged || bo->reusable);
@@ -6322,6 +6321,7 @@ void *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo)
 	if (bo->map__wc)
 		return bo->map__wc;
 
+	kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
 	return __kgem_bo_map__wc(kgem, bo);
 }
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 75c17f9..0de83db 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -16794,7 +16794,8 @@ sna_get_image__inplace(PixmapPtr pixmap,
 		break;
 	}
 
-	if (!kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC))
+	if ((flags & MOVE_INPLACE_HINT) == 0 &&
+	    !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC))
 		return false;
 
 	if (idle && __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
@@ -16806,11 +16807,19 @@ sna_get_image__inplace(PixmapPtr pixmap,
 	assert(sna_damage_contains_box(&priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
 	assert(sna_damage_contains_box(&priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
 
-	src = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
-	if (src == NULL)
-		return false;
+	if (kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC)) {
+		src = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
+		if (src == NULL)
+			return false;
 
-	kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC);
+		kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC);
+	} else {
+		src = kgem_bo_map__wc(&sna->kgem, priv->gpu_bo);
+		if (src == NULL)
+			return false;
+
+		kgem_bo_sync__gtt(&sna->kgem, priv->gpu_bo);
+	}
 
 	if (sigtrap_get())
 		return false;
@@ -16838,10 +16847,9 @@ sna_get_image__inplace(PixmapPtr pixmap,
 			   region->extents.x2 - region->extents.x1,
 			   region->extents.y2 - region->extents.y1);
 		if (!priv->shm) {
-			assert(src == MAP(priv->gpu_bo->map__cpu));
 			pixmap->devPrivate.ptr = src;
 			pixmap->devKind = priv->gpu_bo->pitch;
-			priv->mapped = MAPPED_CPU;
+			priv->mapped = src == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT;
 			assert_pixmap_map(pixmap, priv);
 			priv->cpu = true;
 		}
commit bc59d3fc76047bcdd20e9750591e06227b9cf39e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 7 19:44:12 2015 +0000

    sna: Differentiate between disabling CRTC and turning off DPMS
    
    xf86DisableUnusedFunctions() uses crtc->dpms(off) to disable unused
    pipes. In this case, we do want to explicitly disable the CRTC to
    release any shared state (e.g. PLLs and encoders). However, the user can
    also request for the DPMS to be disabled, either via the DPMS extension
    or the ScreenSaver. Here, we don't want to full disable the pipe as that
    incurs extra latency (and risk of failure) when switching the display
    back on. In order to distinguish the two cases, we can hook into the
    user paths and skip disabling the CRTCs.
    
    Suggested-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 18425e3..7a1bf34 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -286,6 +286,7 @@ struct sna {
 		unsigned shadow_active;
 		unsigned flip_active;
 		bool dirty;
+		bool hidden;
 
 		int max_crtc_width, max_crtc_height;
 		RegionRec shadow_region;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5f6bc42..cf871bc 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -537,6 +537,7 @@ sna_backlight_uevent(int fd, void *closure)
 					       TRUE, FALSE);
 		}
 	}
+	DBG(("%s: complete\n", __FUNCTION__));
 }
 
 static void sna_backlight_pre_init(struct sna *sna)
@@ -584,6 +585,7 @@ static void sna_backlight_drain_uevents(struct sna *sna)
 	if (sna->mode.backlight_monitor == NULL)
 		return;
 
+	DBG(("%s()\n", __FUNCTION__));
 	sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor),
 			     sna);
 }
@@ -4108,6 +4110,8 @@ static bool disable_unused_crtc(struct sna *sna)
 	bool update = false;
 	int o, c;
 
+	DBG(("%s\n", __FUNCTION__));
+
 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
 		xf86CrtcPtr crtc = config->crtc[c];
 
@@ -6029,6 +6033,11 @@ sna_mode_enable(struct sna *sna)
 	if (!sna->scrn->vtSema)
 		return;
 
+	if (sna->mode.hidden) {
+		DBG(("%s: hidden outputs\n", __FUNCTION__));
+		return;
+	}
+
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
 		xf86CrtcPtr crtc = config->crtc[i];
 
@@ -6112,8 +6121,15 @@ sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired)
 		return NULL;
 
 	/* If we do not own the VT, we do not own the CRTC either */
-	if (!sna->scrn->vtSema)
+	if (!sna->scrn->vtSema) {
+		DBG(("%s: none, VT switched\n", __FUNCTION__));
 		return NULL;
+	}
+
+	if (sna->mode.hidden) {
+		DBG(("%s: none, hidden outputs\n", __FUNCTION__));
+		return NULL;
+	}
 
 	DBG(("%s for box=(%d, %d), (%d, %d)\n",
 	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2));
@@ -7016,6 +7032,11 @@ void sna_mode_redisplay(struct sna *sna)
 	RegionPtr region;
 	int i;
 
+	if (sna->mode.hidden) {
+		DBG(("%s: hidden outputs, skipping\n", __FUNCTION__));
+		return;
+	}
+
 	if (!sna->mode.shadow_damage)
 		return;
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 8a3599c..dcd74ec 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -279,27 +279,65 @@ static Bool sna_create_screen_resources(ScreenPtr screen)
 	return TRUE;
 }
 
-static Bool sna_save_screen(ScreenPtr screen, int mode)
+static void sna_dpms_set(ScrnInfoPtr scrn, int mode, int flags)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+	int i;
 
-	DBG(("%s(mode=%d)\n", __FUNCTION__, mode));
+	DBG(("%s(mode=%d, flags=%d), vtSema=%d\n",
+	     __FUNCTION__, mode, flags, scrn->vtSema));
 	if (!scrn->vtSema)
-		return FALSE;
+		return;
 
-	xf86SaveScreen(screen, mode);
-	sna_crtc_config_notify(screen);
-	return TRUE;
+	/* Opencoded version of xf86DPMSSet().
+	 *
+	 * The principle difference is to skip calling crtc->dpms() when
+	 * turning off the display. This (on recent enough kernels at
+	 * least) should be equivalent in power consumption, but require
+	 * less work (hence quicker and less likely to fail) when switching
+	 * back on.
+	 */
+	if (mode == DPMSModeOff) {
+		for (i = 0; i < config->num_output; i++) {
+			xf86OutputPtr output = config->output[i];
+			if (output->crtc != NULL)
+				output->funcs->dpms(output, mode);
+		}
+	} else {
+		/* Re-enable CRTC that have been forced off via other means */
+		for (i = 0; i < config->num_crtc; i++) {
+			xf86CrtcPtr crtc = config->crtc[i];
+			if (crtc->enabled)
+				crtc->funcs->dpms(crtc, mode);
+		}
+
+		for (i = 0; i < config->num_output; i++) {
+			xf86OutputPtr output = config->output[i];
+			if (output->crtc != NULL)
+				output->funcs->dpms(output, mode);
+		}
+	}
+
+	sna_crtc_config_notify(xf86ScrnToScreen(scrn));
+	to_sna(scrn)->mode.hidden = mode == DPMSModeOff;
+	DBG(("%s: hiding outputs? %d\n", __FUNCTION__, to_sna(scrn)->mode.hidden));
 }
 
-static void sna_dpms_set(ScrnInfoPtr scrn, int mode, int flags)
+static Bool sna_save_screen(ScreenPtr screen, int mode)
 {
-	DBG(("%s(mode=%d, flags=%d)\n", __FUNCTION__, mode));
-	if (!scrn->vtSema)
-		return;
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 
-	xf86DPMSSet(scrn, mode, flags);
-	sna_crtc_config_notify(xf86ScrnToScreen(scrn));
+	DBG(("%s(mode=%d [unblank=%d])\n",
+	     __FUNCTION__, mode, xf86IsUnblank(mode)));
+
+	/* We have to unroll xf86SaveScreen() here as it is called
+	 * by DPMSSet() nullifying our special handling crtc->dpms()
+	 * in sna_dpms_set().
+	 */
+	sna_dpms_set(scrn,
+		     xf86IsUnblank(mode) ? DPMSModeOn : DPMSModeOff,
+		     0);
+	return TRUE;
 }
 
 static void sna_selftest(void)
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 6dd6fe8..81cf669 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -224,6 +224,16 @@ sna_present_check_flip(RRCrtcPtr crtc,
 	     pixmap->drawable.serialNumber,
 	     sync_flip));
 
+	if (!sna->scrn->vtSema) {
+		DBG(("%s: VT switched away, no flips\n", __FUNCTION__));
+		return FALSE;
+	}
+
+	if (sna->mode.hidden) {
+		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;
commit 574ab948af15c8deaf5afa11bd79b2ea2d9c202d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 7 14:08:05 2015 +0000

    sna: Add mmap(wc) handling to has_coherent_ptr assertion
    
    Extend the debuging sanity checks to also cover WC mappings.
    
    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 e1a808f..75c17f9 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1557,6 +1557,11 @@ static inline bool has_coherent_ptr(struct sna *sna, struct sna_pixmap *priv, un
 		return true;
 	}
 
+	if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__wc)) {
+		assert(priv->mapped == MAPPED_GTT);
+		return true;
+	}
+
 	return false;
 }
 


More information about the xorg-commit mailing list