sna: Check for a mappable GPU bo before migrating damage
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 28 Jun 2014 13:21:36 +0000 (14:21 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sun, 29 Jun 2014 05:57:05 +0000 (06:57 +0100)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/sna/sna_accel.c

index b7e3d90..2a4c567 100644 (file)
@@ -4520,6 +4520,14 @@ try_upload__tiled_x(PixmapPtr pixmap, RegionRec *region,
                return false;
        }
 
+       if (!sna_pixmap_move_area_to_gpu(pixmap, &region->extents,
+                                        MOVE_WRITE | (region->data ? MOVE_READ : 0)))
+               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);
        if (dst == NULL)
                return false;
@@ -4622,6 +4630,11 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
        if (!USE_INPLACE)
                return false;
 
+       assert(priv);
+
+       if (priv->shm && priv->gpu_damage == NULL)
+               return false;
+
        replaces = region_subsumes_pixmap(region, pixmap);
 
        DBG(("%s: bo? %d, can map? %d, replaces? %d\n", __FUNCTION__,
@@ -4678,18 +4691,10 @@ try_upload__inplace(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:
@@ -4708,6 +4713,14 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
                return false;
        }
 
+       if (!sna_pixmap_move_area_to_gpu(pixmap, &region->extents,
+                                        MOVE_WRITE | (region->data ? MOVE_READ : 0)))
+               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(&sna->kgem, priv->gpu_bo);
        if (dst == NULL)
                return false;
@@ -4768,6 +4781,14 @@ done:
                        sna_damage_destroy(&priv->cpu_damage);
                else
                        sna_damage_subtract(&priv->cpu_damage, region);
+
+               if (priv->cpu_damage == NULL) {
+                       list_del(&priv->flush_list);
+                       sna_damage_all(&priv->gpu_damage, pixmap);
+               }
+
+               if (priv->shm)
+                       sna_add_flush_pixmap(sna, priv, priv->cpu_bo);
        }
 
        assert(!priv->clear);
@@ -4895,6 +4916,7 @@ try_upload__fast(PixmapPtr pixmap, RegionRec *region,
                return false;
 
        if (ignore_cpu_damage(sna, priv, region)) {
+               DBG(("%s: ignore existing cpu damage (if any)\n", __FUNCTION__));
                if (try_upload__inplace(pixmap, region, x, y, w, h, bits, stride))
                        return true;
        }
@@ -6057,6 +6079,8 @@ upload_inplace:
        }
        dst_priv->clear = false;
 
+       assert(has_coherent_ptr(sna, src_priv, MOVE_READ));
+
        box = region_rects(region);
        n = region_num_rects(region);
        if (dst_priv->gpu_bo->tiling) {