xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri2.c src/sna/sna_render.c src/sna/sna_render.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 16 01:42:35 PDT 2014


 src/sna/kgem.c        |   13 +++-
 src/sna/sna_accel.c   |    1 
 src/sna/sna_display.c |  145 ++++++++++++++++++++++++++++++++++++++++----------
 src/sna/sna_dri2.c    |  126 ++++++++-----------------------------------
 src/sna/sna_render.c  |   78 ++++++++++++++++++++++++++
 src/sna/sna_render.h  |    7 ++
 6 files changed, 240 insertions(+), 130 deletions(-)

New commits:
commit 6b98f16241c2a4788f3b5fe4c0d956a849d2ac05
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 16 08:26:03 2014 +0100

    sna: Allow TearFree updates to continue even when the GPU is wedged
    
    Even if we cannot render using the GPU, we should still be able to
    request that the outputs be flipped. So try, and only if that fails,
    resort to writing directly into the scanout.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=85058
    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 12221f2..1903b11 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -17436,6 +17436,7 @@ static void sna_scanout_flush(struct sna *sna)
 	sna->kgem.busy = busy;
 
 	if (priv &&
+	    sna->mode.shadow_damage == NULL &&
 	    sna_pixmap_force_to_gpu(priv->pixmap,
 				    MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT))
 		kgem_scanout_flush(&sna->kgem, priv->gpu_bo);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index dd3a69b..f3971c6 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -130,6 +130,8 @@ struct sna_crtc {
 	uint8_t id;
 	uint8_t pipe;
 
+	RegionRec client_damage; /* XXX overlap with shadow damage? */
+
 	uint16_t shadow_bo_width, shadow_bo_height;
 
 	uint32_t rotation;
@@ -2033,7 +2035,7 @@ out_shadow:
 				return NULL;
 			}
 
-			if (sna->mode.shadow == NULL) {
+			if (sna->mode.shadow == NULL && !wedged(sna)) {
 				RegionRec region;
 				struct kgem_bo *shadow;
 
@@ -2181,6 +2183,7 @@ sna_crtc_damage(xf86CrtcPtr crtc)
 	     __FUNCTION__, to_sna_crtc(crtc)->id,
 	     region.extents.x1, region.extents.y1,
 	     region.extents.x2, region.extents.y2));
+	to_sna_crtc(crtc)->client_damage = region;
 
 	assert(sna->mode.shadow_damage && sna->mode.shadow_active);
 	damage = DamageRegion(sna->mode.shadow_damage);
