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

Chris Wilson ickle at kemper.freedesktop.org
Tue Jun 3 05:50:15 PDT 2014


 src/sna/kgem.c      |   40 +++++++++++++++
 src/sna/kgem.h      |    1 
 src/sna/sna_accel.c |  136 ++++++++++++++++++++++++++++++----------------------
 3 files changed, 121 insertions(+), 56 deletions(-)

New commits:
commit 8297c969ae749ef58d259b2ded2231b928efba43
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 3 09:47:27 2014 +0100

    sna: Replace the bo for tiled uploads if not suitable and being replaced
    
    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 20f4583..85c1c35 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4371,12 +4371,12 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r)
 }
 
 static bool
-create_upload_tiled_x(struct kgem *kgem,
-		      PixmapPtr pixmap,
-		      struct sna_pixmap *priv,
-		      bool replaces)
+can_create_upload_tiled_x(struct kgem *kgem,
+			  PixmapPtr pixmap,
+			  struct sna_pixmap *priv,
+			  bool replaces)
 {
-	unsigned create, tiling;
+	unsigned tiling;
 
 	if (priv->shm || (priv->cpu && !replaces))
 		return false;
@@ -4384,10 +4384,26 @@ create_upload_tiled_x(struct kgem *kgem,
 	if ((priv->create & KGEM_CAN_CREATE_GPU) == 0)
 		return false;
 
+	if (kgem->has_llc)
+		return true;
+
 	tiling = sna_pixmap_choose_tiling(pixmap, I915_TILING_X);
 	assert(tiling != I915_TILING_Y && tiling != -I915_TILING_Y);
+	if (tiling != I915_TILING_NONE)
+		return false;
 
-	if (!kgem->has_llc && tiling != I915_TILING_NONE)
+	return true;
+}
+
+static bool
+create_upload_tiled_x(struct kgem *kgem,
+		      PixmapPtr pixmap,
+		      struct sna_pixmap *priv,
+		      bool replaces)
+{
+	unsigned create;
+
+	if (!can_create_upload_tiled_x(kgem, pixmap, priv, replaces))
 		return false;
 
 	assert(priv->gpu_bo == NULL);
@@ -4404,7 +4420,8 @@ create_upload_tiled_x(struct kgem *kgem,
 			       pixmap->drawable.width,
 			       pixmap->drawable.height,
 			       pixmap->drawable.bitsPerPixel,
-			       tiling, create);
+			       sna_pixmap_choose_tiling(pixmap, I915_TILING_X),
+			       create);
 	return priv->gpu_bo != NULL;
 }
 
@@ -4518,6 +4535,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 {
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
+	bool ignore_cpu = false;
 	bool replaces;
 	BoxRec *box;
 	uint8_t *dst;
@@ -4540,11 +4558,15 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 
 	if (priv->gpu_bo && replaces) {
 		if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
-		if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
-			DBG(("%s: discarding cached upload proxy\n", __FUNCTION__));
+		if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, true) &&
+		    (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
+		     !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
+			DBG(("%s: discarding unusable target bo (busy? %d, mappable? %d)\n", __FUNCTION__,
+			     kgem_bo_is_busy(priv->gpu_bo),
+			     kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)));
 			sna_pixmap_free_gpu(sna, priv);
+			ignore_cpu = true;
 		}
-		replaces = true; /* Mark it all GPU damaged afterwards */
 	}
 	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 
@@ -4557,15 +4579,19 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 	if (priv->gpu_damage &&
 	    region_subsumes_damage(region, priv->gpu_damage)) {
 		if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo);
-		if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
-			DBG(("%s: discarding dirty pixmap\n", __FUNCTION__));
+		if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, priv->cpu_damage == NULL) &&
+		    (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
+		     !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
+			DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__,
+			     kgem_bo_is_busy(priv->gpu_bo),
+			     kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)));
 			sna_pixmap_free_gpu(sna, priv);
+			ignore_cpu = priv->cpu_damage == NULL;
 		}
-		replaces = true; /* Mark it all GPU damaged afterwards */
 	}
 
 	if (priv->gpu_bo == NULL &&
-	    !create_upload_tiled_x(&sna->kgem, pixmap, priv, replaces))
+	    !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu))
 		return false;
 
 	DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling));
@@ -4692,6 +4718,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 		if (priv->cpu_damage == NULL) {
 			list_del(&priv->flush_list);
 			sna_pixmap_free_cpu(sna, priv, priv->cpu);
+			priv->cpu = false;
 		}
 	}
 
