xf86-video-intel: 5 commits - src/sna/gen3_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/sna_accel.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Sep 25 03:54:16 PDT 2013


 src/sna/gen3_render.c |   47 --------------
 src/sna/gen5_render.c |   28 --------
 src/sna/gen6_render.c |    8 ++
 src/sna/gen7_render.c |    8 ++
 src/sna/kgem.c        |   34 ++++++++--
 src/sna/sna_accel.c   |  157 ++++++++++++++++++++++++++++++--------------------
 6 files changed, 136 insertions(+), 146 deletions(-)

New commits:
commit 598dae9af99495cb738c6ddbe8602f8fa19dc0df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Sep 25 10:53:11 2013 +0100

    sna/gen[35]: Remove dead code for choosing between BLT/render composite
    
    For these gen, we always want to use BLT where possible - even if it
    incurs a context switch.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index cb8f046..4c058e1 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3119,52 +3119,6 @@ gen3_composite_picture(struct sna *sna,
 				    x, y, w, h, dst_x, dst_y);
 }
 
-static inline bool
-source_use_blt(struct sna *sna, PicturePtr picture)
-{
-	/* If it is a solid, try to use the BLT paths */
-	if (!picture->pDrawable)
-		return picture->pSourcePict->type == SourcePictTypeSolidFill;
-
-	if (picture->pDrawable->width  == 1 &&
-	    picture->pDrawable->height == 1 &&
-	    picture->repeat)
-		return true;
-
-	if (too_large(picture->pDrawable->width, picture->pDrawable->height))
-		return true;
-
-	return !is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER);
-}
-
-static bool
-try_blt(struct sna *sna,
-	PicturePtr dst,
-	PicturePtr src,
-	int width, int height)
-{
-	if (sna->kgem.mode != KGEM_RENDER) {
-		DBG(("%s: already performing BLT\n", __FUNCTION__));
-		return true;
-	}
-
-	if (too_large(width, height)) {
-		DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
-		     __FUNCTION__, width, height));
-		return true;
-	}
-
-	if (too_large(dst->pDrawable->width, dst->pDrawable->height)) {
-		DBG(("%s: target too large for 3D pipe (%d, %d)\n",
-		     __FUNCTION__,
-		     dst->pDrawable->width, dst->pDrawable->height));
-		return true;
-	}
-
-	/* is the source picture only in cpu memory e.g. a shm pixmap? */
-	return source_use_blt(sna, src);
-}
-
 static void
 gen3_align_vertex(struct sna *sna,
 		  const struct sna_composite_op *op)