@@ -6569,7 +6572,7 @@ inline static DrawablePtr crtc_source(xf86CrtcPtr crtc, int16_t *sx, int16_t *sy
 		*sy = -crtc->y;
 		return &sna_crtc->slave_pixmap->drawable;
 	} else {
-		DBG(("%s: using Screen pixmap=%ld)\n",
+		DBG(("%s: using Screen pixmap=%ld\n",
 		     __FUNCTION__,
 		     to_sna(crtc->scrn)->front->drawable.serialNumber));
 		*sx = *sy = 0;
@@ -6866,7 +6869,7 @@ void sna_shadow_set_crtc(struct sna *sna,
 }
 
 void sna_shadow_unset_crtc(struct sna *sna,
-			 xf86CrtcPtr crtc)
+			   xf86CrtcPtr crtc)
 {
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 
@@ -6944,8 +6947,82 @@ void sna_mode_redisplay(struct sna *sna)
 			damage.extents = crtc->bounds;
 			damage.data = NULL;
 			RegionIntersect(&damage, &damage, region);
-			if (RegionNotEmpty(&damage))
-				sna_crtc_redisplay__fallback(crtc, &damage, sna_crtc->bo);
+			if (RegionNotEmpty(&damage)) {
+				struct kgem_bo *bo = NULL;
+
+				if (sna->flags & SNA_TEAR_FREE) {
+					RegionRec new_damage;
+
+					RegionNull(&new_damage);
+					RegionCopy(&new_damage, &damage);
+
+					bo = sna_crtc->client_bo;
+					if (bo == NULL) {
+						damage.extents = crtc->bounds;
+						damage.data = NULL;
+						bo = kgem_create_2d(&sna->kgem,
+								crtc->mode.HDisplay,
+								crtc->mode.VDisplay,
+								crtc->scrn->bitsPerPixel,
+								sna_crtc->bo->tiling,
+								CREATE_SCANOUT);
+					} else
+						RegionUnion(&damage, &damage, &sna_crtc->client_damage);
+					sna_crtc->client_damage = new_damage;
+				}
+
+				if (bo == NULL)
+					bo = sna_crtc->bo;
+				sna_crtc_redisplay__fallback(crtc, &damage, bo);
+
+				if (bo != sna_crtc->bo) {
+					struct drm_mode_crtc_page_flip arg;
+
+					arg.crtc_id = sna_crtc->id;
+					arg.fb_id = get_fb(sna, bo,
+							   crtc->mode.HDisplay,
+							   crtc->mode.VDisplay);
+
+					arg.user_data = (uintptr_t)sna_crtc;
+					arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
+					arg.reserved = 0;
+
+					if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
+						if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) {
+							assert(sna_crtc->bo->active_scanout);
+							assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
+							sna_crtc->bo->active_scanout--;
+							kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
+
+							sna_crtc->bo = kgem_bo_reference(bo);
+							sna_crtc->bo->active_scanout++;
+							sna_crtc->client_bo = kgem_bo_reference(bo);
+						} else {
+							DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
+							     __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno));
+							sna->flags &= ~SNA_TEAR_FREE;
+
+							damage.extents = crtc->bounds;
+							damage.data = NULL;
+							sna_crtc_redisplay__fallback(crtc, &damage, sna_crtc->bo);
+
+							kgem_bo_destroy(&sna->kgem, bo);
+							sna_crtc->client_bo = NULL;
+						}
+					} else {
+						sna->mode.flip_active++;
+
+						assert(sna_crtc->flip_bo == NULL);
+						sna_crtc->flip_handler = shadow_flip_handler;
+						sna_crtc->flip_data = sna;
+						sna_crtc->flip_bo = bo;
+						sna_crtc->flip_bo->active_scanout++;
+						sna_crtc->flip_serial = sna_crtc->mode_serial;
+
+						sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo);
+					}
+				}
+			}
 			RegionUninit(&damage);
 
 			if (sna_crtc->slave_damage)
commit c896f249c7b64683839665ff528920382f4fc58e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 16 08:17:09 2014 +0100

    sna: Fixup a failed per-CRTC TearFree flip
    
    If we fail to flip onto a new per-CRTC bo, first try a normal modeset.
    This catches instances where the pitch changes for example.
    
    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 37b1f5b..dd3a69b 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -7035,31 +7035,44 @@ void sna_mode_redisplay(struct sna *sna)
 				arg.reserved = 0;
 
 				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
-					BoxRec box;
-					DrawableRec tmp;
+					if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) {
+						assert(sna_crtc->bo->active_scanout);
+						assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
+						sna_crtc->bo->active_scanout--;
+						kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
+
+						sna_crtc->bo = kgem_bo_reference(bo);
+						sna_crtc->bo->active_scanout++;
+						sna_crtc->client_bo = kgem_bo_reference(bo);
+					} else {
+						BoxRec box;
+						DrawableRec tmp;
+
+						DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
+						     __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno));
+						sna->flags &= ~SNA_TEAR_FREE;
 
-					DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
-					     __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno));
 disable1:
