xf86-video-intel: 3 commits - configure.ac src/sna/sna_accel.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 12 23:58:18 PDT 2014


 configure.ac        |   83 ++++++----
 src/sna/sna_accel.c |  415 ++++++++++++++++++++++++++++++++--------------------
 2 files changed, 310 insertions(+), 188 deletions(-)

New commits:
commit 7bc669dd4b7e3e5978e95e4131d1f9215afbc041
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jun 13 07:48:15 2014 +0100

    configure: Allow manual disabling of each DRI level
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index b3b6e8e..21a0bf9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -296,6 +296,21 @@ AC_ARG_ENABLE(dri,
 			     [Disable DRI support [[default=auto]]]),
 	      [DRI=$enableval],
 	      [DRI=auto])
+AC_ARG_ENABLE(dri1,
+	      AS_HELP_STRING([--disable-dri1],
+			     [Disable DRI1 support [[default=yes]]]),
+	      [DRI1=$enableval],
+	      [DRI1=yes])
+AC_ARG_ENABLE(dri2,
+	      AS_HELP_STRING([--disable-dri2],
+			     [Disable DRI2 support [[default=yes]]]),
+	      [DRI2=$enableval],
+	      [DRI2=yes])
+AC_ARG_ENABLE(dri3,
+	      AS_HELP_STRING([--disable-dri3],
+			     [Disable DRI3 support [[default=yes]]]),
+	      [DRI3=$enableval],
+	      [DRI3=yes])
 
 AC_ARG_ENABLE(xvmc, AS_HELP_STRING([--disable-xvmc],
                                   [Disable XvMC support [[default=yes]]]),
@@ -461,15 +476,15 @@ if test "x$UMS" = "xyes"; then
 	AC_DEFINE(UMS,1,[Assume UMS support])
 fi
 
-DRI1=no
+have_dri1=no
 XORG_DRIVER_CHECK_EXT(XF86DRI, xf86driproto)
-if test "x$_EXT_CHECK" != "xno" -a "x$DRI" != "xno" -a "x$UMS" = "xyes"; then
-	PKG_CHECK_MODULES(DRI1, [xf86driproto], [DRI1=$DRI], [DRI1=no])
+if test "x$_EXT_CHECK" != "xno" -a "x$DRI" != "xno" -a "x$DRI1" != "xno" -a "x$UMS" = "xyes"; then
+	PKG_CHECK_MODULES(DRI1, [xf86driproto], [have_dri1=$DRI], [have_dri1=no])
         save_CFLAGS="$CFLAGS"
         save_CPPFLAGS="$CPPFLAGS"
         CFLAGS="$CFLAGS $XORG_CFLAGS $DRI1_CFLAGS $DRM_CFLAGS"
         CPPFLAGS="$CPPFLAGS $XORG_CFLAGS $DRI1_CFLAGS $DRM_CFLAGS"
-        AC_CHECK_HEADERS([dri.h sarea.h dristruct.h], [], [DRI1=no],
+        AC_CHECK_HEADERS([dri.h sarea.h dristruct.h], [], [have_dri1=no],
                 [/* for dri.h */
                  #include <xf86str.h>
                  /* for dristruct.h */
@@ -486,49 +501,55 @@ if test "x$_EXT_CHECK" != "xno" -a "x$DRI" != "xno" -a "x$UMS" = "xyes"; then
 fi
 
 AC_MSG_CHECKING([whether to include DRI1 support])
-AC_MSG_RESULT([$DRI1])
+AC_MSG_RESULT([$have_dri1])
 
-AM_CONDITIONAL(DRI1, test "x$DRI1" != "xno")
-if test "x$DRI1" != "xno"; then
+AM_CONDITIONAL(DRI1, test "x$have_dri1" != "xno")
+if test "x$have_dri1" != "xno"; then
         AC_DEFINE(HAVE_DRI1,1,[Enable DRI1 driver support])
 	dri_msg="$dri_msg DRI1"
 else
         DRI1_CFLAGS=""
         DRI1_LIBS=""
 
-        if test "x$DRI" = "xyes" -a "x$UMS" = "xyes"; then
+        if test "x$DRI" = "xyes" -a "x$UMS" = "xyes" -a "x$DRI1" != "xno"; then
                 AC_MSG_ERROR([DRI1 requested but prerequisites not found])
         fi
 fi
 
-DRI2=no
-DRI3=no
+have_dri2=no
+have_dri3=no
 if test "x$DRI" != "xno"; then
-	PKG_CHECK_MODULES(DRI2, [dri2proto >= 2.6], [DRI2=$DRI], [DRI2=no])
-	dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri`
-	if test "x$dridriverdir" = "x"; then
-		dridriverdir="$libdir/dri"
-	fi
-	AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI2 driver path])
 	if test "x$DRI2" != "xno"; then
+		PKG_CHECK_MODULES(have_dri2, [dri2proto >= 2.6], [have_dri2=$DRI], [have_dri2=no])
+	fi
+	if test "x$have_dri2" != "xno"; then
 		save_CFLAGS=$CFLAGS
 		CFLAGS="$XORG_CFLAGS $DRM_CFLAGS $DRI1_CFLAGS $DRI2_CFLAGS"
-		AC_CHECK_HEADERS([dri2.h], [], [DRI2=no], [
+		AC_CHECK_HEADERS([dri2.h], [], [have_dri2=no], [
 #include <dixstruct.h>
 #include <drm.h>
 ])
 		CFLAGS=$save_CFLAGS
 	fi
-
-	XORG_DRIVER_CHECK_EXT(DRI3, dri3proto)
-	if test "x$_EXT_CHECK" != "xno"; then
-		PKG_CHECK_MODULES(DRI3, [dri3proto], [DRI3=$DRI], [])
+	if test "x$have_dri2" != "xno"; then
+		dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri`
+		if test "x$dridriverdir" = "x"; then
+			dridriverdir="$libdir/dri"
+		fi
+		AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default have_dri2 driver path])
 	fi
+
 	if test "x$DRI3" != "xno"; then
+		XORG_DRIVER_CHECK_EXT(DRI3, dri3proto)
+		if test "x$_EXT_CHECK" != "xno"; then
+			PKG_CHECK_MODULES(DRI3, [dri3proto], [have_dri3=$DRI], [])
+		fi
+	fi
+	if test "x$have_dri3" != "xno"; then
 		save_CFLAGS=$CFLAGS
 		CFLAGS="$XORG_CFLAGS $DRI3_CFLAGS"
-		AC_CHECK_DECL(DRI3, [], [DRI3=no], [#include <xorg-server.h>])
-		AC_CHECK_HEADERS([misyncstr.h misyncshm.h], [], [DRI3=no], [
+		AC_CHECK_DECL(DRI3, [], [have_dri3=no], [#include <xorg-server.h>])
+		AC_CHECK_HEADERS([misyncstr.h misyncshm.h], [], [have_dri3=no], [
 #include <xorg-server.h>
 #include <xf86str.h>
 #include <misync.h>
@@ -538,13 +559,13 @@ if test "x$DRI" != "xno"; then
 fi
 
 AC_MSG_CHECKING([whether to include DRI2 support])
-AM_CONDITIONAL(DRI2, test "x$DRI2" != "xno")
-AC_MSG_RESULT([$DRI2])
-if test "x$DRI2" != "xno"; then
+AM_CONDITIONAL(DRI2, test "x$have_dri2" != "xno")
+AC_MSG_RESULT([$have_dri2])
+if test "x$have_dri2" != "xno"; then
         AC_DEFINE(HAVE_DRI2,1,[Enable DRI2 driver support])
 	dri_msg="$dri_msg DRI2"
 else
-	if test "x$DRI" = "xyes" -a "x$KMS" = "xyes"; then
+	if test "x$DRI" = "xyes" -a "x$DRI2" != "xno" -a "x$KMS" = "xyes"; then
 		AC_MSG_ERROR([DRI2 requested but prerequisites not found])
 	fi
 
@@ -553,13 +574,13 @@ else
 fi
 
 AC_MSG_CHECKING([whether to include DRI3 support])
-AM_CONDITIONAL(DRI3, test "x$DRI3" != "xno")
-AC_MSG_RESULT([$DRI3])
-if test "x$DRI3" != "xno"; then
+AM_CONDITIONAL(DRI3, test "x$have_dri3" != "xno")
+AC_MSG_RESULT([$have_dri3])
+if test "x$have_dri3" != "xno"; then
         AC_DEFINE(HAVE_DRI3,1,[Enable DRI3 driver support])
 	dri_msg="$dri_msg DRI3"
 else
-	if test "x$DRI" = "xyes" -a "x$KMS" = "xyes"; then
+	if test "x$DRI" = "xyes" -a "x$DRI3" != "xno" -a "x$KMS" = "xyes"; then
 		AC_MSG_ERROR([DRI3 requested but prerequisites not found])
 	fi
 fi
commit ffe067705b524930d243b18e97508219ed26390c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 12 09:52:50 2014 +0100

    sna: Try to use CPU uploads before BLT uploads
    
    As the BLT upload implies a sync (and a likely GPU boost), only do so if
    we cannot do an immediate upload with the CPU, either directly to
    backing memory or through the GTT.
    
    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 773af6f..23e27af 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -585,7 +585,7 @@ static bool sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv, bool a
 		return false;
 
 	if (priv->ptr == NULL)
-		return false;
+		return true;
 
 	__sna_pixmap_free_cpu(sna, priv);
 
@@ -3383,10 +3383,14 @@ done:
 			     __FUNCTION__));
 			assert(priv->gpu_bo);
 			assert(priv->gpu_bo->proxy == NULL);
-			sna_damage_all(&priv->gpu_damage, pixmap);
+			if (sna_pixmap_free_cpu(sna, priv, priv->cpu))
+				sna_damage_all(&priv->gpu_damage, pixmap);
 		}
-		if (DAMAGE_IS_ALL(priv->gpu_damage))
+		if (DAMAGE_IS_ALL(priv->gpu_damage)) {
 			sna_pixmap_free_cpu(sna, priv, priv->cpu);
+			sna_damage_destroy(&priv->cpu_damage);
+			list_del(&priv->flush_list);
+		}
 		priv->cpu = false;
 	}
 
@@ -4407,106 +4411,110 @@ create_upload_tiled_x(struct kgem *kgem,
 }
 
 static bool
-try_upload_blt(PixmapPtr pixmap, RegionRec *region,
-	       int x, int y, int w, int  h, char *bits, int stride)
+try_upload__tiled_x(PixmapPtr pixmap, RegionRec *region,
+		    int x, int y, int w, int  h, char *bits, int stride)
 {
 	struct sna *sna = to_sna_from_pixmap(pixmap);
-	struct sna_pixmap *priv;
-	struct kgem_bo *src_bo;
-	bool ok;
+	struct sna_pixmap *priv = sna_pixmap(pixmap);
+	BoxRec *box;
+	uint8_t *dst;
+	int n;
 
-	if (!sna->kgem.has_userptr || !USE_USERPTR_UPLOADS)
+	if (!kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)) {
+		DBG(("%s: no, cannot map through the CPU\n", __FUNCTION__));
 		return false;
+	}
 
-	priv = sna_pixmap(pixmap);
-	if (priv == NULL)
+	dst = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
+	if (dst == NULL)
 		return false;
 
-	if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL || priv->cpu) {
-		DBG(("%s: no, no gpu damage\n", __FUNCTION__));
-		return false;
-	}
+	kgem_bo_sync__cpu(&sna->kgem, priv->gpu_bo);
 
-	assert(priv->gpu_bo);
-	assert(priv->gpu_bo->proxy == NULL);
+	box = region_rects(region);
+	n = region_num_rects(region);
 
-	if ((priv->create & (KGEM_CAN_CREATE_GTT | KGEM_CAN_CREATE_LARGE)) == KGEM_CAN_CREATE_GTT &&
-	    kgem_bo_can_map(&sna->kgem, priv->gpu_bo) &&
-	    (priv->cow == NULL &&
-	     (priv->move_to_gpu == NULL || sna_pixmap_discard_shadow_damage(priv, region))  &&
-	     !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))) {
-		DBG(("%s: no, target is idle\n", __FUNCTION__));
-		return false;
-	}
+	DBG(("%s: upload(%d, %d, %d, %d) x %d\n", __FUNCTION__, x, y, w, h, n));
 
-	if (priv->cpu_damage &&
-	    sna_damage_contains_box__no_reduce(priv->cpu_damage,
-					       &region->extents) &&
-	    !box_inplace(pixmap, &region->extents)) {
-		DBG(("%s: no, damage on CPU and too small\n", __FUNCTION__));
+	if (sigtrap_get())
 		return false;
-	}
 
-	if (!sna_pixmap_move_area_to_gpu(pixmap, &region->extents, MOVE_WRITE | MOVE_ASYNC_HINT | (region->data ? MOVE_READ : 0)))
-		return false;
+	if (priv->gpu_bo->tiling) {
+		do {
+			DBG(("%s: copy tiled box (%d, %d)->(%d, %d)x(%d, %d)\n",
+			     __FUNCTION__,
+			     box->x1 - x, box->y1 - y,
+			     box->x1, box->y1,
+			     box->x2 - box->x1, box->y2 - box->y1));
 
-	src_bo = kgem_create_map(&sna->kgem, bits, stride * h, false);
-	if (src_bo == NULL)
-		return false;
+			assert(box->x2 > box->x1);
+			assert(box->y2 > box->y1);
 
-	src_bo->pitch = stride;
-	kgem_bo_mark_unreusable(src_bo);
+			assert(box->x1 >= 0);
+			assert(box->y1 >= 0);
+			assert(box->x2 <= pixmap->drawable.width);
+			assert(box->y2 <= pixmap->drawable.height);
 
-	DBG(("%s: upload(%d, %d, %d, %d) x %d through a temporary map\n",
-	     __FUNCTION__, x, y, w, h, region_num_rects(region)));
+			assert(box->x1 - x >= 0);
+			assert(box->y1 - y >= 0);
+			assert(box->x2 - x <= w);
+			assert(box->y2 - y <= h);
 
-	if (sigtrap_get() == 0) {
-		ok = sna->render.copy_boxes(sna, GXcopy,
-					    pixmap, src_bo, -x, -y,
-					    pixmap, priv->gpu_bo, 0, 0,
-					    region_rects(region),
-					    region_num_rects(region),
-					    COPY_LAST);
-		sigtrap_put();
-	} else
-		ok = false;
+			memcpy_to_tiled_x(&sna->kgem, bits, dst,
+					  pixmap->drawable.bitsPerPixel,
+					  stride, priv->gpu_bo->pitch,
+					  box->x1 - x, box->y1 - y,
+					  box->x1, box->y1,
+					  box->x2 - box->x1, box->y2 - box->y1);
+			box++;
+		} while (--n);
+	} else {
+		do {
+			DBG(("%s: copy lined box (%d, %d)->(%d, %d)x(%d, %d)\n",
+			     __FUNCTION__,
+			     box->x1 - x, box->y1 - y,
+			     box->x1, box->y1,
+			     box->x2 - box->x1, box->y2 - box->y1));
 
-	kgem_bo_sync__cpu(&sna->kgem, src_bo);
-	assert(src_bo->rq == NULL);
-	kgem_bo_destroy(&sna->kgem, src_bo);
+			assert(box->x2 > box->x1);
+			assert(box->y2 > box->y1);
 
-	if (!ok) {
-		DBG(("%s: copy failed!\n", __FUNCTION__));
-		return false;
-	}
+			assert(box->x1 >= 0);
+			assert(box->y1 >= 0);
+			assert(box->x2 <= pixmap->drawable.width);
+			assert(box->y2 <= pixmap->drawable.height);
 
-	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-		assert(!priv->clear);
-		if (region_subsumes_drawable(region, &pixmap->drawable)) {
-			sna_damage_all(&priv->gpu_damage, pixmap);
-		} else {
-			sna_damage_add(&priv->gpu_damage, region);
-			sna_damage_reduce_all(&priv->gpu_damage, pixmap);
-		}
-		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);
-			if (sna_pixmap_free_cpu(sna, priv, priv->cpu))
-				sna_damage_all(&priv->gpu_damage, pixmap);
+			assert(box->x1 - x >= 0);
+			assert(box->y1 - y >= 0);
+			assert(box->x2 - x <= w);
+			assert(box->y2 - y <= h);
+
+			memcpy_blt(bits, dst,
+				   pixmap->drawable.bitsPerPixel,
+				   stride, priv->gpu_bo->pitch,
+				   box->x1 - x, box->y1 - y,
+				   box->x1, box->y1,
+				   box->x2 - box->x1, box->y2 - box->y1);
+			box++;
+		} while (--n);
+
+		if (!priv->shm) {
+			assert(dst == MAP(priv->gpu_bo->map__cpu));
+			pixmap->devPrivate.ptr = dst;
+			pixmap->devKind = priv->gpu_bo->pitch;
+			priv->mapped = MAPPED_CPU;
+			assert_pixmap_map(pixmap, priv);
+			priv->cpu = true;
 		}
 	}
-	priv->cpu = false;
-	priv->clear = false;
 
+	sigtrap_put();
 	return true;
 }
 
 static bool
-try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
-		   int x, int y, int w, int  h, char *bits, int stride)
+try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
+		    int x, int y, int w, int  h, char *bits, int stride)
 {
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
@@ -4516,7 +4524,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 	uint8_t *dst;
 	int n;
 
-	if (wedged(sna))
+	if (!USE_INPLACE)
 		return false;
 
 	replaces = region_subsumes_pixmap(region, pixmap);
@@ -4574,35 +4582,44 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 		}
 	}
 
