summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-23 15:59:00 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-23 17:47:20 +0100
commit82e91327d57e03d2117638165f298a50b946fcaa (patch)
tree851593ddc2d767301560577621462b1956e3a798
parentb286ffa6beccb8fe341c464a4fb9f2af98541263 (diff)
sna: Use a temporary userptr mapping for a large upload into a busy target
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 0499a1dd..2a976cf6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4333,6 +4333,41 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
return;
}
+ if (src_priv == NULL &&
+ sna->kgem.has_userptr &&
+ __kgem_bo_is_busy(&sna->kgem, bo) &&
+ box_inplace(src_pixmap, &region->extents)) {
+ struct kgem_bo *src_bo;
+ bool ok = false;
+
+ DBG(("%s: upload through a temporary map\n",
+ __FUNCTION__));
+
+ src_bo = kgem_create_map(&sna->kgem,
+ src_pixmap->devPrivate.ptr,
+ src_pixmap->devKind * src_pixmap->drawable.height,
+ true);
+ if (src_bo) {
+ src_bo->flush = true;
+ src_bo->pitch = src_pixmap->devKind;
+ src_bo->reusable = false;
+
+ ok = sna->render.copy_boxes(sna, alu,
+ src_pixmap, src_bo, src_dx, src_dy,
+ dst_pixmap, bo, 0, 0,
+ box, n, COPY_LAST);
+
+ kgem_bo_sync__cpu(&sna->kgem, src_bo);
+ kgem_bo_destroy(&sna->kgem, src_bo);
+ }
+
+ if (ok) {
+ if (damage)
+ sna_damage_add(damage, region);
+ return;
+ }
+ }
+
if (alu != GXcopy) {
PixmapPtr tmp;
int i;