@@ -3530,7 +3484,6 @@ gen3_render_composite(struct sna *sna,
 	 * 3D -> 2D context switch.
 	 */
 	if (mask == NULL &&
-	    try_blt(sna, dst, src, width, height) &&
 	    sna_blt_composite(sna,
 			      op, src, dst,
 			      src_x, src_y,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 7e336f0..c625639 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1611,33 +1611,6 @@ gen5_composite_set_target(struct sna *sna,
 }
 
 static bool
-try_blt(struct sna *sna,
-	PicturePtr dst, PicturePtr src,
-	int width, int height)
-{
-	if (sna->kgem.mode != KGEM_RENDER) {
-		DBG(("%s: already performing BLT\n", __FUNCTION__));
-		return true;
-	}
-
-	if (too_large(width, height)) {
-		DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
-		     __FUNCTION__, width, height));
-		return true;
-	}
-
-	if (too_large(dst->pDrawable->width, dst->pDrawable->height))
-		return true;
-
-	/* The blitter is much faster for solids */
-	if (sna_picture_is_solid(src, NULL))
-		return true;
-
-	/* is the source picture only in cpu memory e.g. a shm pixmap? */
-	return picture_is_cpu(sna, src);
-}
-
-static bool
 is_gradient(PicturePtr picture, bool precise)
 {
 	if (picture->pDrawable)
@@ -1868,7 +1841,6 @@ gen5_render_composite(struct sna *sna,
 	}
 
 	if (mask == NULL &&
-	    try_blt(sna, dst, src, width, height) &&
 	    sna_blt_composite(sna, op,
 			      src, dst,
 			      src_x, src_y,
commit 3a05b1a4aa96f4d4484e7397b8e8d901819a3799
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Sep 25 10:52:17 2013 +0100

    sna/gen6+: Fallback to BLT composite if fallback is forced
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 1f15091..b014e9e 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2267,7 +2267,13 @@ gen6_render_composite(struct sna *sna,
 		return true;
 
 	if (gen6_composite_fallback(sna, src, mask, dst))
-		return false;
+		return (mask == NULL &&
+			sna_blt_composite(sna, op,
+					  src, dst,
+					  src_x, src_y,
+					  dst_x, dst_y,
+					  width, height,
+					  tmp, true));
 
 	if (need_tiling(sna, width, height))
 		return sna_tiling_composite(op, src, mask, dst,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 6f2e3ab..1b5e607 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2518,7 +2518,13 @@ gen7_render_composite(struct sna *sna,
 		return true;
 
 	if (gen7_composite_fallback(sna, src, mask, dst))
-		return false;
+		return (mask == NULL &&
+			sna_blt_composite(sna, op,
+					src, dst,
+					src_x, src_y,
+					dst_x, dst_y,
+					width, height,
+					tmp, true));
 
 	if (need_tiling(sna, width, height))
 		return sna_tiling_composite(op, src, mask, dst,
commit 5dfe9217f21870c2b3563fb2337254db316eea72
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Sep 24 13:48:28 2013 +0100

    sna: Clear CPU damage when uploading partial images inplace
    
    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 76a917c..7c03c61 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4051,20 +4051,26 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
 	if (priv == NULL)
 		return false;
 
-	if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL)
+	if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL) {
+		DBG(("%s: no, no gpu damage\n", __FUNCTION__));
 		return false;
+	}
 
 	assert(priv->gpu_bo);
 	assert(priv->gpu_bo->proxy == NULL);
 
-	if (priv->cow || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
+	if (priv->cow || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
+		DBG(("%s: no, target is idle\n", __FUNCTION__));
 		return false;
+	}
 
 	if (priv->cpu_damage &&
 	    sna_damage_contains_box__no_reduce(priv->cpu_damage,
 					       &region->extents) &&
-	    !box_inplace(pixmap, &region->extents))
+	    !box_inplace(pixmap, &region->extents)) {
+		DBG(("%s: no, damage on CPU and too small\n", __FUNCTION__));
 		return false;
+	}
 
 	src_bo = kgem_create_map(&sna->kgem, bits, stride * h, true);
 	if (src_bo == NULL)
@@ -4088,8 +4094,10 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
 	assert(src_bo->rq == NULL);
 	kgem_bo_destroy(&sna->kgem, src_bo);
 
-	if (!ok)
+	if (!ok) {
+		DBG(("%s: copy failed!\n", __FUNCTION__));
 		return false;
+	}
 
 	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 		assert(!priv->clear);
@@ -4105,9 +4113,12 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
 					      pixmap->drawable.width,
 					      pixmap->drawable.height);
 		}
-		if (DAMAGE_IS_ALL(priv->gpu_damage)) {
-			list_del(&priv->flush_list);
+		if (DAMAGE_IS_ALL(priv->gpu_damage))
 			sna_damage_destroy(&priv->cpu_damage);
+		else
+			sna_damage_subtract(&priv->cpu_damage, region);
+		if (priv->cpu_damage == NULL) {
+			list_del(&priv->flush_list);
 			sna_pixmap_free_cpu(sna, priv, priv->cpu);
 		}
 	}
@@ -4213,12 +4224,15 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 		} else {
 			sna_damage_add(&priv->gpu_damage, region);
 			sna_damage_reduce_all(&priv->gpu_damage,
-					pixmap->drawable.width,
-					pixmap->drawable.height);
+					      pixmap->drawable.width,
+					      pixmap->drawable.height);
 		}
-		if (DAMAGE_IS_ALL(priv->gpu_damage)) {
-			list_del(&priv->flush_list);
+		if (DAMAGE_IS_ALL(priv->gpu_damage))
 			sna_damage_destroy(&priv->cpu_damage);
+		else
+			sna_damage_subtract(&priv->cpu_damage, region);
+		if (priv->cpu_damage == NULL) {
+			list_del(&priv->flush_list);
 			sna_pixmap_free_cpu(sna, priv, priv->cpu);
 		}
 	}
commit 53b43673efed4d82b6dd498e9b76892e3e5b13e6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Sep 24 13:44:59 2013 +0100

    sna: Add some DBG for early flushes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b0e0477..d46f967 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4571,8 +4571,10 @@ bool kgem_check_bo(struct kgem *kgem, ...)
 		if (bo->exec)
 			continue;
 
-		if (needs_semaphore(kgem, bo))
+		if (needs_semaphore(kgem, bo)) {
+			DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
 			return false;
+		}
 
 		num_pages += num_pages(bo);
 		num_exec++;
@@ -4587,8 +4589,10 @@ bool kgem_check_bo(struct kgem *kgem, ...)
 	if (!num_pages)
 		return true;
 
-	if (kgem_flush(kgem, flush))
+	if (kgem_flush(kgem, flush)) {
+		DBG(("%s: opportunistic flushing\n", __FUNCTION__));
 		return false;
+	}
 
 	if (kgem->aperture > kgem->aperture_low &&
 	    kgem_ring_is_idle(kgem, kgem->ring)) {
@@ -4641,18 +4645,25 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 		return true;
 	}
 
-	if (needs_semaphore(kgem, bo))
+	if (needs_semaphore(kgem, bo)) {
+		DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
 		return false;
+	}
 
-	if (kgem_flush(kgem, bo->flush))
+	if (kgem_flush(kgem, bo->flush)) {
+		DBG(("%s: opportunistic flushing\n", __FUNCTION__));
 		return false;
+	}
 
 	if (kgem->nexec >= KGEM_EXEC_SIZE(kgem) - 1)
 		return false;
 
 	if (kgem->aperture > kgem->aperture_low &&
-	    kgem_ring_is_idle(kgem, kgem->ring))
+	    kgem_ring_is_idle(kgem, kgem->ring)) {
+		DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n",
+		     __FUNCTION__, kgem->aperture, kgem->aperture_low));
 		return false;
