xf86-video-intel: 7 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_render.c src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Jul 16 06:51:19 PDT 2012


 src/sna/kgem.c           |   49 +++++++++++++++++++++++++-----
 src/sna/sna_accel.c      |   75 ++++++++++++++++++++++++++++-------------------
 src/sna/sna_render.c     |    3 +
 src/sna/sna_trapezoids.c |   25 ++++++++++++---
 4 files changed, 109 insertions(+), 43 deletions(-)

New commits:
commit 907a2a7c97514d3f7610648ed87c7042a857f786
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 14:47:03 2012 +0100

    sna/trapezoids: Fix inplace unaligned fills (on gen4)
    
    Reported-by: Sergio Callegari <sergio.callegari at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=52150
    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 1261e9b..634423e 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -3054,7 +3054,7 @@ lerp32_unaligned_box_row(PixmapPtr scratch, uint32_t color,
 	DBG(("%s: x=(%d.%d, %d.%d), y=%dx%d, covered=%d\n", __FUNCTION__,
 	     x1, fx1, x2, fx2, y, h, covered));
 
-	if (x2 < x1) {
+	if (x1 < x2) {
 		if (fx1) {
 			lerp32_opacity(scratch, color,
 				       x1, 1,
commit 6ce2f40249231f57cf464361ea5329cee1932ccf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 14:46:39 2012 +0100

    sna/trapezoids: Add some DBG to unaligned fills
    
    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 1553f58..1261e9b 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -3043,14 +3043,17 @@ lerp32_unaligned_box_row(PixmapPtr scratch, uint32_t color,
 {
 	int16_t x1 = pixman_fixed_to_int(trap->left.p1.x) + dx;
 	int16_t fx1 = grid_coverage(SAMPLES_X, trap->left.p1.x);
-	int16_t x2 = pixman_fixed_to_int(trap->right.p1.x) + dx;
-	int16_t fx2 = grid_coverage(SAMPLES_X, trap->right.p1.x);
+	int16_t x2 = pixman_fixed_to_int(trap->right.p2.x) + dx;
+	int16_t fx2 = grid_coverage(SAMPLES_X, trap->right.p2.x);
 
 	if (x1 < extents->x1)
 		x1 = extents->x1, fx1 = 0;
 	if (x2 > extents->x2)
 		x2 = extents->x2, fx2 = 0;
 
+	DBG(("%s: x=(%d.%d, %d.%d), y=%dx%d, covered=%d\n", __FUNCTION__,
+	     x1, fx1, x2, fx2, y, h, covered));
+
 	if (x2 < x1) {
 		if (fx1) {
 			lerp32_opacity(scratch, color,
@@ -3185,6 +3188,7 @@ composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color,
 	if (!(dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8)) {
 		DBG(("%s: fallback -- can not perform operation in place, unhanbled format %08lx\n",
 		     __FUNCTION__, (long)dst->format));
+
 		goto pixman;
 	}
 
@@ -3193,7 +3197,7 @@ composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color,
 
 	if (op == PictOpOver && (color >> 24) == 0xff)
 		op = PictOpSrc;
-	if (op == PictOpOver) {
+	if (op == PictOpOver || op == PictOpAdd) {
 		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		if (priv && priv->clear && priv->clear_color == 0)
 			op = PictOpSrc;
@@ -3208,7 +3212,8 @@ composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color,
 		goto pixman;
 	}
 
-	DBG(("%s: inplace operation on argb32 destination\n", __FUNCTION__));
+	DBG(("%s: inplace operation on argb32 destination x %d\n",
+	     __FUNCTION__, n));
 	do {
 		RegionRec clip;
 		BoxPtr extents;
@@ -3244,10 +3249,20 @@ composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color,
 			int16_t y2 = dy + pixman_fixed_to_int(t->bottom);
 			int16_t fy2 = pixman_fixed_frac(t->bottom);
 
+			DBG(("%s: t=(%d, %d), (%d, %d), extents (%d, %d), (%d, %d)\n",
+			     __FUNCTION__,
+			     pixman_fixed_to_int(t->left.p1.x),
+			     pixman_fixed_to_int(t->top),
+			     pixman_fixed_to_int(t->right.p2.x),
+			     pixman_fixed_to_int(t->bottom),
+			     extents->x1, extents->y1,
+			     extents->x2, extents->y2));
+
 			if (y1 < extents->y1)
 				y1 = extents->y1, fy1 = 0;
 			if (y2 > extents->y2)
 				y2 = extents->y2, fy2 = 0;
+
 			if (y1 < y2) {
 				if (fy1) {
 					lerp32_unaligned_box_row(pixmap, color, extents,
commit 2721214868685123c973970a8ce0d93346ae0ee2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 13:52:39 2012 +0100

    sna: Move the disabling of CPU bo for gen4 to the render unit
    
    They appear to work fine with the BLT and only seem to cause issues when
    used with the sammpler. So enable them for accelerated uploads and
    downloads.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 93a0f94..51fc29d 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -687,9 +687,6 @@ static bool test_has_cache_level(struct kgem *kgem)
 	if (DBG_NO_CACHE_LEVEL)
 		return false;
 
-	if (kgem->gen == 40) /* XXX sampler dies with snoopable memory */
-		return false;
-
 	handle = gem_create(kgem->fd, 1);
 	if (handle == 0)
 		return false;
@@ -708,9 +705,6 @@ static bool test_has_vmap(struct kgem *kgem)
 	if (DBG_NO_VMAP)
 		return false;
 
-	if (kgem->gen == 40)
-		return false;
-
 	return gem_param(kgem, I915_PARAM_HAS_VMAP) > 0;
 #else
 	return false;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index dcfab91..ab7fb81 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -301,6 +301,9 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box)
 		return NULL;
 	}
 
+	if (sna->kgem.gen == 40) /* XXX sampler dies with snoopable memory */
+		return NULL;
+
 	if (priv->gpu_bo) {
 		switch (sna_damage_contains_box(priv->cpu_damage, box)) {
 		case PIXMAN_REGION_OUT:
commit 0777b146bf1a63c99e4d4af141e676a47b1f2dc9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 13:11:07 2012 +0100

    sna: Use set-cache-level to allocate snoopable upload buffers
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f85b5af..93a0f94 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3123,6 +3123,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
 			return NULL;
 
 		bo->reusable = false;
+		bo->vmap = true;
 		if (!gem_set_cache_level(kgem->fd, bo->handle, I915_CACHE_LLC) ||
 		    kgem_bo_map__cpu(kgem, bo) == NULL) {
 			kgem_bo_destroy(kgem, bo);
@@ -4055,15 +4056,51 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 			}
 		}
 	}
-#else
-	flags &= ~KGEM_BUFFER_INPLACE;
 #endif
 	/* Be more parsimonious with pwrite/pread buffers */
 	if ((flags & KGEM_BUFFER_INPLACE) == 0)
 		alloc = NUM_PAGES(size);
 	flags &= ~KGEM_BUFFER_INPLACE;
 
-	if (kgem->has_vmap) {
+	if (flags & KGEM_BUFFER_WRITE && kgem->has_cache_level) {
+		uint32_t handle;
+
+		handle = gem_create(kgem->fd, alloc);
+		if (handle == 0)
+			return NULL;
+
+		if (!gem_set_cache_level(kgem->fd, handle, I915_CACHE_LLC)) {
+			gem_close(kgem->fd, handle);
+			return NULL;
+		}
+
+		bo = malloc(sizeof(*bo));
+		if (bo == NULL) {
+			gem_close(kgem->fd, handle);
+			return NULL;
+		}
+
+		debug_alloc(kgem, alloc);
+		__kgem_bo_init(&bo->base, handle, alloc);
+		DBG(("%s: created handle=%d for buffer\n",
+		     __FUNCTION__, bo->base.handle));
+
+		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
+		if (bo->mem) {
+			bo->mmapped = true;
+			bo->need_io = false;
+			bo->base.io = true;
+			bo->base.reusable = false;
+			bo->base.vmap = true;
+			goto init;
+		} else {
+			bo->base.refcnt = 0; /* for valgrind */
+			kgem_bo_free(kgem, &bo->base);
+			bo = NULL;
+		}
+	}
+
+	if (flags & KGEM_BUFFER_WRITE && kgem->has_vmap) {
 		bo = partial_bo_alloc(alloc);
 		if (bo) {
 			uint32_t handle = gem_vmap(kgem->fd, bo->mem,
commit 33443f7ee48fa54b6f4d09c93cddac0e32314b9c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 12:51:54 2012 +0100

    sna: Add a couple of DBG options to control accelerated up/downloads
    
    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 3391a37..6d7f51c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -63,6 +63,8 @@
 #define USE_SHM_VMAP 0
 
 #define MIGRATE_ALL 0
+#define DBG_NO_CPU_UPLOAD 0
+#define DBG_NO_CPU_DOWNLOAD 0
 
 #define ACCEL_FILL_SPANS 1
 #define ACCEL_SET_SPANS 1
@@ -1071,15 +1073,16 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap)
 static inline bool use_cpu_bo_for_download(struct sna *sna,
 					   struct sna_pixmap *priv)
 {
+	if (DBG_NO_CPU_DOWNLOAD)
+		return false;
+
 	return priv->cpu_bo != NULL && sna->kgem.can_blt_cpu;
 }
 
 static inline bool use_cpu_bo_for_upload(struct sna_pixmap *priv)
 {
-#if 0
-	if (pixmap->devPrivate.ptr == NULL)
-		return true;
-#endif
+	if (DBG_NO_CPU_UPLOAD)
+		return false;
 
 	if (priv->cpu_bo == NULL)
 		return false;
commit 924060293826a1cc0d9d7bc26e913e46c6b2d054
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 12:03:47 2012 +0100

    sna: Discard and recreate the CPU buffer when busy during move-to-cpu
    
    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 b231c51..3391a37 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1127,8 +1127,6 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 		assert(flags & MOVE_WRITE);
 		DBG(("%s: no readbck, discarding gpu damage [%d], pending clear[%d]\n",
 		     __FUNCTION__, priv->gpu_damage != NULL, priv->clear));
-		sna_damage_destroy(&priv->gpu_damage);
-		priv->clear = false;
 
 		if (priv->create & KGEM_CAN_CREATE_GPU &&
 		    pixmap_inplace(sna, pixmap, priv)) {
@@ -1165,6 +1163,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 				       pixmap->drawable.height);
 			sna_damage_destroy(&priv->cpu_damage);
 			priv->undamaged = false;
+			priv->clear = false;
 			priv->cpu = false;
 			list_del(&priv->list);
 			if (priv->cpu_bo) {
@@ -1177,23 +1176,20 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 		}
 
 skip_inplace_map:
+		sna_damage_destroy(&priv->gpu_damage);
 		if (priv->cpu_bo && !priv->cpu_bo->sync && kgem_bo_is_busy(priv->cpu_bo)) {
 			if (priv->cpu_bo->exec == NULL)
 				kgem_retire(&sna->kgem);
 
 			if (kgem_bo_is_busy(priv->cpu_bo)) {
 				DBG(("%s: discarding busy CPU bo\n", __FUNCTION__));
+				assert(priv->gpu_bo);
+				assert(priv->gpu_damage == NULL);
+
 				sna_damage_destroy(&priv->cpu_damage);
-				list_del(&priv->list);
-				if (priv->undamaged) {
-					sna_damage_all(&priv->gpu_damage,
-						       pixmap->drawable.width,
-						       pixmap->drawable.height);
-					list_del(&priv->list);
-					priv->undamaged = false;
-				}
-				priv->cpu = false;
-				assert(!priv->cpu_bo->sync);
+				priv->undamaged = false;
+
+				sna_pixmap_free_gpu(sna, priv);
 				sna_pixmap_free_cpu(sna, priv);
 			}
 		}
commit 7024ef771ff170e61e788b5216c86b46e0f8ae6a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 16 12:15:54 2012 +0100

    sna: Add a few DBG to show when CPU bos are being used for xfer
    
    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 1734a8f..b231c51 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1068,13 +1068,13 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap)
 	return priv->gpu_bo && kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo);
 }
 
-static inline bool use_cpu_bo_for_write(struct sna *sna,
-					struct sna_pixmap *priv)
+static inline bool use_cpu_bo_for_download(struct sna *sna,
+					   struct sna_pixmap *priv)
 {
 	return priv->cpu_bo != NULL && sna->kgem.can_blt_cpu;
 }
 
-static inline bool use_cpu_bo_for_read(struct sna_pixmap *priv)
+static inline bool use_cpu_bo_for_upload(struct sna_pixmap *priv)
 {
 #if 0
 	if (pixmap->devPrivate.ptr == NULL)
@@ -1287,11 +1287,13 @@ skip_inplace_map:
 		if (n) {
 			bool ok = false;
 
-			if (use_cpu_bo_for_write(sna, priv))
+			if (use_cpu_bo_for_download(sna, priv)) {
+				DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
 				ok = sna->render.copy_boxes(sna, GXcopy,
 							    pixmap, priv->gpu_bo, 0, 0,
 							    pixmap, priv->cpu_bo, 0, 0,
 							    box, n, COPY_LAST);
+			}
 			if (!ok)
 				sna_read_boxes(sna,
 					       priv->gpu_bo, 0, 0,
@@ -1746,11 +1748,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 			assert(pixmap_contains_damage(pixmap, priv->gpu_damage));
 
 			ok = false;
-			if (use_cpu_bo_for_write(sna, priv))
+			if (use_cpu_bo_for_download(sna, priv)) {
+				DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
 				ok = sna->render.copy_boxes(sna, GXcopy,
 							    pixmap, priv->gpu_bo, 0, 0,
 							    pixmap, priv->cpu_bo, 0, 0,
 							    box, n, COPY_LAST);
+			}
 			if (!ok)
 				sna_read_boxes(sna,
 					       priv->gpu_bo, 0, 0,
@@ -1854,11 +1858,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 				if (n) {
 					bool ok = false;
 
-					if (use_cpu_bo_for_write(sna, priv))
+					if (use_cpu_bo_for_download(sna, priv)) {
+						DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
 						ok = sna->render.copy_boxes(sna, GXcopy,
 									    pixmap, priv->gpu_bo, 0, 0,
 									    pixmap, priv->cpu_bo, 0, 0,
 									    box, n, COPY_LAST);
+					}
 
 					if (!ok)
 						sna_read_boxes(sna,
@@ -1879,11 +1885,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 				DBG(("%s: region wholly inside damage\n",
 				     __FUNCTION__));
 
-				if (use_cpu_bo_for_write(sna, priv))
+				if (use_cpu_bo_for_download(sna, priv)) {
+					DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
 					ok = sna->render.copy_boxes(sna, GXcopy,
 								    pixmap, priv->gpu_bo, 0, 0,
 								    pixmap, priv->cpu_bo, 0, 0,
 								    box, n, COPY_LAST);
+				}
 				if (!ok)
 					sna_read_boxes(sna,
 						       priv->gpu_bo, 0, 0,
@@ -1904,11 +1912,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 					DBG(("%s: region intersects damage\n",
 					     __FUNCTION__));
 
-					if (use_cpu_bo_for_write(sna, priv))
+					if (use_cpu_bo_for_download(sna, priv)) {
+						DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
 						ok = sna->render.copy_boxes(sna, GXcopy,
 									    pixmap, priv->gpu_bo, 0, 0,
 									    pixmap, priv->cpu_bo, 0, 0,
 									    box, n, COPY_LAST);
+					}
 					if (!ok)
 						sna_read_boxes(sna,
 							       priv->gpu_bo, 0, 0,
@@ -2163,11 +2173,13 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 		if (n) {
 			bool ok = false;
 
-			if (use_cpu_bo_for_read(priv))
+			if (use_cpu_bo_for_upload(priv)) {
+				DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
 				ok = sna->render.copy_boxes(sna, GXcopy,
 							    pixmap, priv->cpu_bo, 0, 0,
 							    pixmap, priv->gpu_bo, 0, 0,
 							    box, n, 0);
+			}
 			if (!ok) {
 				if (pixmap->devPrivate.ptr == NULL) {
 					assert(priv->stride && priv->ptr);
@@ -2201,11 +2213,13 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 	} else if (DAMAGE_IS_ALL(priv->cpu_damage) ||
 		   sna_damage_contains_box__no_reduce(priv->cpu_damage, box)) {
 		bool ok = false;
-		if (use_cpu_bo_for_read(priv))
+		if (use_cpu_bo_for_upload(priv)) {
+			DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
 			ok = sna->render.copy_boxes(sna, GXcopy,
 						    pixmap, priv->cpu_bo, 0, 0,
 						    pixmap, priv->gpu_bo, 0, 0,
 						    box, 1, 0);
+		}
 		if (!ok) {
 			if (pixmap->devPrivate.ptr == NULL) {
 				assert(priv->stride && priv->ptr);
@@ -2230,11 +2244,13 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 
 		box = REGION_RECTS(&i);
 		ok = false;
-		if (use_cpu_bo_for_read(priv))
+		if (use_cpu_bo_for_upload(priv)) {
+			DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
 			ok = sna->render.copy_boxes(sna, GXcopy,
 						    pixmap, priv->cpu_bo, 0, 0,
 						    pixmap, priv->gpu_bo, 0, 0,
-						    box, n,0);
+						    box, n, 0);
+		}
 		if (!ok) {
 			if (pixmap->devPrivate.ptr == NULL) {
 				assert(priv->stride && priv->ptr);
@@ -2674,11 +2690,13 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		DBG(("%s: uploading %d damage boxes\n", __FUNCTION__, n));
 
 		ok = false;
-		if (use_cpu_bo_for_read(priv))
+		if (use_cpu_bo_for_upload(priv)) {
+			DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
 			ok = sna->render.copy_boxes(sna, GXcopy,
 						    pixmap, priv->cpu_bo, 0, 0,
 						    pixmap, priv->gpu_bo, 0, 0,
 						    box, n, 0);
+		}
 		if (!ok) {
 			if (pixmap->devPrivate.ptr == NULL) {
 				assert(priv->stride && priv->ptr);


More information about the xorg-commit mailing list