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

Chris Wilson ickle at kemper.freedesktop.org
Mon Jan 14 10:35:36 PST 2013


 src/sna/kgem.c       |    2 
 src/sna/sna.h        |    3 
 src/sna/sna_accel.c  |  533 ++++++++++++---------------------------------------
 src/sna/sna_damage.h |   28 +-
 4 files changed, 150 insertions(+), 416 deletions(-)

New commits:
commit f235c74cd661970c76e152777e9a2c314a368a56
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 14 15:49:42 2013 +0000

    sna: Tweak considering of last-cpu placement for inplace regions
    
    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 9c33bb4..9125f9c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1806,12 +1806,7 @@ static inline bool region_inplace(struct sna *sna,
 	if (wedged(sna) && !priv->pinned)
 		return false;
 
-	if (priv->cpu) {
-		DBG(("%s: no, preferring last action of CPU\n", __FUNCTION__));
-		return false;
-	}
-
-	if (!write_only &&
+	if ((priv->cpu || !write_only) &&
 	    region_overlaps_damage(region, priv->cpu_damage, 0, 0)) {
 		DBG(("%s: no, uncovered CPU damage pending\n", __FUNCTION__));
 		return false;
@@ -1822,6 +1817,11 @@ static inline bool region_inplace(struct sna *sna,
 		return true;
 	}
 
+	if (priv->cpu) {
+		DBG(("%s: no, preferring last action of CPU\n", __FUNCTION__));
+		return false;
+	}
+
 	if (priv->mapped) {
 		DBG(("%s: yes, already mapped, continuiung\n", __FUNCTION__));
 		return !IS_CPU_MAP(priv->gpu_bo->map);
commit 70c5e41b519e44e620948d683d3b1111494d2f48
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 14 15:03:59 2013 +0000

    sna: Limit temporary userptr uploads to large busy targets or LLC machines
    
    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 c80f51d..9c33bb4 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4363,8 +4363,9 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		if (USE_USERPTR_UPLOADS &&
 		    src_priv == NULL &&
 		    sna->kgem.has_userptr &&
-		    ((bo->tiling && !bo->scanout) || __kgem_bo_is_busy(&sna->kgem, bo)) &&
-		    box_inplace(src_pixmap, &region->extents)) {
+		    box_inplace(src_pixmap, &region->extents) &&
+		    ((sna->kgem.has_llc && bo->tiling && !bo->scanout) ||
+		     __kgem_bo_is_busy(&sna->kgem, bo))) {
 			struct kgem_bo *src_bo;
 			bool ok = false;
 
commit cf860da1c78244036c59edf934b312cc1367e8aa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 14 12:50:54 2013 +0000

    sna: Apply PutImage optimisations to move-to-cpu
    
    We can replace the custom heuristics for PutImage by applying them to
    the common path, where hopefully they are equally valid.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 4d1d46a..2f8d696 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3385,6 +3385,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem,
 	size = kgem_surface_size(kgem, false, 0,
 				 width, height, bpp,
 				 I915_TILING_NONE, &pitch);
+	DBG(("%s: untiled size=%d\n", __FUNCTION__, size));
 	if (size > 0) {
 		if (size < 4096)
 			flags |= KGEM_CAN_CREATE_SMALL;
@@ -3409,6 +3410,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem,
 		size = kgem_surface_size(kgem, false, 0,
 					 width, height, bpp, tiling,
 					 &pitch);
+		DBG(("%s: tiled[%d] size=%d\n", __FUNCTION__, tiling, size));
 		if (size > 0 && size <= kgem->max_gpu_size)
 			flags |= KGEM_CAN_CREATE_GPU;
 		if (size > 0 && size <= kgem->aperture_mappable/4)
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 6fe9e5e..bddeed4 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -111,6 +111,7 @@ struct sna_pixmap {
 	struct kgem_bo *gpu_bo, *cpu_bo;
 	struct sna_damage *gpu_damage, *cpu_damage;
 	void *ptr;
+#define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1))
 
 	struct list list;
 
@@ -125,11 +126,11 @@ struct sna_pixmap {
 #define PIN_SCANOUT 0x1
 #define PIN_DRI 0x2
 #define PIN_PRIME 0x4
+	uint8_t create :5;
 	uint8_t mapped :1;
 	uint8_t shm :1;
 	uint8_t clear :1;
 	uint8_t undamaged :1;
-	uint8_t create :3;
 	uint8_t header :1;
 	uint8_t cpu :1;
 };
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 636411b..c80f51d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -96,7 +96,6 @@
 
 #define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1)
 #define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1))
-#define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1))
 
 #if 0
 static void __sna_fallback_flush(DrawablePtr d)
@@ -1331,7 +1330,8 @@ void sna_pixmap_destroy(PixmapPtr pixmap)
 
 static inline bool pixmap_inplace(struct sna *sna,
 				  PixmapPtr pixmap,
-				  struct sna_pixmap *priv)
+				  struct sna_pixmap *priv,
+				  bool write_only)
 {
 	if (FORCE_INPLACE)
 		return FORCE_INPLACE > 0;
@@ -1342,6 +1342,9 @@ static inline bool pixmap_inplace(struct sna *sna,
 	if (priv->mapped)
 		return !IS_CPU_MAP(priv->gpu_bo->map);
 
+	if (!write_only && priv->cpu_damage)
+		return false;
+
 	return (pixmap->devKind * pixmap->drawable.height >> 12) >
 		sna->kgem.half_cpu_cache_pages;
 }
@@ -1355,6 +1358,9 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap)
 	if (wedged(sna))
 		return false;
 
+	if ((priv->create & KGEM_CAN_CREATE_GTT) == 0)
+		return false;
+
 	assert_pixmap_damage(pixmap);
 
 	assert(priv->gpu_bo == NULL);
@@ -1432,14 +1438,25 @@ static inline bool use_cpu_bo_for_upload(struct sna *sna,
 
 static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags)
 {
-	if ((priv->create & KGEM_CAN_CREATE_GTT) == 0)
+	if ((priv->create & KGEM_CAN_CREATE_GTT) == 0) {
+		DBG(("%s: no, not accessible via GTT\n", __FUNCTION__));
 		return false;
+	}
 
-	if ((flags & MOVE_INPLACE_HINT) == 0)
+	if ((flags & MOVE_INPLACE_HINT) == 0) {
+		DBG(("%s: no, inplace operation not suitable\n", __FUNCTION__));
 		return false;
+	}
+
+	if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) {
+		DBG(("%s: yes, CPU is busy\n", __FUNCTION__));
+		return true;
+	}
 
-	if (priv->gpu_damage && kgem_bo_is_busy(priv->gpu_bo))
+	if (flags & MOVE_WRITE && priv->gpu_bo&&kgem_bo_is_busy(priv->gpu_bo)) {
+		DBG(("%s: no, GPU is busy, so stage write\n", __FUNCTION__));
 		return false;
+	}
 
 	return true;
 }
@@ -1475,7 +1492,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 		     __FUNCTION__, priv->gpu_damage != NULL, priv->clear));
 
 		if (priv->create & KGEM_CAN_CREATE_GPU &&
-		    pixmap_inplace(sna, pixmap, priv)) {
+		    pixmap_inplace(sna, pixmap, priv, true)) {
 			assert(!priv->shm);
 			DBG(("%s: write inplace\n", __FUNCTION__));
 			if (priv->gpu_bo) {
@@ -1533,6 +1550,13 @@ skip_inplace_map:
 
 			sna_pixmap_free_gpu(sna, priv);
 			sna_pixmap_free_cpu(sna, priv);
+
+			if (!sna_pixmap_alloc_cpu(sna, pixmap, priv, false))
+				return false;
+
+			sna_damage_all(&priv->cpu_damage,
+					pixmap->drawable.width,
+					pixmap->drawable.height);
 		}
 	}
 
@@ -1544,8 +1568,8 @@ skip_inplace_map:
 	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 
 	if (operate_inplace(priv, flags) &&
-	    pixmap_inplace(sna, pixmap, priv) &&
-	    sna_pixmap_move_to_gpu(pixmap, flags)) {
+	    pixmap_inplace(sna, pixmap, priv, (flags & MOVE_READ) == 0) &&
+	    (priv->gpu_bo || sna_pixmap_create_mappable_gpu(pixmap))) {
 		kgem_bo_submit(&sna->kgem, priv->gpu_bo);
 
 		DBG(("%s: try to operate inplace (GTT)\n", __FUNCTION__));
@@ -1584,7 +1608,7 @@ skip_inplace_map:
 
 	if (priv->gpu_damage &&
 	    priv->gpu_bo->tiling == I915_TILING_NONE &&
-	    sna_pixmap_move_to_gpu(pixmap, flags)) {
+	    sna_pixmap_move_to_gpu(pixmap, MOVE_READ)) {
 		kgem_bo_submit(&sna->kgem, priv->gpu_bo);
 
 		DBG(("%s: try to operate inplace (CPU)\n", __FUNCTION__));
@@ -1617,63 +1641,9 @@ skip_inplace_map:
 	if (priv->clear && priv->cpu_bo && !priv->cpu_bo->flush &&
 	    __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) {
 		assert(!priv->shm);
-		assert(DAMAGE_IS_ALL(priv->gpu_damage));
 		sna_pixmap_free_cpu(sna, priv);
 	}
 
-	if (priv->ptr == NULL &&
-	    (flags & MOVE_READ) == 0 &&
-	    sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING) == I915_TILING_NONE) {
-		assert(flags & MOVE_WRITE);
-		assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
-
-		DBG(("%s: uninitialised, try to create inplace (CPU)\n",
-		     __FUNCTION__));
-
-		assert(pixmap->devPrivate.ptr == NULL);
-		assert(pixmap->usage_hint != SNA_CREATE_FB);
-
-		if (priv->gpu_bo && priv->gpu_bo->domain != DOMAIN_CPU) {
-			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
-			priv->gpu_bo = NULL;
-		}
-
-		if (priv->gpu_bo == NULL)
-			priv->gpu_bo = kgem_create_2d(&sna->kgem,
-						      pixmap->drawable.width,
-						      pixmap->drawable.height,
-						      pixmap->drawable.bitsPerPixel,
-						      I915_TILING_NONE,
-						      CREATE_CPU_MAP | CREATE_INACTIVE);
-		if (priv->gpu_bo)
-			pixmap->devPrivate.ptr =
-				kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
-		if (pixmap->devPrivate.ptr != NULL) {
-			priv->clear = false;
-			priv->cpu = true;
-			priv->mapped = true;
-			pixmap->devKind = priv->gpu_bo->pitch;
-
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
-			sna_damage_destroy(&priv->cpu_damage);
-			sna_pixmap_free_cpu(sna, priv);
-			list_del(&priv->list);
-			priv->undamaged = false;
-
-			kgem_bo_sync__cpu(&sna->kgem, priv->gpu_bo);
-			assert_pixmap_damage(pixmap);
-			DBG(("%s: operate inplace (CPU)\n", __FUNCTION__));
-			return true;
-		}
-
-		if (priv->gpu_bo) {
-			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
-			priv->gpu_bo = NULL;
-		}
-	}
-
 	if (pixmap->devPrivate.ptr == NULL &&
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL && !priv->clear))
 		return false;
@@ -1923,6 +1893,11 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		goto out;
 	}
 
+	if (USE_INPLACE &&
+	    (flags & MOVE_READ) == 0 &&
+	    (priv->flush || box_inplace(pixmap, &region->extents)))
+		flags |= MOVE_INPLACE_HINT;
+
 	if (flags & MOVE_WHOLE_HINT)
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 
@@ -1943,98 +1918,9 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 	}
 
-	if (USE_INPLACE && (flags & MOVE_READ) == 0) {
-		DBG(("%s: no read, checking to see if we can stream the write into the GPU bo\n",
-		     __FUNCTION__));
-		assert(flags & MOVE_WRITE);
-
-		if (priv->gpu_bo &&
-		    kgem_bo_can_map(&sna->kgem, priv->gpu_bo) &&
-		    region_inplace(sna, pixmap, region, priv, true)) {
-			assert(priv->gpu_bo->proxy == NULL);
-			if (!__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
-				pixmap->devPrivate.ptr =
-					kgem_bo_map(&sna->kgem, priv->gpu_bo);
-				if (pixmap->devPrivate.ptr == NULL) {
-					if (dx | dy)
-						RegionTranslate(region, -dx, -dy);
-					return false;
-				}
-
-				priv->mapped = true;
-				pixmap->devKind = priv->gpu_bo->pitch;
-
-				sna_damage_subtract(&priv->cpu_damage, region);
-				if (priv->cpu_damage == NULL) {
-					list_del(&priv->list);
-					sna_damage_all(&priv->gpu_damage,
-						       pixmap->drawable.width,
-						       pixmap->drawable.height);
-					priv->undamaged = false;
-				} else
-					sna_damage_add(&priv->gpu_damage,
-						       region);
-
-				priv->clear = false;
-				priv->cpu = false;
-				assert_pixmap_damage(pixmap);
-				if (dx | dy)
-					RegionTranslate(region, -dx, -dy);
-				return true;
-			}
-		}
-
-		if (priv->cpu_bo && !priv->cpu_bo->flush) {
-			if (__kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) {
-				sna_damage_subtract(&priv->cpu_damage, region);
-				if (!sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE)) {
-					if (dx | dy)
-						RegionTranslate(region, -dx, -dy);
-					return false;
-				}
-
-				assert(!priv->shm);
-				sna_pixmap_free_cpu(sna, priv);
-			}
-		}
-
-		if (priv->gpu_bo == NULL &&
-		    sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING) != I915_TILING_NONE &&
-		    region_inplace(sna, pixmap, region, priv, true) &&
-		    sna_pixmap_create_mappable_gpu(pixmap)) {
-			pixmap->devPrivate.ptr =
-				kgem_bo_map(&sna->kgem, priv->gpu_bo);
-			if (pixmap->devPrivate.ptr == NULL) {
-				if (dx | dy)
-					RegionTranslate(region, -dx, -dy);
-				return false;
-			}
-
-			priv->mapped = true;
-			pixmap->devKind = priv->gpu_bo->pitch;
-
-			sna_damage_subtract(&priv->cpu_damage, region);
-			if (priv->cpu_damage == NULL) {
-				list_del(&priv->list);
-				sna_damage_all(&priv->gpu_damage,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height);
-				priv->undamaged = false;
-			} else
-				sna_damage_add(&priv->gpu_damage, region);
-
-			assert_pixmap_damage(pixmap);
-			priv->clear = false;
-			priv->cpu = false;
-			if (dx | dy)
-				RegionTranslate(region, -dx, -dy);
-			return true;
-		}
-	}
-
 	if (operate_inplace(priv, flags) &&
 	    region_inplace(sna, pixmap, region, priv, (flags & MOVE_READ) == 0) &&
-	    sna_pixmap_move_to_gpu(pixmap, flags | MOVE_READ)) {
+	    (priv->gpu_bo || sna_pixmap_create_mappable_gpu(pixmap))) {
 		kgem_bo_submit(&sna->kgem, priv->gpu_bo);
 
 		DBG(("%s: try to operate inplace\n", __FUNCTION__));
@@ -2084,8 +1970,22 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		priv->mapped = false;
 	}
 