-					box.x1 = 0;
-					box.y1 = 0;
-					tmp.width = box.x2 = crtc->mode.HDisplay;
-					tmp.height = box.y2 = crtc->mode.VDisplay;
-					tmp.depth = sna->front->drawable.depth;
-					tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
-
-					if (!sna->render.copy_boxes(sna, GXcopy,
-								    &sna->front->drawable, bo, 0, 0,
-								    &tmp, sna_crtc->bo, 0, 0,
-								    &box, 1, COPY_LAST)) {
-						xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-							   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
-							   __FUNCTION__, sna_crtc->id, sna_crtc->pipe);
-						sna_crtc_disable(crtc);
-					}
+						box.x1 = 0;
+						box.y1 = 0;
+						tmp.width = box.x2 = crtc->mode.HDisplay;
+						tmp.height = box.y2 = crtc->mode.VDisplay;
+						tmp.depth = sna->front->drawable.depth;
+						tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
+
+						if (!sna->render.copy_boxes(sna, GXcopy,
+									    &sna->front->drawable, bo, 0, 0,
+									    &tmp, sna_crtc->bo, 0, 0,
+									    &box, 1, COPY_LAST)) {
+							xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+								   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
+								   __FUNCTION__, sna_crtc->id, sna_crtc->pipe);
+							sna_crtc_disable(crtc);
+						}
 
-					kgem_bo_destroy(&sna->kgem, bo);
-					sna_crtc->client_bo = NULL;
+						kgem_bo_destroy(&sna->kgem, bo);
+						sna_crtc->client_bo = NULL;
+					}
 					continue;
 				}
 				sna->mode.flip_active++;
@@ -7181,6 +7194,7 @@ fixup_flip:
 					crtc->bo = kgem_bo_reference(flip_bo);
 					crtc->bo->active_scanout++;
 				} else {
+					sna->flags &= ~SNA_TEAR_FREE;
 					if (sna->mode.flip_active == 0) {
 						DBG(("%s: abandoning flip attempt\n", __FUNCTION__));
 						goto fixup_shadow;
commit 3812dfce175eeaef7f41632d2df6a0d88c0ae19b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 16 07:46:26 2014 +0100

    sna: Replace GPU render operations with CPU callbacks after wedged
    
    If we find the GPU is wedged, replace some of the lowlevel render
    operations with CPU equivalents to simplify some fallbacks that still
    need to operate on GPU bo (such as copying DRI buffers).
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=85058
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index a6aa275..234d1d0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -282,6 +282,13 @@ static void assert_bo_retired(struct kgem_bo *bo)
 #define assert_bo_retired(bo)
 #endif
 
+static void
+__kgem_set_wedged(struct kgem *kgem)
+{
+	kgem->wedged = true;
+	sna_render_mark_wedged(container_of(kgem, struct sna, kgem));
+}
+
 static void kgem_sna_reset(struct kgem *kgem)
 {
 	struct sna *sna = container_of(kgem, struct sna, kgem);
@@ -3343,7 +3350,7 @@ void _kgem_submit(struct kgem *kgem)
 				if (!kgem->wedged) {
 					xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
 						   "Failed to submit rendering commands, disabling acceleration.\n");
-					kgem->wedged = true;
+					__kgem_set_wedged(kgem);
 				}
 
 #if !NDEBUG
@@ -3451,8 +3458,7 @@ void kgem_throttle(struct kgem *kgem)
 	if (kgem->wedged)
 		return;
 
-	kgem->wedged = __kgem_throttle(kgem, true);
-	if (kgem->wedged) {
+	if (__kgem_throttle(kgem, true)) {
 		static int once;
 		char path[128];
 
@@ -3465,6 +3471,7 @@ void kgem_throttle(struct kgem *kgem)
 			once = 1;
 		}
 
+		__kgem_set_wedged(kgem);
 		kgem->need_throttle = false;
 	}
 }
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 04ba786..784caee 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -862,74 +862,6 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
 	_kgem_set_mode(&sna->kgem, mode);
 }
 