+	}
 
 	if (kgem->aperture + num_pages(bo) > kgem->aperture_high)
 		return false;
@@ -4703,8 +4714,10 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 			continue;
 		}
 
-		if (needs_semaphore(kgem, bo))
+		if (needs_semaphore(kgem, bo)) {
+			DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
 			return false;
+		}
 
 		assert_tiling(kgem, bo);
 		num_pages += num_pages(bo);
@@ -4731,12 +4744,17 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 	}
 
 	if (num_pages) {
-		if (kgem_flush(kgem, flush))
+		if (kgem_flush(kgem, flush)) {
+			DBG(("%s: opportunistic flushing\n", __FUNCTION__));
 			return false;
+		}
 
 		if (kgem->aperture > kgem->aperture_low &&
-		    kgem_ring_is_idle(kgem, kgem->ring))
+		    kgem_ring_is_idle(kgem, kgem->ring)) {
+			DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n",
+			     __FUNCTION__, kgem->aperture, kgem->aperture_low));
 			return false;
+		}
 
 		if (num_pages + kgem->aperture > kgem->aperture_high)
 			return false;
commit ad0390068832ad4727371902fe41a85a53de1894
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Sep 24 10:00:03 2013 +0100

    sna: Separate out copy preferrence from operating in place decision
    
    The two decision trees are no longer identical.
    
    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 fb8a228..76a917c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3195,6 +3195,11 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
 	if (priv->cpu && (flags & (FORCE_GPU | IGNORE_CPU)) == 0)
 		flags &= ~PREFER_GPU;
 
+	if ((flags & (PREFER_GPU | IGNORE_CPU)) == IGNORE_CPU) {
+		if (box_inplace(pixmap, box))
+			flags |= PREFER_GPU;
+	}
+
 	DBG(("%s: flush=%d, shm=%d, cpu=%d => flags=%x\n",
 	     __FUNCTION__, priv->flush, priv->shm, priv->cpu, flags));
 