+	if ((priv->clear || (flags & MOVE_READ) == 0) &&
+	    priv->cpu_bo && !priv->cpu_bo->flush &&
+	    __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) {
+		sna_damage_subtract(&priv->gpu_damage, region);
+		if (sna_pixmap_move_to_gpu(pixmap, MOVE_READ)) {
+			sna_damage_all(&priv->gpu_damage,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height);
+			priv->undamaged = false;
+			sna_pixmap_free_cpu(sna, priv);
+		}
+	}
+
 	if (pixmap->devPrivate.ptr == NULL &&
-	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL)) {
+	    !sna_pixmap_alloc_cpu(sna, pixmap, priv,
+				  priv->gpu_damage && !priv->clear)) {
 		if (dx | dy)
 			RegionTranslate(region, -dx, -dy);
 		return false;
@@ -3295,11 +3195,7 @@ done:
 			      pixmap->drawable.height);
 	if (DAMAGE_IS_ALL(priv->gpu_damage)) {
 		priv->undamaged = false;
-		if (priv->ptr) {
-			assert(priv->cpu_bo == NULL || !priv->cpu_bo->flush);
-			assert(!priv->shm);
-			sna_pixmap_free_cpu(sna, priv);
-		}
+		sna_pixmap_free_cpu(sna, priv);
 	}
 
 active:
