xf86-video-intel: 5 commits - src/sna/sna_accel.c src/sna/sna_damage.c src/sna/sna_dri.c src/sna/sna.h src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Jul 1 06:53:31 PDT 2012


 src/sna/sna.h            |    1 +
 src/sna/sna_accel.c      |   38 +++++++++++++++++++++++++++++++++++++-
 src/sna/sna_damage.c     |    9 +++++++--
 src/sna/sna_dri.c        |    4 ++++
 src/sna/sna_trapezoids.c |   10 ++++++----
 5 files changed, 55 insertions(+), 7 deletions(-)

New commits:
commit fbd114507d9bf2e2b1d1e52c5e42dc6cdbd8c9a0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 1 14:03:31 2012 +0100

    sna/dri: Assert that the replacement bo is large enough for the pixmap
    
    Just another paranoid sanity check.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index f01de17..93e24b8 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1147,6 +1147,9 @@ sna_dri_exchange_buffers(DrawablePtr draw,
 	back_bo = get_private(back)->bo;
 	front_bo = get_private(front)->bo;
 
+	assert(pixmap->drawable.height * back_bo->pitch <= kgem_bo_size(back_bo));
+	assert(pixmap->drawable.height * front_bo->pitch <= kgem_bo_size(front_bo));
+
 	DBG(("%s: exchange front=%d/%d and back=%d/%d\n",
 	     __FUNCTION__,
 	     front_bo->handle, front->name,
@@ -1335,6 +1338,7 @@ sna_dri_flip_continue(struct sna *sna,
 
 	name = info->back->name;
 	bo = get_private(info->back)->bo;
+	assert(get_drawable_pixmap(draw)->drawable.height * bo->pitch <= kgem_bo_size(bo));
 
 	info->count = sna_page_flip(sna, bo, info, info->pipe, &info->old_fb);
 	if (info->count == 0)
commit 675cbd5fade91fd6a6bf533a31b0a211237af6e8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 1 12:39:13 2012 +0100

    sna/trapezoids: Skip the division when converting coverage to floating point
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 7bbe270..36defa1 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -2770,6 +2770,7 @@ composite_unaligned_trap_row(struct sna *sna,
 	BoxRec box;
 	int opacity;
 	int x1, x2;
+#define u8_to_float(x) ((x) * (1.f/255))
 
 	if (covered == 0)
 		return;
@@ -2800,7 +2801,7 @@ composite_unaligned_trap_row(struct sna *sna,
 
 		if (opacity)
 			composite_unaligned_box(sna, tmp, &box,
-						opacity/255., clip);
+						u8_to_float(opacity), clip);
 	} else {
 		if (pixman_fixed_frac(trap->left.p1.x)) {
 			box.x1 = x1;
@@ -2811,7 +2812,7 @@ composite_unaligned_trap_row(struct sna *sna,
 
 			if (opacity)
 				composite_unaligned_box(sna, tmp, &box,
-							opacity/255., clip);
+							u8_to_float(opacity), clip);
 		}
 
 		if (x2 > x1) {
@@ -2819,7 +2820,8 @@ composite_unaligned_trap_row(struct sna *sna,
 			box.x2 = x2;
 
 			composite_unaligned_box(sna, tmp, &box,
-						covered*SAMPLES_X/255., clip);
+						covered == SAMPLES_Y ? 1. : u8_to_float(covered*SAMPLES_X),
+						clip);
 		}
 
 		if (pixman_fixed_frac(trap->right.p1.x)) {
@@ -2831,7 +2833,7 @@ composite_unaligned_trap_row(struct sna *sna,
 
 			if (opacity)
 				composite_unaligned_box(sna, tmp, &box,
-							opacity/255., clip);
+							u8_to_float(opacity), clip);
 		}
 	}
 }
commit 182c3637cc5d3a6ce52127087aa2f19ca2b42719
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 1 13:23:44 2012 +0100

    sna: If the pixmap is marked for flushing, prefer to use the GPU
    
    Again, to avoid the forced ping-pong as we upload the damage after
    nearly every operation, simply prefer to use the GPU in such cases.
    
    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 cb507c1..c4dbe12 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2219,6 +2219,8 @@ sna_drawable_use_bo(DrawablePtr drawable,
 		goto use_cpu_bo;
 	}
 
+	if (priv->flush)
+		prefer_gpu = true;
 	if (priv->cpu)
 		prefer_gpu = false;
 
commit 35b1ac138002c206a6d6b866d49a0d73705dd3ac
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 1 10:53:07 2012 +0100

    sna: After an operation on the CPU, prefer not to use the GPU
    
    A nasty habit of applications is to fill an area, only to read it back
    with GetImage, render locally and replace with PutImage. This causes a
    readback of an active bo everytime, so let's try to mitigate that by
    preferring not to use the GPU after a forced readback.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 66ee6c0..9d36543 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -140,6 +140,7 @@ struct sna_pixmap {
 	uint8_t undamaged :1;
 	uint8_t create :3;
 	uint8_t header :1;
+	uint8_t cpu :1;
 };
 
 struct sna_glyph {
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index d280f84..cb507c1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1108,6 +1108,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 				       pixmap->drawable.height);
 			sna_damage_destroy(&priv->cpu_damage);
 			priv->undamaged = false;
+			priv->cpu = false;
 			list_del(&priv->list);
 			if (priv->cpu_bo) {
 				assert(!priv->cpu_bo->sync);
@@ -1134,6 +1135,7 @@ skip_inplace_map:
 					list_del(&priv->list);
 					priv->undamaged = false;
 				}
+				priv->cpu = false;
 				assert(!priv->cpu_bo->sync);
 				sna_pixmap_free_cpu(sna, priv);
 			}
@@ -1167,6 +1169,7 @@ skip_inplace_map:
 				list_del(&priv->list);
 				priv->undamaged = false;
 				priv->clear = false;
+				priv->cpu = false;
 			}
 
 			assert_pixmap_damage(pixmap);
@@ -1266,6 +1269,7 @@ done:
 		DBG(("%s: syncing CPU bo\n", __FUNCTION__));
 		kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
 	}
