summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-11-05 08:49:28 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-11-05 09:06:19 +0000
commitdc61705a6e425952de4c81c2320382af07cf948a (patch)
tree438f68920eedf661bb9f3fba5a675632ac4e6a77 /src
parentf3225fcb38686f3b9701725bf3a11ecf1c100c3f (diff)
sna: Use an inplace exchange for large untiled BO
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>
Diffstat (limited to 'src')
-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;