@@ -3512,136 +3408,6 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r)
 }
 
 static bool
-sna_put_image_upload_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
-			 int x, int y, int w, int h, char *bits, int stride)
-{
-	PixmapPtr pixmap = get_drawable_pixmap(drawable);
-	struct sna *sna = to_sna_from_pixmap(pixmap);
-	struct sna_pixmap *priv = sna_pixmap(pixmap);
-	BoxPtr box;
-	int nbox;
-	int16_t dx, dy;
-
-	box = REGION_RECTS(region);
-	nbox = REGION_NUM_RECTS(region);
-
-	DBG(("%s: %d x [(%d, %d), (%d, %d)...]\n",
-	     __FUNCTION__, nbox,
-	     box->x1, box->y1, box->x2, box->y2));
-
-	if (gc->alu != GXcopy)
-		return false;
-
-	if (priv->gpu_bo == NULL &&
-	    !sna_pixmap_create_mappable_gpu(pixmap))
-		return false;
-
-	assert(priv->gpu_bo);
-	assert(priv->gpu_bo->proxy == NULL);
-
-	if (!priv->pinned && nbox == 1 &&
-	    box->x1 <= 0 && box->y1 <= 0 &&
-	    box->x2 >= pixmap->drawable.width &&
-	    box->y2 >= pixmap->drawable.height)
-		return sna_replace(sna, pixmap, &priv->gpu_bo, bits, stride);
-
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
-	x += dx + drawable->x;
-	y += dy + drawable->y;
-
-	return sna_write_boxes(sna, pixmap,
-			       priv->gpu_bo, 0, 0,
-			       bits, stride, -x, -y,
-			       box, nbox);
-}
-
-static bool upload_inplace(struct sna *sna,
-			   PixmapPtr pixmap,
-			   struct sna_pixmap *priv,
-			   RegionRec *region)
-{
-	if (priv->shm) {
-		DBG(("%s: no, SHM Pixmap\n", __FUNCTION__));
-		return false;
-	}
-
-	if (priv->mapped && IS_CPU_MAP(priv->gpu_bo->map))
-		return false;
-
-	if (priv->create & KGEM_CAN_CREATE_LARGE) {
-		if (priv->gpu_bo) {
-			DBG(("%s: yes, large buffer and already have GPU bo\n",
-			     __FUNCTION__));
-			return true;
-		}
-		if (priv->cpu_bo){
-			DBG(("%s: no, large buffer and already have CPU bo\n",
-			     __FUNCTION__));
-			return false;
-		}
-	}
-
-	if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo) &&
-	    !(priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))) {
-		DBG(("%s: yes, CPU bo is busy, but the GPU bo is not\n", __FUNCTION__));
-		return true;
-	}
-
-	if (!region_inplace(sna, pixmap, region, priv, true)) {
-		DBG(("%s? no, region not suitable\n", __FUNCTION__));
-		return false;
-	}
-
-	if (sna->kgem.has_llc && !priv->flush) {
-		if (priv->cpu_bo) {
-			if (priv->cpu_damage &&
-			    kgem_bo_is_busy(priv->cpu_bo) &&
-			    !region_subsumes_damage(region, priv->cpu_damage)) {
-				DBG(("%s? yes, CPU bo is busy\n", __FUNCTION__));
-				return true;
-			}
-
-			DBG(("%s? no, have CPU bo\n", __FUNCTION__));
-			return false;
-		}
-
-		if (priv->create & KGEM_CAN_CREATE_CPU) {
-			DBG(("%s? no, can create CPU bo\n", __FUNCTION__));
-			return false;
-		}
-	}
-
-	if (priv->gpu_bo) {
-		if (priv->gpu_bo->proxy)
-			return false;
-
-		if (!kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
-			DBG(("%s? no, GPU bo not mappable\n", __FUNCTION__));
-			return false;
-		}
-
-		if (!kgem_bo_is_busy(priv->gpu_bo)) {
-			DBG(("%s? yes, GPU bo is idle\n", __FUNCTION__));
-			return true;
-		}
-
-		if (!priv->pinned &&
-		    region_subsumes_drawable(region, &pixmap->drawable)) {
-			DBG(("%s? yes, will replace busy GPU\n", __FUNCTION__));
-			return true;
-		}
-	}
-
-	if ((priv->create & (KGEM_CAN_CREATE_GPU | KGEM_CAN_CREATE_CPU)) == KGEM_CAN_CREATE_GPU &&
-	    region_subsumes_drawable(region, &pixmap->drawable)) {
-		DBG(("%s? yes, will fill fresh GPU bo\n", __FUNCTION__));
-		return true;
-	}
-
-	return false;
-}
-
-static bool
 sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		    int x, int y, int w, int  h, char *bits, int stride)
 {
@@ -3667,115 +3433,14 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		goto blt;
 	}
 
