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,
- ®ion->extents) &&
- !box_inplace(pixmap, ®ion->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, ®ion->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, ®ion->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,
+ ®ion->extents) &&
+ !box_inplace(pixmap, ®ion->extents)) {
+ DBG(("%s: no, damage on CPU and too small\n", __FUNCTION__));
+ return false;
}
- sigtrap_put();
+ if (!sna_pixmap_move_area_to_gpu(pixmap, ®ion->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, ®ion->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