+	priv->cpu = true;
 	assert(pixmap->devPrivate.ptr);
 	assert(pixmap->devKind);
 	assert_pixmap_damage(pixmap);
@@ -1369,6 +1373,11 @@ static inline bool region_inplace(struct sna *sna,
 	if (wedged(sna))
 		return false;
 
+	if (priv->cpu) {
+		DBG(("%s: no, preferring last action of CPU\n", __FUNCTION__));
+		return false;
+	}
+
 	if (!write_only && priv->cpu_damage &&
 	    region_overlaps_damage(region, priv->cpu_damage)) {
 		DBG(("%s: no, uncovered CPU damage pending\n", __FUNCTION__));
@@ -1504,6 +1513,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 						       region);
 
 				priv->clear = false;
+				priv->cpu = false;
 				assert_pixmap_damage(pixmap);
 				if (dx | dy)
 					RegionTranslate(region, -dx, -dy);
@@ -1553,6 +1563,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 
 			assert_pixmap_damage(pixmap);
 			priv->clear = false;
+			priv->cpu = false;
 			if (dx | dy)
 				RegionTranslate(region, -dx, -dy);
 			return true;
@@ -1587,6 +1598,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 			}
 			assert_pixmap_damage(pixmap);
 			priv->clear = false;
+			priv->cpu = false;
 			if (dx | dy)
 				RegionTranslate(region, -dx, -dy);
 			return true;
@@ -1871,10 +1883,11 @@ out:
 		priv->source_count = SOURCE_BIAS;
 		assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 	}
-	if (priv->cpu_bo) {
+	if ((flags & MOVE_ASYNC_HINT) == 0 && priv->cpu_bo) {
 		DBG(("%s: syncing cpu bo\n", __FUNCTION__));
 		kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
 	}
+	priv->cpu = true;
 	assert(pixmap->devPrivate.ptr);
 	assert(pixmap->devKind);
 	assert_pixmap_damage(pixmap);
@@ -2206,6 +2219,9 @@ sna_drawable_use_bo(DrawablePtr drawable,
 		goto use_cpu_bo;
 	}
 
+	if (priv->cpu)
+		prefer_gpu = false;
+
 	if (!prefer_gpu && priv->gpu_bo && !kgem_bo_is_busy(priv->gpu_bo))
 		goto use_cpu_bo;
 
@@ -2457,6 +2473,7 @@ sna_pixmap_mark_active(struct sna *sna, struct sna_pixmap *priv)
 	    (priv->create & KGEM_CAN_CREATE_LARGE) == 0)
 		list_move(&priv->inactive, &sna->active_pixmaps);
 	priv->clear = false;
+	priv->cpu = false;
 	return priv;
 }
 
@@ -2527,6 +2544,8 @@ sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags)
 	if (!sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE))
 		return NULL;
 