-	/* XXX performing the upload inplace is currently about 20x slower
-	 * for putimage10 on gen6 -- mostly due to slow page faulting in kernel.
-	 * So we try again with vma caching and only for pixmaps who will be
-	 * immediately flushed...
-	 */
-	if (upload_inplace(sna, pixmap, priv, region) &&
-	    sna_put_image_upload_blt(drawable, gc, region,
-				     x, y, w, h, bits, stride)) {
-		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-			DBG(("%s: marking damage\n", __FUNCTION__));
-			if (region_subsumes_drawable(region, &pixmap->drawable))
-				sna_damage_destroy(&priv->cpu_damage);
-			else
-				sna_damage_subtract(&priv->cpu_damage, region);
-			if (priv->cpu_damage == NULL) {
-				assert(priv->gpu_bo->proxy == NULL);
-				sna_damage_all(&priv->gpu_damage,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height);
-				list_del(&priv->list);
-				priv->undamaged = false;
-			} else
-				sna_damage_add(&priv->gpu_damage, region);
-		}
-
-		/* And mark as having a valid GTT mapping for future uploads */
-		if (kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
-			pixmap->devPrivate.ptr =
-				kgem_bo_map__async(&sna->kgem, priv->gpu_bo);
-			if (pixmap->devPrivate.ptr) {
-				priv->mapped = true;
-				pixmap->devKind = priv->gpu_bo->pitch;
-			}
-		}
-
-		assert_pixmap_damage(pixmap);
-		priv->clear = false;
-		priv->cpu = false;
-		return true;
-	}
-
-	if (USE_USERPTR_UPLOADS &&
-	    sna->kgem.has_userptr &&
-	    box_inplace(pixmap, &region->extents)) {
-		struct kgem_bo *src_bo = NULL;
-		bool ok = false;
-
-		DBG(("%s: upload through a temporary map\n",
-		     __FUNCTION__));
-
-		if (priv->gpu_bo == NULL)
-			priv->gpu_bo = kgem_create_2d(&sna->kgem,
-						      pixmap->drawable.width,
-						      pixmap->drawable.height,
-						      pixmap->drawable.bitsPerPixel,
-						      sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
-						      pixmap->usage_hint == SNA_CREATE_FB ?  CREATE_EXACT | CREATE_SCANOUT : 0);
-
-		if (priv->gpu_bo)
-			src_bo = kgem_create_map(&sna->kgem, bits, stride * h, true);
-		if (src_bo) {
-			src_bo->flush = true;
-			src_bo->pitch = stride;
-			src_bo->reusable = false;
-
-			get_drawable_deltas(drawable, pixmap, &dx, &dy);
-			ok = sna->render.copy_boxes(sna, GXcopy,
-						    pixmap, src_bo,
-						    -(x + dx + drawable->x),
-						    -(y + dy + drawable->y),
-						    pixmap, priv->gpu_bo, 0, 0,
-						    REGION_RECTS(region),
-						    REGION_NUM_RECTS(region),
-						    COPY_LAST);
-
-			kgem_bo_sync__cpu(&sna->kgem, src_bo);
-			kgem_bo_destroy(&sna->kgem, src_bo);
-		}
-
-		if (ok) {
-			if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-				DBG(("%s: marking damage\n", __FUNCTION__));
-				if (region_subsumes_drawable(region, &pixmap->drawable))
-					sna_damage_destroy(&priv->cpu_damage);
-				else
-					sna_damage_subtract(&priv->cpu_damage, region);
-				if (priv->cpu_damage == NULL) {
-					assert(priv->gpu_bo->proxy == NULL);
-					sna_damage_all(&priv->gpu_damage,
-						       pixmap->drawable.width,
-						       pixmap->drawable.height);
-					list_del(&priv->list);
-					priv->undamaged = false;
-				} else
-					sna_damage_add(&priv->gpu_damage, region);
-			}
-			return true;
-		}
-	}
-
 	flags = MOVE_WRITE;