-static bool can_copy_cpu(struct sna *sna,
-			 struct kgem_bo *src,
-			 struct kgem_bo *dst)
-{
-	if (src->tiling != dst->tiling)
-		return false;
-
-	if (src->pitch != dst->pitch)
-		return false;
-
-	if (!kgem_bo_can_map__cpu(&sna->kgem, src, false))
-		return false;
-
-	if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true))
-		return false;
-
-	DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle));
-	return true;
-}
-
-static void
-sna_dri2_copy_fallback(struct sna *sna,
-		       const DrawableRec *draw,
-		       struct kgem_bo *src_bo, int sx, int sy,
-		       struct kgem_bo *dst_bo, int dx, int dy,
-		       const BoxRec *box, int n)
-{
-	void *dst, *src;
-	bool clipped;
-
-	clipped = (n > 1 ||
-		   box->x1 + sx > 0 ||
-		   box->y1 + sy > 0 ||
-		   box->x2 + sx < draw->width ||
-		   box->y2 + sy < draw->height);
-
-	dst = src = NULL;
-	if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) {
-		dst = kgem_bo_map__cpu(&sna->kgem, dst_bo);
-		src = kgem_bo_map__cpu(&sna->kgem, src_bo);
-	}
-
-	if (dst == NULL || src == NULL) {
-		dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
-		src = kgem_bo_map__gtt(&sna->kgem, src_bo);
-		if (dst == NULL || src == NULL)
-			return;
-	} else {
-		kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true);
-		kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false);
-	}
-
-	DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
-	     __FUNCTION__, sx, sy, dx, dy, n));
-
-	if (sigtrap_get() == 0) {
-		do {
-			memcpy_blt(src, dst, draw->bitsPerPixel,
-				   src_bo->pitch, dst_bo->pitch,
-				   box->x1 + sx, box->y1 + sy,
-				   box->x1 + dx, box->y1 + dy,
-				   box->x2 - box->x1, box->y2 - box->y1);
-			box++;
-		} while (--n);
-		sigtrap_put();
-	}
-}
-
 static bool is_front(int attachment)
 {
 	return attachment == DRI2BufferFrontLeft;
@@ -950,6 +882,7 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	struct kgem_bo *dst_bo;
 	const BoxRec *boxes;
 	int16_t dx, dy, sx, sy;
+	unsigned flags;
 	int n;
 
 	/* To hide a stale DRI2Buffer, one may choose to substitute
@@ -1071,7 +1004,6 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	assert(dst_bo->refcnt);
 	if (is_front(dst->attachment)) {
 		struct sna_pixmap *priv;
-		unsigned int flags;
 
 		flags = MOVE_WRITE | __MOVE_FORCE;
 		if (clip.data)
@@ -1135,38 +1067,32 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	}
 	DamageRegionAppend(&pixmap->drawable, region);
 
-	if (wedged(sna)) {
-fallback:
-		sna_dri2_copy_fallback(sna, src_draw,
-				      src_bo, sx, sy,
-				      dst_bo, dx, dy,
-				      boxes, n);
-	} else {
-		unsigned flags;
 
-		DBG(("%s: copying [(%d, %d), (%d, %d)]x%d src=(%d, %d), dst=(%d, %d)\n",
-		     __FUNCTION__,
-		     boxes[0].x1, boxes[0].y1,
-		     boxes[0].x2, boxes[0].y2,
-		     n, sx, sy, dx, dy));
-
-		flags = COPY_LAST;
-		if (sync)
-			flags |= COPY_SYNC;
-		if (!sna->render.copy_boxes(sna, GXcopy,
-					    src_draw, src_bo, sx, sy,
-					    dst_draw, dst_bo, dx, dy,
-					    boxes, n, flags))
-			goto fallback;
-
-		DBG(("%s: flushing? %d\n", __FUNCTION__, sync));
-		if (sync) { /* STAT! */
-			struct kgem_request *rq = sna->kgem.next_request;
-			kgem_submit(&sna->kgem);
-			if (rq->bo) {
-				bo = ref(rq->bo);
-				DBG(("%s: recording sync fence handle=%d\n", __FUNCTION__, bo->handle));
-			}
+	DBG(("%s: copying [(%d, %d), (%d, %d)]x%d src=(%d, %d), dst=(%d, %d)\n",
+	     __FUNCTION__,
+	     boxes[0].x1, boxes[0].y1,
+	     boxes[0].x2, boxes[0].y2,
+	     n, sx, sy, dx, dy));
+
+	flags = COPY_LAST;
+	if (sync)
+		flags |= COPY_SYNC;
+	if (!sna->render.copy_boxes(sna, GXcopy,
+				    src_draw, src_bo, sx, sy,
+				    dst_draw, dst_bo, dx, dy,
+				    boxes, n, flags))
+		memcpy_copy_boxes(sna, GXcopy,
+				  src_draw, src_bo, sx, sy,
+				  dst_draw, dst_bo, dx, dy,
+				  boxes, n, flags);
+
+	DBG(("%s: flushing? %d\n", __FUNCTION__, sync));
+	if (sync) { /* STAT! */
+		struct kgem_request *rq = sna->kgem.next_request;
+		kgem_submit(&sna->kgem);
+		if (rq->bo) {
+			bo = ref(rq->bo);
+			DBG(("%s: recording sync fence handle=%d\n", __FUNCTION__, bo->handle));
 		}
 	}
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 8cc63a0..22bc491 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -2297,3 +2297,81 @@ cleanup_boxes:
 
 	return ret;
 }