+	if (!sna_pixmap_move_area_to_gpu(pixmap, &region->extents,
+					 MOVE_WRITE | (region->data ? MOVE_READ : 0)))
+		return false;
+
 	if (priv->gpu_bo == NULL &&
 	    !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu))
 		return false;
 
+	if ((priv->create & KGEM_CAN_CREATE_LARGE) == 0 &&
+	    __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
+		return false;
+
 	DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling));
 	switch (priv->gpu_bo->tiling) {
 	case I915_TILING_Y:
-		return false;
+		break;
 	case I915_TILING_X:
 		if (!sna->kgem.memcpy_to_tiled_x)
-			return false;
+			break;
 	default:
+		if (try_upload__tiled_x(pixmap, region, x, y, w, h, bits, stride))
+			goto done;
 		break;
 	}
 
-	if (!kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)) {
+	if (!kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
 		DBG(("%s: no, cannot map through the CPU\n", __FUNCTION__));
 		return false;
 	}
 
-	if ((priv->create & KGEM_CAN_CREATE_LARGE) == 0 &&
-	    __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
-		return false;
-
-	dst = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
+	dst = kgem_bo_map(&sna->kgem, priv->gpu_bo);
 	if (dst == NULL)
 		return false;
 
-	kgem_bo_sync__cpu(&sna->kgem, priv->gpu_bo);
+	pixmap->devPrivate.ptr = dst;
+	pixmap->devKind = priv->gpu_bo->pitch;
+	priv->mapped = dst == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT;
+	assert(has_coherent_ptr(sna, priv, MOVE_WRITE));
 
 	box = region_rects(region);
 	n = region_num_rects(region);
@@ -4612,80 +4629,117 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 	if (sigtrap_get())
 		return false;
 
-	if (priv->gpu_bo->tiling) {
-		do {
-			DBG(("%s: copy tiled box (%d, %d)->(%d, %d)x(%d, %d)\n",
-			     __FUNCTION__,
-			     box->x1 - x, box->y1 - y,
-			     box->x1, box->y1,
-			     box->x2 - box->x1, box->y2 - box->y1));
+	do {
+		DBG(("%s: copy lined box (%d, %d)->(%d, %d)x(%d, %d)\n",
+		     __FUNCTION__,
+		     box->x1 - x, box->y1 - y,
+		     box->x1, box->y1,
+		     box->x2 - box->x1, box->y2 - box->y1));
 
-			assert(box->x2 > box->x1);
-			assert(box->y2 > box->y1);
+		assert(box->x2 > box->x1);
+		assert(box->y2 > box->y1);
 
-			assert(box->x1 >= 0);
-			assert(box->y1 >= 0);
-			assert(box->x2 <= pixmap->drawable.width);
-			assert(box->y2 <= pixmap->drawable.height);
+		assert(box->x1 >= 0);
+		assert(box->y1 >= 0);
+		assert(box->x2 <= pixmap->drawable.width);
+		assert(box->y2 <= pixmap->drawable.height);
 
-			assert(box->x1 - x >= 0);
-			assert(box->y1 - y >= 0);
-			assert(box->x2 - x <= w);
-			assert(box->y2 - y <= h);
+		assert(box->x1 - x >= 0);
+		assert(box->y1 - y >= 0);
+		assert(box->x2 - x <= w);
+		assert(box->y2 - y <= h);
 
-			memcpy_to_tiled_x(&sna->kgem, bits, dst,
-					  pixmap->drawable.bitsPerPixel,
-					  stride, priv->gpu_bo->pitch,
-					  box->x1 - x, box->y1 - y,
-					  box->x1, box->y1,
-					  box->x2 - box->x1, box->y2 - box->y1);
-			box++;
-		} while (--n);
-	} else {
-		do {
-			DBG(("%s: copy lined box (%d, %d)->(%d, %d)x(%d, %d)\n",
-			     __FUNCTION__,
-			     box->x1 - x, box->y1 - y,
-			     box->x1, box->y1,
-			     box->x2 - box->x1, box->y2 - box->y1));
+		memcpy_blt(bits, dst,
+			   pixmap->drawable.bitsPerPixel,
+			   stride, priv->gpu_bo->pitch,
+			   box->x1 - x, box->y1 - y,
+			   box->x1, box->y1,
+			   box->x2 - box->x1, box->y2 - box->y1);
+		box++;
+	} while (--n);
 
-			assert(box->x2 > box->x1);
-			assert(box->y2 > box->y1);
+	sigtrap_put();
 
-			assert(box->x1 >= 0);
-			assert(box->y1 >= 0);
-			assert(box->x2 <= pixmap->drawable.width);
-			assert(box->y2 <= pixmap->drawable.height);
+done:
+	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
+		if (replaces) {
+			sna_damage_all(&priv->gpu_damage, pixmap);
+		} else {
+			sna_damage_add(&priv->gpu_damage, region);
+			sna_damage_reduce_all(&priv->gpu_damage, pixmap);
+		}
+		if (DAMAGE_IS_ALL(priv->gpu_damage))
+			sna_damage_destroy(&priv->cpu_damage);
+		else
+			sna_damage_subtract(&priv->cpu_damage, region);
+	}
 
-			assert(box->x1 - x >= 0);
-			assert(box->y1 - y >= 0);
-			assert(box->x2 - x <= w);
-			assert(box->y2 - y <= h);
+	assert(!priv->clear);
+	return true;
+}
 
-			memcpy_blt(bits, dst,
-				   pixmap->drawable.bitsPerPixel,
-				   stride, priv->gpu_bo->pitch,
-				   box->x1 - x, box->y1 - y,
-				   box->x1, box->y1,
-				   box->x2 - box->x1, box->y2 - box->y1);
-			box++;
-		} while (--n);
+static bool
+try_upload__blt(PixmapPtr pixmap, RegionRec *region,
+		int x, int y, int w, int  h, char *bits, int stride)
+{
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	struct sna_pixmap *priv;
+	struct kgem_bo *src_bo;
+	bool ok;
 
-		if (!priv->shm) {
-			assert(dst == MAP(priv->gpu_bo->map__cpu));
-			pixmap->devPrivate.ptr = dst;
-			pixmap->devKind = priv->gpu_bo->pitch;
-			priv->mapped = MAPPED_CPU;
-			assert_pixmap_map(pixmap, priv);
-			priv->cpu = true;
-		}
+	if (!sna->kgem.has_userptr || !USE_USERPTR_UPLOADS)
+		return false;
+
+	priv = sna_pixmap(pixmap);
+	assert(priv);
+	assert(priv->gpu_bo);
+	assert(priv->gpu_bo->proxy == NULL);
+
+	if (priv->cpu_damage &&
+	    sna_damage_contains_box__no_reduce(priv->cpu_damage,
+					       &region->extents) &&
+	    !box_inplace(pixmap, &region->extents)) {
+		DBG(("%s: no, damage on CPU and too small\n", __FUNCTION__));
+		return false;
 	}
 
-	sigtrap_put();
+	if (!sna_pixmap_move_area_to_gpu(pixmap, &region->extents,
+					 MOVE_WRITE | MOVE_ASYNC_HINT | (region->data ? MOVE_READ : 0)))
+		return false;
+
+	src_bo = kgem_create_map(&sna->kgem, bits, stride * h, false);
+	if (src_bo == NULL)
+		return false;
+
+	src_bo->pitch = stride;
+	kgem_bo_mark_unreusable(src_bo);
+
+	DBG(("%s: upload(%d, %d, %d, %d) x %d through a temporary map\n",
+	     __FUNCTION__, x, y, w, h, region_num_rects(region)));
+
+	if (sigtrap_get() == 0) {
+		ok = sna->render.copy_boxes(sna, GXcopy,
+					    pixmap, src_bo, -x, -y,
+					    pixmap, priv->gpu_bo, 0, 0,
+					    region_rects(region),
+					    region_num_rects(region),
+					    COPY_LAST);
+		sigtrap_put();
+	} else
+		ok = false;
+
+	kgem_bo_sync__cpu(&sna->kgem, src_bo);
+	assert(src_bo->rq == NULL);
+	kgem_bo_destroy(&sna->kgem, src_bo);
+
+	if (!ok) {
+		DBG(("%s: copy failed!\n", __FUNCTION__));
+		return false;
+	}
 
 	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 		assert(!priv->clear);
-		if (replaces) {
+		if (region_subsumes_drawable(region, &pixmap->drawable)) {
 			sna_damage_all(&priv->gpu_damage, pixmap);
 		} else {
 			sna_damage_add(&priv->gpu_damage, region);
@@ -4699,14 +4753,63 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 			list_del(&priv->flush_list);
 			if (sna_pixmap_free_cpu(sna, priv, priv->cpu))
 				sna_damage_all(&priv->gpu_damage, pixmap);
-			priv->cpu = false;
 		}
 	}
-
+	priv->cpu = false;
 	priv->clear = false;
+
 	return true;
 }
 
+static bool ignore_cpu_damage(struct sna_pixmap *priv, const BoxRec *box)
+{
+	if (priv->cpu_damage == NULL)
+		return true;
+
+	if (!sna_damage_contains_box__no_reduce(priv->cpu_damage, box))
+		return true;
+
+	return box_inplace(priv->pixmap, box);
+}
+
+static bool
+try_upload__fast(PixmapPtr pixmap, RegionRec *region,
+		 int x, int y, int w, int  h, char *bits, int stride)
+{
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	struct sna_pixmap *priv;
+
+	if (wedged(sna))
+		return false;
+
+	priv = sna_pixmap(pixmap);
+	if (priv == NULL)
+		return false;
+
+	if (region_subsumes_pixmap(region, pixmap) ||
+	    (ignore_cpu_damage(priv, &region->extents) &&
+	     (priv->gpu_bo == NULL || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)))) {
+		if (try_upload__inplace(pixmap, region, x, y, w, h, bits, stride))
+			return true;
+	}
+
+	if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL || priv->cpu) {
+		DBG(("%s: no, no gpu damage\n", __FUNCTION__));
+		return false;
+	}
+
+	assert(priv->gpu_bo);
+	assert(priv->gpu_bo->proxy == NULL);
+
+	if (try_upload__blt(pixmap, region, x, y, w, h, bits, stride))
+		return true;
+
+	if (try_upload__inplace(pixmap, region, x, y, w, h, bits, stride))
+		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)
@@ -4729,10 +4832,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 	x += dx + drawable->x;
 	y += dy + drawable->y;
 