-	flags |= MOVE_INPLACE_HINT;
 	if (w == pixmap->drawable.width) {
 		flags |= MOVE_WHOLE_HINT;
 		if (h != pixmap->drawable.height)
 			flags |= MOVE_READ;
 	}
 
-	if (!sna_drawable_move_region_to_cpu(drawable, region, flags))
+	if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, region, flags))
 		return false;
 
 blt:
diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 5e800b7..76718eb 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -259,20 +259,22 @@ static inline void sna_damage_reduce_all(struct sna_damage **_damage,
 	if (damage == NULL || DAMAGE_IS_ALL(damage))
 		return;
 
-	if (damage->mode == DAMAGE_ADD &&
-	    damage->extents.x1 <= 0 &&
-	    damage->extents.y1 <= 0 &&
-	    damage->extents.x2 >= width &&
-	    damage->extents.y2 >= height) {
-		if (damage->dirty) {
-			damage = *_damage = _sna_damage_reduce(damage);
-			if (damage == NULL)
-				return;
+	if (damage->mode == DAMAGE_ADD) {
+		if (damage->extents.x1 <= 0 &&
+		    damage->extents.y1 <= 0 &&
+		    damage->extents.x2 >= width &&
+		    damage->extents.y2 >= height) {
+			if (damage->dirty) {
+				damage = *_damage = _sna_damage_reduce(damage);
+				if (damage == NULL)
+					return;
+			}
+
+			if (damage->region.data == NULL)
+				*_damage = _sna_damage_all(damage, width, height);
 		}
-
-		if (damage->region.data == NULL)
-			*_damage = _sna_damage_all(damage, width, height);
-	}
+	} else
+		*_damage = _sna_damage_reduce(damage);
 }
 
 void __sna_damage_destroy(struct sna_damage *damage);
commit e4ad4477815abe31b1a2323673da86a6def2f246
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 14 13:12:46 2013 +0000

    sna: Use userptr to accelerate GetImage
    
    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 8f12708..636411b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -63,6 +63,7 @@
 #define USE_ZERO_SPANS 1 /* -1 force CPU, 1 force GPU */
 #define USE_CPU_BO 1
 #define USE_USERPTR_UPLOADS 1
+#define USE_USERPTR_DOWNLOADS 1
 
 #define MIGRATE_ALL 0
 #define DBG_NO_CPU_UPLOAD 0
@@ -13701,6 +13702,62 @@ static int sna_create_gc(GCPtr gc)
 	return true;
 }
 