+
+static bool can_copy_cpu(struct sna *sna,
+			 struct kgem_bo *src,
+			 struct kgem_bo *dst)
+{
+	if (src->tiling != dst->tiling)
+		return false;
+
+	if (src->pitch != dst->pitch)
+		return false;
+
+	if (!kgem_bo_can_map__cpu(&sna->kgem, src, false))
+		return false;
+
+	if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true))
+		return false;
+
+	DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle));
+	return true;
+}
+
+bool
+memcpy_copy_boxes(struct sna *sna, uint8_t op,
+		  const DrawableRec *src_draw, struct kgem_bo *src_bo, int16_t sx, int16_t sy,
+		  const DrawableRec *dst_draw, struct kgem_bo *dst_bo, int16_t dx, int16_t dy,
+		  const BoxRec *box, int n, unsigned flags)
+{
+	void *dst, *src;
+	bool clipped;
+
+	if (op != GXcopy)
+		return false;
+
+	clipped = (n > 1 ||
+		   box->x1 + dx > 0 ||
+		   box->y1 + dy > 0 ||
+		   box->x2 + dx < dst_draw->width ||
+		   box->y2 + dy < dst_draw->height);
+
+	dst = src = NULL;
+	if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) {
+		dst = kgem_bo_map__cpu(&sna->kgem, dst_bo);
+		src = kgem_bo_map__cpu(&sna->kgem, src_bo);
+	}
+
+	if (dst == NULL || src == NULL) {
+		dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
+		src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+		if (dst == NULL || src == NULL)
+			return false;
+	} else {
+		kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true);
+		kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false);
+	}
+
+	DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
+	     __FUNCTION__, sx, sy, dx, dy, n));
+
+	if (sigtrap_get() == 0) {
+		do {
+			memcpy_blt(src, dst, dst_draw->bitsPerPixel,
+				   src_bo->pitch, dst_bo->pitch,
+				   box->x1 + sx, box->y1 + sy,
+				   box->x1 + dx, box->y1 + dy,
+				   box->x2 - box->x1, box->y2 - box->y1);
+			box++;
+		} while (--n);
+		sigtrap_put();
+	}
+
+	return true;
+}
+
+void
+sna_render_mark_wedged(struct sna *sna)
+{
+	sna->render.copy_boxes = memcpy_copy_boxes;
+}
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 8b839de..823b86c 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -620,6 +620,8 @@ const char *gen6_render_init(struct sna *sna, const char *backend);
 const char *gen7_render_init(struct sna *sna, const char *backend);
 const char *gen8_render_init(struct sna *sna, const char *backend);
 
+void sna_render_mark_wedged(struct sna *sna);
+
 bool sna_tiling_composite(uint32_t op,
 			  PicturePtr src,
 			  PicturePtr mask,
@@ -707,6 +709,11 @@ bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu,
 				 const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
 				 const BoxRec *box, int nbox);
 
+bool memcpy_copy_boxes(struct sna *sna, uint8_t op,
+		       const DrawableRec *src_draw, struct kgem_bo *src_bo, int16_t sx, int16_t sy,
+		       const DrawableRec *dst_draw, struct kgem_bo *dst_bo, int16_t dx, int16_t dy,
+		       const BoxRec *box, int n, unsigned flags);
+
 bool _sna_get_pixel_from_rgba(uint32_t *pixel,
 			     uint16_t red,
 			     uint16_t green,


More information about the xorg-commit mailing list