xf86-video-intel: 3 commits - src/sna/fb src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri2.c test/dri2-race.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Oct 5 08:24:50 UTC 2016


 src/sna/fb/fbimage.c  |   12 +++++++++---
 src/sna/kgem.c        |   27 ++++++++++++++++-----------
 src/sna/sna_accel.c   |   15 ++++++++++++---
 src/sna/sna_display.c |    5 +++--
 src/sna/sna_dri2.c    |    5 ++++-
 test/dri2-race.c      |   15 +++++++++++++++
 6 files changed, 59 insertions(+), 20 deletions(-)

New commits:
commit bd33d0a7e9801e710b77fd32df90b3cc953045fe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Oct 2 19:05:58 2016 +0100

    sna: Force fb release on tiling changes
    
    Since trying to change tiling with an fb attached causes EBUSY, try
    without.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index c957bbf..20ca9b9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -443,6 +443,19 @@ static void kgem_sna_flush(struct kgem *kgem)
 		sna_render_flush_solid(sna);
 }
 
+static bool kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo)
+{
+	if (bo->scanout && bo->delta) {
+		DBG(("%s: releasing fb=%d for handle=%d\n",
+		     __FUNCTION__, bo->delta, bo->handle));
+		/* XXX will leak if we are not DRM_MASTER. *shrug* */
+		do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
+		bo->delta = 0;
+		return true;
+	} else
+		return false;
+}
+
 static bool kgem_set_tiling(struct kgem *kgem, struct kgem_bo *bo,
 			    int tiling, int stride)
 {
@@ -487,6 +500,9 @@ restart:
 		goto restart;
 	}
 
+	if (err == EBUSY && kgem_bo_rmfb(kgem, bo))
+		goto restart;
+
 	ERR(("%s: failed to set-tiling(tiling=%d, pitch=%d) for handle=%d: %d\n",
 	     __FUNCTION__, tiling, stride, bo->handle, err));
 	return false;
@@ -2517,17 +2533,6 @@ static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
 	}
 }
 
-static void kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo)
-{
-	if (bo->scanout && bo->delta) {
-		DBG(("%s: releasing fb=%d for handle=%d\n",
-		     __FUNCTION__, bo->delta, bo->handle));
-		/* XXX will leak if we are not DRM_MASTER. *shrug* */
-		do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
-		bo->delta = 0;
-	}
-}
-
 static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
 {
 	DBG(("%s: handle=%d, size=%d\n", __FUNCTION__, bo->handle, bytes(bo)));
commit d9a32dc657d6359d19427f5c610be54d15ebb1a9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Oct 2 15:24:02 2016 +0100

    sna/dri2: Assert signal is unset before setting
    
    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 cde4ca2..43fe4db 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1540,7 +1540,8 @@ static void defer_event(struct sna *sna, struct drm_event *base)
 
 	memcpy(&sna->mode.shadow_events[sna->mode.shadow_nevent++],
 	       base, sizeof(struct drm_event_vblank));
-	DBG(("%s: deferring event count=%d\n", sna->mode.shadow_nevent));
+	DBG(("%s: deferring event count=%d\n",
+	     __func__, sna->mode.shadow_nevent));
 }
 
 static void flush_events(struct sna *sna)
@@ -1550,7 +1551,7 @@ static void flush_events(struct sna *sna)
 	if (!sna->mode.shadow_nevent)
 		return;
 
-	DBG(("%s: flushing %d events=%d\n", sna->mode.shadow_nevent));
+	DBG(("%s: flushing %d events=%d\n", __func__, sna->mode.shadow_nevent));
 
 	for (n = 0; n < sna->mode.shadow_nevent; n++) {
 		struct drm_event_vblank *vb = &sna->mode.shadow_events[n];
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 0c697dd..72cb128 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -2697,6 +2697,7 @@ void sna_dri2_vblank_handler(struct drm_event_vblank *event)
 			     get_private(info->front)->bo->handle, info->front->name, get_private(info->front)->bo->active_scanout));
 
 			assert(info->draw);