+static bool
+sna_get_image_blt(DrawablePtr drawable,
+		  RegionPtr region,
+		  char *dst)
+{
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna_pixmap *priv = sna_pixmap(pixmap);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	struct kgem_bo *dst_bo;
+	bool ok = false;
+	int pitch;
+
+	if (!USE_USERPTR_DOWNLOADS)
+		return false;
+
+	if (priv == NULL)
+		return false;
+
+	if (!sna->kgem.has_userptr)
+		return false;
+
+	if (!DAMAGE_IS_ALL(priv->gpu_damage) ||
+	    !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
+		return false;
+
+	DBG(("%s: download through a temporary map\n", __FUNCTION__));
+
+	pitch = PixmapBytePad(region->extents.x2 - region->extents.x1,
+			      drawable->depth);
+	dst_bo = kgem_create_map(&sna->kgem, dst,
+				 pitch * (region->extents.y2 - region->extents.y1),
+				 false);
+	if (dst_bo) {
+		int16_t dx, dy;
+
+		dst_bo->flush = true;
+		dst_bo->pitch = pitch;
+		dst_bo->reusable = false;
+
+		get_drawable_deltas(drawable, pixmap, &dx, &dy);
+
+		ok = sna->render.copy_boxes(sna, GXcopy,
+					    pixmap, priv->gpu_bo, dx, dy,
+					    pixmap, dst_bo,
+					    -region->extents.x1,
+					    -region->extents.y1,
+					    &region->extents, 1,
+					    COPY_LAST);
+
+		kgem_bo_sync__cpu(&sna->kgem, dst_bo);
+		kgem_bo_destroy(&sna->kgem, dst_bo);
+	}
+
+	return ok;
+}
+
 static void
 sna_get_image(DrawablePtr drawable,
 	      int x, int y, int w, int h,
@@ -13709,6 +13766,7 @@ sna_get_image(DrawablePtr drawable,
 {
 	RegionRec region;
 	unsigned int flags;
+	bool can_blt;
 
 	if (!fbDrawableEnabled(drawable))
 		return;
@@ -13721,6 +13779,13 @@ sna_get_image(DrawablePtr drawable,
 	region.extents.y2 = region.extents.y1 + h;
 	region.data = NULL;
 
+	can_blt = format == ZPixmap &&
+		drawable->bitsPerPixel >= 8 &&
+		PM_IS_SOLID(drawable, mask);
+
+	if (can_blt && sna_get_image_blt(drawable, &region, dst))
+		return;
+
 	flags = MOVE_READ;
 	if ((w | h) == 1)
 		flags |= MOVE_INPLACE_HINT;
@@ -13729,9 +13794,7 @@ sna_get_image(DrawablePtr drawable,
 	if (!sna_drawable_move_region_to_cpu(drawable, &region, flags))
 		return;
 
-	if (format == ZPixmap &&
-	    drawable->bitsPerPixel >= 8 &&
-	    PM_IS_SOLID(drawable, mask)) {
+	if (can_blt) {
 		PixmapPtr pixmap = get_drawable_pixmap(drawable);
 		int16_t dx, dy;
 


More information about the xorg-commit mailing list