diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-04 11:02:39 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-04 11:25:28 +0100 |
commit | 64bcb91f58fba3956f2c66fa37707b9e496da936 (patch) | |
tree | 14574fbf608ce24de0973a8a77abdd69d8212555 | |
parent | 821ef20b27f84cc26aec266b0f616a7f39ba9e3d (diff) |
sna: Utilise existing cached upload for promoting to GPU bo
If we already have a buffer that represents the data on the GPU, we can
simply use that when we need to promote the pixmap onto the GPU.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 55 | ||||
-rw-r--r-- | src/sna/sna_damage.h | 1 |
2 files changed, 35 insertions, 21 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 9191fe2f..0b16bd00 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4091,24 +4091,19 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) goto active; } - if (kgem_bo_discard_cache(priv->gpu_bo, flags & (MOVE_WRITE | __MOVE_FORCE))) { - DBG(("%s: discarding cached upload buffer\n", __FUNCTION__)); - assert(DAMAGE_IS_ALL(priv->cpu_damage)); - assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage)); /* magical upload buffer */ - assert(!priv->pinned); - assert(!priv->mapped); - sna_damage_destroy(&priv->gpu_damage); - kgem_bo_destroy(&sna->kgem, priv->gpu_bo); - priv->gpu_bo = NULL; - } - if ((flags & MOVE_READ) == 0) sna_damage_destroy(&priv->cpu_damage); sna_damage_reduce(&priv->cpu_damage); assert_pixmap_damage(pixmap); DBG(("%s: CPU damage? %d\n", __FUNCTION__, priv->cpu_damage != NULL)); - if (priv->gpu_bo == NULL) { + if (priv->gpu_bo == NULL || + kgem_bo_discard_cache(priv->gpu_bo, flags & (MOVE_WRITE | __MOVE_FORCE))) { + struct kgem_bo *proxy; + + proxy = priv->gpu_bo; + priv->gpu_bo = NULL; + DBG(("%s: creating GPU bo (%dx%d@%d), create=%x\n", __FUNCTION__, pixmap->drawable.width, @@ -4116,9 +4111,9 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) pixmap->drawable.bitsPerPixel, priv->create)); assert(!priv->mapped); - if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) { - unsigned create; + assert(list_is_empty(&priv->flush_list)); + if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) { assert(pixmap->drawable.width > 0); assert(pixmap->drawable.height > 0); assert(pixmap->drawable.bitsPerPixel >= 8); @@ -4138,21 +4133,39 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) pixmap->devPrivate.ptr = NULL; sna_damage_all(&priv->gpu_damage, pixmap); 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; + } else { + unsigned create = 0; + if (flags & MOVE_INPLACE_HINT || (priv->cpu_damage && priv->cpu_bo == NULL)) + create = CREATE_GTT_MAP | CREATE_INACTIVE; - sna_pixmap_alloc_gpu(sna, pixmap, priv, create); + sna_pixmap_alloc_gpu(sna, pixmap, priv, create); + } } + if (priv->gpu_bo == NULL) { DBG(("%s: not creating GPU bo\n", __FUNCTION__)); assert(priv->gpu_damage == NULL); + priv->gpu_bo = proxy; + if (proxy) + sna_damage_all(&priv->cpu_damage, pixmap); return NULL; } + if (proxy) { + DBG(("%s: promoting upload proxy handle=%d to GPU\n", __FUNCTION__, proxy->handle)); + + if (priv->cpu_damage && + sna->render.copy_boxes(sna, GXcopy, + &pixmap->drawable, proxy, 0, 0, + &pixmap->drawable, priv->gpu_bo, 0, 0, + region_rects(DAMAGE_REGION(priv->cpu_damage)), + region_num_rects(DAMAGE_REGION(priv->cpu_damage)), + 0)) + sna_damage_destroy(&priv->cpu_damage); + + kgem_bo_destroy(&sna->kgem, proxy); + } + if (flags & MOVE_WRITE && priv->cpu_damage == NULL) { /* Presume that we will only ever write to the GPU * bo. Readbacks are expensive but fairly constant diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h index 28f7ee60..a55f8598 100644 --- a/src/sna/sna_damage.h +++ b/src/sna/sna_damage.h @@ -25,6 +25,7 @@ struct sna_damage { #define DAMAGE_IS_ALL(ptr) (((uintptr_t)(ptr))&1) #define DAMAGE_MARK_ALL(ptr) ((struct sna_damage *)(((uintptr_t)(ptr))|1)) #define DAMAGE_PTR(ptr) ((struct sna_damage *)(((uintptr_t)(ptr))&~1)) +#define DAMAGE_REGION(ptr) (&DAMAGE_PTR(ptr)->region) struct sna_damage *sna_damage_create(void); |