-	if (try_upload_blt(pixmap, region, x, y, w, h, bits, stride))
-		return true;
-
-	if (try_upload_tiled_x(pixmap, region, x, y, w, h, bits, stride))
+	if (try_upload__fast(pixmap, region, x, y, w, h, bits, stride))
 		return true;
 
 	hint = MOVE_WRITE;
commit 93444ea673be0ac11092a13ab3354f886f4aad63
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 12 09:26:14 2014 +0100

    sna: Refactor USE_INPLACE debug macro
    
    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 b3569bf..773af6f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2004,6 +2004,9 @@ sna_pixmap_make_cow(struct sna *sna,
 
 static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags)
 {
+	if (!USE_INPLACE)
+		return false;
+
 	if ((flags & MOVE_INPLACE_HINT) == 0) {
 		DBG(("%s: no, inplace operation not suitable\n", __FUNCTION__));
 		return false;
@@ -2166,8 +2169,7 @@ skip_inplace_map:
 
 	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 
-	if (USE_INPLACE &&
-	    operate_inplace(priv, flags) &&
+	if (operate_inplace(priv, flags) &&
 	    pixmap_inplace(sna, pixmap, priv, flags) &&
 	    sna_pixmap_create_mappable_gpu(pixmap, (flags & MOVE_READ) == 0)) {
 		void *ptr;
@@ -2623,8 +2625,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		RegionTranslate(region, dx, dy);
 	}
 
-	if (USE_INPLACE &&
-	    operate_inplace(priv, flags) &&
+	if (operate_inplace(priv, flags) &&
 	    region_inplace(sna, pixmap, region, priv, flags) &&
 	    sna_pixmap_create_mappable_gpu(pixmap, false)) {
 		void *ptr;


More information about the xorg-commit mailing list