commit 1c55d0447dba5bbde5be3903b273e04e3c9d084f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 3 12:43:51 2014 +0100

    sna: Allow replacements to cancel operations between both bo under a Pixmap
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3eb63d8..ea114f4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2175,6 +2175,46 @@ void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
 	assert(bo->exec == NULL);
 }
 
+void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b)
+{
+	if (kgem->nexec > 2)
+		return;
+
+	if (kgem->nexec == 1) {
+		if (a)
+			kgem_bo_undo(kgem, a);
+		if (b)
+			kgem_bo_undo(kgem, b);
+		return;
+	}
+
+	if (a == NULL || b == NULL)
+		return;
+	if (a->exec == NULL || b->exec == NULL)
+		return;
+
+	DBG(("%s: only handles in batch, discarding last operations for handle=%d and handle=%d\n",
+	     __FUNCTION__, a->handle, b->handle));
+
+	assert(a->exec == &kgem->exec[0] || a->exec == &kgem->exec[1]);
+	assert(a->handle == kgem->exec[0].handle || a->handle == kgem->exec[1].handle);
+	assert(RQ(a->rq) == kgem->next_request);
+	assert(b->exec == &kgem->exec[0] || b->exec == &kgem->exec[1]);
+	assert(b->handle == kgem->exec[0].handle || b->handle == kgem->exec[1].handle);
+	assert(RQ(b->rq) == kgem->next_request);
+
+	a->refcnt++;
+	b->refcnt++;
+	kgem_reset(kgem);
+	b->refcnt--;
+	a->refcnt--;
+
+	assert(kgem->nreloc == 0);
+	assert(kgem->nexec == 0);
+	assert(a->exec == NULL);
+	assert(b->exec == NULL);
+}
+
 static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 {
 	DBG(("%s: handle=%d, size=%d\n", __FUNCTION__, bo->handle, bytes(bo)));
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 6e61909..ae25821 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -548,6 +548,7 @@ static inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
 }
 
 void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo);
+void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b);
 
 bool __kgem_busy(struct kgem *kgem, int handle);
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e4fad3b..20f4583 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -483,12 +483,15 @@ static void sna_pixmap_free_gpu(struct sna *sna, struct sna_pixmap *priv)
 	sna_damage_destroy(&priv->gpu_damage);
 	priv->clear = false;
 
-	if (priv->gpu_bo && !priv->pinned) {
-		assert(!priv->flush);
-		assert(!priv->move_to_gpu);
-		sna_pixmap_unmap(priv->pixmap, priv);
-		kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
-		priv->gpu_bo = NULL;
+	if (priv->gpu_bo) {
+		if (!priv->pinned) {
+			assert(!priv->flush);
+			assert(!priv->move_to_gpu);
+			sna_pixmap_unmap(priv->pixmap, priv);
+			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+			priv->gpu_bo = NULL;
+		} else
+			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
 	}
 
 	/* and reset the upload counter */
@@ -1460,6 +1463,7 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap)
 	sna_damage_destroy(&priv->gpu_damage);
 	sna_damage_destroy(&priv->cpu_damage);
 
+	list_del(&priv->cow_list);
 	if (priv->cow) {
 		struct sna_cow *cow = COW(priv->cow);
 		DBG(("%s: pixmap=%ld discarding cow, refcnt=%d\n",
@@ -1468,8 +1472,8 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap)
 		if (!--cow->refcnt)
 			free(cow);
 		priv->cow = NULL;
-	}
-	list_del(&priv->cow_list);
+	} else
+		kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
 
 	if (priv->move_to_gpu)
 		(void)priv->move_to_gpu(sna, priv, 0);
@@ -2075,10 +2079,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 	assert(priv->gpu_damage == NULL || priv->gpu_bo);
 
 	if ((flags & MOVE_READ) == 0 && UNDO) {
-		if (priv->gpu_bo)
-			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
-		if (priv->cpu_bo)
-			kgem_bo_undo(&sna->kgem, priv->cpu_bo);
+		kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
 		if (priv->move_to_gpu)
 			sna_pixmap_discard_shadow_damage(priv, NULL);
 	}
@@ -3929,12 +3930,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		return NULL;
 	}
 