+			assert(!info->signal);
 			info->keepalive++;
 			info->signal = true;
 		}
@@ -2847,6 +2848,9 @@ sna_dri2_flip_continue(struct sna_dri2_event *info)
 	if (info->draw == NULL)
 		return false;
 
+	assert(!info->signal);
+	info->signal = info->type == FLIP_THROTTLE;
+
 	if (info->sna->mode.front_active == 0)
 		return false;
 
@@ -2863,7 +2867,6 @@ sna_dri2_flip_continue(struct sna_dri2_event *info)
 	info->sna->dri2.flip_pending = info;
 	info->queued = true;
 	assert(info->draw);
-	info->signal = info->type == FLIP_THROTTLE;
 
 	return true;
 }
diff --git a/test/dri2-race.c b/test/dri2-race.c
index 79dc9c4..ece624f 100644
--- a/test/dri2-race.c
+++ b/test/dri2-race.c
@@ -144,6 +144,7 @@ static void race_window(Display *dpy, int width, int height,
 	for (n = 0; n < N_DIVISORS; n++) {
 		loop = 256 >> ffs(divisors[n]);
 		printf("DRI2SwapBuffers(divisor=%d), loop=%d", divisors[n], loop);
+		fflush(stdout);
 		do {
 			win = XCreateWindow(dpy, DefaultRootWindow(dpy),
 					0, 0, width, height, 0,
@@ -174,6 +175,7 @@ static void race_window(Display *dpy, int width, int height,
 	for (n = 0; n < N_DIVISORS; n++) {
 		loop = 256 >> ffs(divisors[n]);
 		printf("xcb_dri2_swap_buffers(divisor=%d), loops=%d", divisors[n], loop);
+		fflush(stdout);
 		do {
 			win = XCreateWindow(dpy, DefaultRootWindow(dpy),
 					0, 0, width, height, 0,
@@ -204,6 +206,7 @@ static void race_window(Display *dpy, int width, int height,
 	for (n = 0; n < N_DIVISORS; n++) {
 		loop = 256 >> ffs(divisors[n]);
 		printf("DRI2WaitMsc(divisor=%d), loop=%d", divisors[n], loop);
+		fflush(stdout);
 		do {
 			uint64_t ignore, msc;
 			xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -276,6 +279,7 @@ static void race_resize(Display *dpy, int width, int height,
 
 		loop = 256 >> ffs(divisors[n]);
 		printf("DRI2SwapBuffers(divisor=%d), loop=%d", divisors[n], loop);
+		fflush(stdout);
 		do {
 			int w, h;
 
@@ -310,6 +314,7 @@ static void race_resize(Display *dpy, int width, int height,
 
 		loop = 256 >> ffs(divisors[n]);
 		printf("xcb_dri2_swap_buffers(divisor=%d), loops=%d", divisors[n], loop);
+		fflush(stdout);
 		do {
 			int w, h;
 
@@ -344,6 +349,7 @@ static void race_resize(Display *dpy, int width, int height,
 
 		loop = 256 >> ffs(divisors[n]);
 		printf("DRI2WaitMsc(divisor=%d), loop=%d", divisors[n], loop);
+		fflush(stdout);
 		do {
 			uint64_t ignore, msc;
 			xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -393,6 +399,7 @@ static void race_manager(Display *dpy, int width, int height,
 	attr.override_redirect = 1;
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("DRI2SwapBuffers(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			win = XCreateWindow(dpy, DefaultRootWindow(dpy),
@@ -425,6 +432,7 @@ static void race_manager(Display *dpy, int width, int height,
 
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("xcb_dri2_swap_buffers(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			win = XCreateWindow(dpy, DefaultRootWindow(dpy),
@@ -457,6 +465,7 @@ static void race_manager(Display *dpy, int width, int height,
 
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("DRI2WaitMsc(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			uint64_t ignore, msc;
@@ -518,6 +527,7 @@ static void race_close(int width, int height,
 	attr.override_redirect = 1;
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("DRI2SwapBuffers(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			Display *dpy = XOpenDisplay(NULL);
@@ -547,6 +557,7 @@ static void race_close(int width, int height,
 
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("xcb_dri2_swap_buffers(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			Display *dpy = XOpenDisplay(NULL);
@@ -576,6 +587,7 @@ static void race_close(int width, int height,
 
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("DRI2WaitMsc(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			uint64_t ignore, msc;
@@ -629,6 +641,7 @@ static void race_client(int width, int height,
 	attr.override_redirect = 1;
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("DRI2SwapBuffers(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			Display *dpy = XOpenDisplay(NULL);
@@ -672,6 +685,7 @@ static void race_client(int width, int height,
 
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("xcb_dri2_swap_buffers(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			Display *dpy = XOpenDisplay(NULL);
@@ -715,6 +729,7 @@ static void race_client(int width, int height,
 
 	for (n = 0; n < N_DIVISORS; n++) {
 		printf("DRI2WaitMsc(divisor=%d)", divisors[n]);
+		fflush(stdout);
 		loop = 256 >> ffs(divisors[n]);
 		do {
 			Display *dpy = XOpenDisplay(NULL);
commit 2579d34713033c75deed3628a50dfcb164028310
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Sep 28 18:26:42 2016 +0100

    sna: Handle GetImage planemask inplace
    
    As found by Adam Jackson, we can perform the masking of the planemask on
    the user buffer and so avoid hitting the fallback paths, so long as we
    have no 24bpp Pixmaps.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/fb/fbimage.c b/src/sna/fb/fbimage.c
index 5af2389..cc81c85 100644
--- a/src/sna/fb/fbimage.c
+++ b/src/sna/fb/fbimage.c
@@ -229,13 +229,19 @@ fbGetImage(DrawablePtr drawable,
 		FbBits pm;
 
 		pm = fbReplicatePixel(planeMask, srcBpp);
+
 		dstStride = PixmapBytePad(w, drawable->depth);
-		if (pm != FB_ALLONES)
-			memset(d, 0, dstStride * h);
 		dstStride /= sizeof(FbStip);
+
 		fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride,
 			  (x + srcXoff) * srcBpp,
-			  dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp);
+			  dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp);
+
+		if (pm != FB_ALLONES) {
+			int i = dstStride * h;
+			while (i--)
+				*dst++ &= pm;
+		}
 	} else {
 		dstStride = BitmapBytePad(w) / sizeof(FbStip);
 		fbBltPlane(src + (y + srcYoff) * srcStride,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 3025298..9fe09ff 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -17191,8 +17191,7 @@ sna_get_image(DrawablePtr drawable,
 	if (ACCEL_GET_IMAGE &&
 	    !FORCE_FALLBACK &&
 	    format == ZPixmap &&
-	    drawable->bitsPerPixel >= 8 &&
-	    PM_IS_SOLID(drawable, mask)) {
+	    drawable->bitsPerPixel >= 8) {
 		PixmapPtr pixmap = get_drawable_pixmap(drawable);
 		int16_t dx, dy;
 
@@ -17204,7 +17203,7 @@ sna_get_image(DrawablePtr drawable,
 		region.data = NULL;
 
 		if (sna_get_image__fast(pixmap, &region, dst, flags))
-			return;
+			goto apply_planemask;
 
 		if (!sna_drawable_move_region_to_cpu(&pixmap->drawable,
 						     &region, flags))
@@ -17222,6 +17221,16 @@ sna_get_image(DrawablePtr drawable,
 				   region.extents.x1, region.extents.y1, 0, 0, w, h);
 			sigtrap_put();
 		}
+
+apply_planemask:
+		if (!PM_IS_SOLID(drawable, mask)) {
+			FbStip pm = fbReplicatePixel(mask, drawable->bitsPerPixel);
+			FbStip *d = (FbStip *)dst;
+			int i, n = PixmapBytePad(w, drawable->depth) / sizeof(FbStip) * h;
+
+			for (i = 0; i < n; i++)
+				d[i] &= pm;
+		}
 	} else {
 		region.extents.x1 = x + drawable->x;
 		region.extents.y1 = y + drawable->y;


More information about the xorg-commit mailing list