summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sna/kgem.c10
-rw-r--r--src/sna/kgem.h2
-rw-r--r--src/sna/sna_accel.c14
3 files changed, 26 insertions, 0 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 00d0723b..3a746167 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -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);
+}
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index f2abb047..6abab08e 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -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);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 28cdd740..2aae0e2f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -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;