+	assert(!priv->cpu);
+
 	/* For large bo, try to keep only a single copy around */
 	if (priv->create & KGEM_CAN_CREATE_LARGE && priv->ptr) {
 		sna_damage_all(&priv->gpu_damage,
@@ -2986,6 +3005,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 	if (upload_inplace(sna, pixmap, priv, region) &&
 	    sna_put_image_upload_blt(drawable, gc, region,
 				     x, y, w, h, bits, stride)) {
+		assert(priv->cpu == false);
 		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 			DBG(("%s: marking damage\n", __FUNCTION__));
 			if (region_subsumes_drawable(region, &pixmap->drawable))
@@ -3055,6 +3075,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 
 					assert_pixmap_damage(pixmap);
 					priv->clear = false;
+					priv->cpu = false;
 					return true;
 				}
 			} else {
@@ -3124,6 +3145,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		sna_pixmap_free_gpu(sna, priv);
 		priv->undamaged = false;
 		priv->clear = false;
+		priv->cpu = false;
 	}
 
 	if (!DAMAGE_IS_ALL(priv->cpu_damage)) {
@@ -3150,6 +3172,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		if (priv->flush)
 			list_move(&priv->list, &sna->dirty_pixmaps);
 	}
+	priv->cpu = true;
 
 blt:
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
@@ -3832,6 +3855,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		list_del(&dst_priv->list);
 		dst_priv->undamaged = true;
 		dst_priv->clear = false;
+		dst_priv->cpu = false;
 	}
 
 	if (src_priv == NULL &&
@@ -3913,6 +3937,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				fill.done(sna, &fill);
 			}
 
+			dst_priv->cpu = false;
 			if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
 				if (replaces) {
 					sna_damage_destroy(&dst_priv->cpu_damage);
@@ -3946,6 +3971,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				goto fallback;
 			}
 
+			dst_priv->cpu = false;
 			if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
 				if (replaces) {
 					sna_damage_destroy(&dst_priv->cpu_damage);
@@ -3973,6 +3999,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				goto fallback;
 			}
 
+			dst_priv->cpu = false;
 			if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
 				if (replaces) {
 					sna_damage_destroy(&dst_priv->cpu_damage);
@@ -4042,6 +4069,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			}
 			tmp->drawable.pScreen->DestroyPixmap(tmp);
 
+			dst_priv->cpu = false;
 			if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
 				RegionTranslate(&region, dst_dx, dst_dy);
 				assert_pixmap_contains_box(dst_pixmap,
@@ -4076,6 +4104,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 						 bits, stride))
 					goto fallback;
 
+				dst_priv->cpu = false;
 				if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
 					sna_damage_destroy(&dst_priv->cpu_damage);
 					sna_damage_all(&dst_priv->gpu_damage,
@@ -4096,6 +4125,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 						     box, n))
 					goto fallback;
 
+				dst_priv->cpu = false;
 				if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
 					if (replaces) {
 						sna_damage_destroy(&dst_priv->cpu_damage);
@@ -4130,6 +4160,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			goto fallback;
 		}
 
+		dst_priv->cpu = true;
 		if (replaces) {
 			sna_damage_all(&dst_priv->cpu_damage,
 				       dst_pixmap->drawable.width,
@@ -10492,6 +10523,8 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 		if (region_subsumes_damage(&region, priv->cpu_damage)) {
 			sna_damage_destroy(&priv->cpu_damage);
 			list_del(&priv->list);
+			priv->undamaged = false;
+			priv->cpu = false;
 		}
 	}
 
@@ -12598,6 +12631,7 @@ static void sna_accel_inactive(struct sna *sna)
 			assert(priv->cpu_bo == NULL || !priv->cpu_bo->sync);
 			sna_pixmap_free_cpu(sna, priv);
 			priv->undamaged = false;
+			priv->cpu = false;
 
 			list_add(&priv->inactive, &preserve);
 		} else {
commit e625c02e6266403fcd8a72ccce2c6c6291e2e5fc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 30 09:34:21 2012 +0100

    sna/damage: Early check for contains-box? if subtract and box outside region
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index ce16b77..745e2d1 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -1260,8 +1260,13 @@ static int __sna_damage_contains_box(struct sna_damage *damage,
 	if (!damage->dirty)
 		return ret;
 
-	if (damage->mode == DAMAGE_ADD && ret == PIXMAN_REGION_IN)
-		return ret;
+	if (damage->mode == DAMAGE_ADD) {
+		if (ret == PIXMAN_REGION_IN)
+			return ret;
+	} else {
+		if (ret == PIXMAN_REGION_OUT)
+			return ret;
+	}
 
 	__sna_damage_reduce(damage);
 	return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);


More information about the xorg-commit mailing list