@@ -4690,6 +4695,9 @@ source_contains_region(struct sna_damage *damage,
 	if (DAMAGE_IS_ALL(damage))
 		return true;
 
+	if (damage == NULL)
+		return false;
+
 	box = region->extents;
 	box.x1 += dx;
 	box.x2 += dx;
@@ -4954,39 +4962,46 @@ sna_pixmap_is_gpu(PixmapPtr pixmap)
 }
 
 static int
-source_prefer_gpu(struct sna *sna, struct sna_pixmap *priv,
-		  RegionRec *region, int16_t dx, int16_t dy)
+copy_prefer_gpu(struct sna *sna,
+		struct sna_pixmap *dst_priv,
+		struct sna_pixmap *src_priv,
+		RegionRec *region,
+		int16_t dx, int16_t dy)
 {
-	if (priv == NULL) {
+	assert(dst_priv);
+
+	if (wedged(sna) && !dst_priv->pinned)
+		return 0;
+
+	if (src_priv == NULL) {
 		DBG(("%s: source unattached, use cpu\n", __FUNCTION__));
 		return 0;
 	}
 
-	if (priv->clear) {
+	if (src_priv->clear) {
 		DBG(("%s: source is clear, don't force use of GPU\n", __FUNCTION__));
 		return 0;
 	}
 
-	if (priv->gpu_damage &&
-	    (priv->cpu_damage == NULL ||
-	     !source_contains_region(priv->cpu_damage, region, dx, dy))) {
+	if (src_priv->gpu_damage &&
+	    !source_contains_region(src_priv->cpu_damage, region, dx, dy)) {
 		DBG(("%s: source has gpu damage, force gpu? %d\n",
-		     __FUNCTION__, priv->cpu_damage == NULL));
-		assert(priv->gpu_bo);
-		return priv->cpu_damage ? PREFER_GPU : PREFER_GPU | FORCE_GPU;
+		     __FUNCTION__, src_priv->cpu_damage == NULL));
+		assert(src_priv->gpu_bo);
+		return src_priv->cpu_damage ? PREFER_GPU : PREFER_GPU | FORCE_GPU;
 	}
 
-	if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) {
+	if (src_priv->cpu_bo && kgem_bo_is_busy(src_priv->cpu_bo)) {
 		DBG(("%s: source has busy CPU bo, force gpu\n", __FUNCTION__));
 		return PREFER_GPU | FORCE_GPU;
 	}
 
-	if (DAMAGE_IS_ALL(priv->cpu_damage))
-		return priv->cpu_bo && kgem_is_idle(&sna->kgem);
+	if (source_contains_region(src_priv->cpu_damage, region, dx, dy))
+		return src_priv->cpu_bo && kgem_is_idle(&sna->kgem);
 
 	DBG(("%s: source has GPU bo? %d\n",
-	     __FUNCTION__, priv->gpu_bo != NULL));
-	return priv->gpu_bo != NULL;
+	     __FUNCTION__, src_priv->gpu_bo != NULL));
+	return src_priv->gpu_bo != NULL;
 }
 
 static bool use_shm_bo(struct sna *sna,
@@ -5161,6 +5176,22 @@ sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
 	return true;
 }
 
+static void discard_cpu_damage(struct sna *sna, struct sna_pixmap *priv)
+{
+	DBG(("%s: discarding existing CPU damage\n", __FUNCTION__));
+	if (priv->gpu_bo && priv->gpu_bo->proxy) {
+		assert(priv->gpu_damage == NULL);
+		assert(!priv->pinned);
+		kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+		priv->gpu_bo = NULL;
+	}
+	sna_damage_destroy(&priv->cpu_damage);
+	list_del(&priv->flush_list);
+
+	sna_pixmap_free_cpu(sna, priv, priv->cpu);
+	priv->cpu = false;
+}
+
 static void
 sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	       RegionPtr region, int dx, int dy,
@@ -5173,7 +5204,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	struct sna *sna = to_sna_from_pixmap(src_pixmap);
 	struct sna_damage **damage;
 	struct kgem_bo *bo;
-	unsigned hint;
 	int16_t src_dx, src_dy;
 	int16_t dst_dx, dst_dy;
 	BoxPtr box = RegionRects(region);
