sna: Use an inplace exchange for large untiled BO
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 5 Nov 2013 08:49:28 +0000 (08:49 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 5 Nov 2013 09:06:19 +0000 (09:06 +0000)
On older architectures, large BO have to be untiled and so we can reuse
an existing CPU bo by adjusting its caching mode.

References: https://bugs.freedesktop.org/show_bug.cgi?id=70924
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/sna/kgem.c
src/sna/kgem.h
src/sna/sna_accel.c

index 00d0723..3a74616 100644 (file)
@@ -6541,3 +6541,13 @@ kgem_replace_bo(struct kgem *kgem,
 
        return dst;
 }
+
+bool kgem_bo_convert_to_gpu(struct kgem *kgem, struct kgem_bo *bo)
+{
+       assert(bo->tiling == I915_TILING_NONE);
+
+       if (kgem->has_llc)
+               return true;
+
+       return gem_set_caching(kgem->fd, bo->handle, UNCACHED);
+}
index f2abb04..6abab08 100644 (file)
@@ -299,6 +299,8 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
                                   int bpp,
                                   uint32_t flags);
 
+bool kgem_bo_convert_to_gpu(struct kgem *kgem, struct kgem_bo *bo);
+
 uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format);
 void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
 
index 28cdd74..2aae0e2 100644 (file)
@@ -3772,6 +3772,20 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
                        tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING;
                        tiling = sna_pixmap_choose_tiling(pixmap, tiling);
 
+                       if (tiling == I915_TILING_NONE &&
+                           priv->cpu_bo && !priv->shm &&
+                           kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo)) {
+                               assert(!priv->mapped);
+                               priv->gpu_bo = priv->cpu_bo;
+                               priv->cpu_bo = NULL;
+                               priv->ptr = NULL;
+                               sna_damage_all(&priv->gpu_damage,
+                                              pixmap->drawable.width,
+                                              pixmap->drawable.height);
+                               sna_damage_destroy(&priv->cpu_damage);
+                               goto done;
+                       }
+
                        create = 0;
                        if (flags & MOVE_INPLACE_HINT || (priv->cpu_damage && priv->cpu_bo == NULL))
                                create = CREATE_GTT_MAP | CREATE_INACTIVE;