-	if ((flags & MOVE_READ) == 0 && UNDO) {
-		if (priv->gpu_bo)
-			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
-		if (priv->cpu_bo)
-			kgem_bo_undo(&sna->kgem, priv->cpu_bo);
-	}
+	if ((flags & MOVE_READ) == 0 && UNDO)
+		kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
 
 	if (priv->cow && (flags & MOVE_WRITE || priv->cpu_damage)) {
 		if (!sna_pixmap_undo_cow(sna, priv, flags & MOVE_READ))
@@ -4542,8 +4539,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 	}
 
 	if (priv->gpu_bo && replaces) {
-		if (UNDO)
-			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
+		if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
 		if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
 			DBG(("%s: discarding cached upload proxy\n", __FUNCTION__));
 			sna_pixmap_free_gpu(sna, priv);
@@ -4560,8 +4556,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 
 	if (priv->gpu_damage &&
 	    region_subsumes_damage(region, priv->gpu_damage)) {
-		if (UNDO)
-			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
+		if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo);
 		if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
 			DBG(("%s: discarding dirty pixmap\n", __FUNCTION__));
 			sna_pixmap_free_gpu(sna, priv);
@@ -6013,7 +6008,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 			if (n == 1) {
 				if (replaces && UNDO)
-					kgem_bo_undo(&sna->kgem, bo);
+					kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
 
 				if (!sna->render.fill_one(sna,
 							  dst_pixmap, bo, color,
@@ -6066,7 +6061,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			DBG(("%s: move whole src_pixmap to GPU and copy\n",
 			     __FUNCTION__));
 			if (replaces && UNDO)
-				kgem_bo_undo(&sna->kgem, bo);
+				kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
 
 			if (replaces &&
 			    src_pixmap->drawable.width == dst_pixmap->drawable.width &&
@@ -6120,7 +6115,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			}
 
 			if (replaces && UNDO)
-				kgem_bo_undo(&sna->kgem, bo);
+				kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
 
 			if (!sna->render.copy_boxes(sna, alu,
 						    src_pixmap, src_priv->gpu_bo, src_dx, src_dy,
@@ -6158,7 +6153,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			}
 
 			if (replaces && UNDO)
-				kgem_bo_undo(&sna->kgem, bo);
+				kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
 
 			if (src_priv->shm) {
 				assert(!src_priv->flush);
@@ -14321,7 +14316,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 		goto fallback;
 	}
 	if (hint & REPLACES && (flags & 2) == 0 && UNDO)
-		kgem_bo_undo(&sna->kgem, bo);
+		kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
 
 	if (gc_is_solid(gc, &color)) {
 		DBG(("%s: solid fill [%08x], testing for blt\n",
commit a82bfb033448eb61bf8cc7f5358be019f0cc28e6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 3 09:28:24 2014 +0100

    sna: Discard unwanted damage when promoting to a full CPU migration
    
    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 2513b8b..e4fad3b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2630,18 +2630,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		}
 	}
 
-	if (flags & MOVE_WHOLE_HINT) {
-		DBG(("%s: region (%d, %d), (%d, %d) marked with WHOLE hint, pixmap %dx%d\n",
-		       __FUNCTION__,
-		       region->extents.x1,
-		       region->extents.y1,
-		       region->extents.x2,
-		       region->extents.y2,
-		       pixmap->drawable.width,
-		       pixmap->drawable.height));
-		return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
-	}
-
 	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
 		DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
 		RegionTranslate(region, dx, dy);
@@ -2696,11 +2684,27 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 
 	if (priv->clear && flags & MOVE_WRITE) {
 		DBG(("%s: pending clear, moving whole pixmap for partial write\n", __FUNCTION__));
+demote_to_cpu:
 		if (dx | dy)
 			RegionTranslate(region, -dx, -dy);
 		return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
 	}
 
+	if (flags & MOVE_WHOLE_HINT) {
+		DBG(("%s: region (%d, %d), (%d, %d) marked with WHOLE hint, pixmap %dx%d\n",
+		       __FUNCTION__,
+		       region->extents.x1,
+		       region->extents.y1,
+		       region->extents.x2,
+		       region->extents.y2,
+		       pixmap->drawable.width,
+		       pixmap->drawable.height));
+move_to_cpu:
+		if ((flags & MOVE_READ) == 0)
+			sna_damage_subtract(&priv->gpu_damage, region);
+		goto demote_to_cpu;
+	}
+
 	sna_pixmap_unmap(pixmap, priv);
 
 	if (USE_INPLACE &&
@@ -2776,10 +2780,8 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	if (pixmap->devPrivate.ptr == NULL &&
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv,
 				  flags & MOVE_READ ? priv->gpu_damage && !priv->clear : 0)) {
-		if (dx | dy)
-			RegionTranslate(region, -dx, -dy);
 		DBG(("%s: CPU bo allocation failed, trying full move-to-cpu\n", __FUNCTION__));
-		return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
+		goto move_to_cpu;
 	}
 	assert(priv->mapped == MAPPED_NONE);
 	assert(pixmap->devPrivate.ptr == PTR(priv->ptr));


More information about the xorg-commit mailing list