@@ -5233,26 +5263,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	if (dst_priv == NULL)
 		goto fallback;
 
-	hint = source_prefer_gpu(sna, src_priv, region, src_dx, src_dy) ?:
-		region_inplace(sna, dst_pixmap, region,
-			       dst_priv, alu_overwrites(alu) ? MOVE_WRITE : MOVE_READ | MOVE_WRITE);
-	if (dst_priv->cpu_damage && alu_overwrites(alu)) {
-		DBG(("%s: overwritting CPU damage\n", __FUNCTION__));
-		if (region_subsumes_damage(region, dst_priv->cpu_damage)) {
-			DBG(("%s: discarding existing CPU damage\n", __FUNCTION__));
-			if (dst_priv->gpu_bo && dst_priv->gpu_bo->proxy) {
-				assert(!dst_priv->pinned);
-				kgem_bo_destroy(&sna->kgem, dst_priv->gpu_bo);
-				dst_priv->gpu_bo = NULL;
-			}
-			sna_damage_destroy(&dst_priv->cpu_damage);
-			list_del(&dst_priv->flush_list);
-			dst_priv->cpu = false;
-		}
-	}
-	if (region->data == NULL && alu_overwrites(alu))
-		hint |= IGNORE_CPU;
-
 	/* XXX hack for firefox -- subsequent uses of src will be corrupt! */
 	if (src_priv &&
 	    COW(src_priv->cow) == COW(dst_priv->cow) &&
@@ -5262,9 +5272,24 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		assert(src_priv->cpu_damage == NULL);
 		bo = dst_priv->gpu_bo;
 		damage = NULL;
-	} else
+	} else {
+		unsigned hint = copy_prefer_gpu(sna, dst_priv, src_priv, region, src_dx, src_dy);
+		if (replaces) {
+			discard_cpu_damage(sna, dst_priv);
+			hint |= REPLACES | IGNORE_CPU;
+		} else if (alu_overwrites(alu)) {
+			if (region->data == NULL)
+				hint |= IGNORE_CPU;
+			if (dst_priv->cpu_damage &&
+			    region_subsumes_damage(region,
+						   dst_priv->cpu_damage)) {
+				discard_cpu_damage(sna, dst_priv);
+				hint |= IGNORE_CPU;
+			}
+		}
 		bo = sna_drawable_use_bo(&dst_pixmap->drawable, hint,
 					 &region->extents, &damage);
+	}
 	if (bo) {
 		if (src_priv && src_priv->clear) {
 			DBG(("%s: applying src clear [%08x] to dst\n",
@@ -12909,22 +12934,18 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 			RegionTranslate(&region, dx, dy);
 		}
 
-		if (priv->cpu_damage && (flags & 2) == 0) {
-			if (region_subsumes_damage(&region, priv->cpu_damage)) {
-				DBG(("%s: discarding existing CPU damage\n", __FUNCTION__));
-				if (priv->gpu_bo && priv->gpu_bo->proxy) {
-					assert(priv->gpu_damage == NULL);
-					assert(!priv->pinned);
-					kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
-					priv->gpu_bo = NULL;
-				}
-				sna_damage_destroy(&priv->cpu_damage);
-				list_del(&priv->flush_list);
+		if (region_subsumes_drawable(&region, &pixmap->drawable)) {
+			discard_cpu_damage(sna, priv);
+			hint |= IGNORE_CPU | REPLACES;
+		} else {
+			if ((flags & 2) == 0)
+				hint |= IGNORE_CPU;
+			if (priv->cpu_damage &&
+			    region_subsumes_damage(&region, priv->cpu_damage)) {
+				discard_cpu_damage(sna, priv);
+				hint |= IGNORE_CPU;
 			}
-			hint |= IGNORE_CPU;
 		}
-		if (region_subsumes_drawable(&region, &pixmap->drawable))
-			hint |= REPLACES;
 		if (priv->cpu_damage == NULL) {
 			if (priv->gpu_bo &&
 			    (hint & REPLACES || box_inplace(pixmap, &region.extents))) {


More information about the xorg-commit mailing list