diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-03 09:47:27 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-03 13:48:58 +0100 |
commit | 8297c969ae749ef58d259b2ded2231b928efba43 (patch) | |
tree | 594167b892c45989bcc096c29d353abb94df3bf6 /src/sna | |
parent | 1c55d0447dba5bbde5be3903b273e04e3c9d084f (diff) |
sna: Replace the bo for tiled uploads if not suitable and being replaced
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/sna_accel.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 20f4583c..85c1c355 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4371,12 +4371,12 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r) } static bool -create_upload_tiled_x(struct kgem *kgem, - PixmapPtr pixmap, - struct sna_pixmap *priv, - bool replaces) +can_create_upload_tiled_x(struct kgem *kgem, + PixmapPtr pixmap, + struct sna_pixmap *priv, + bool replaces) { - unsigned create, tiling; + unsigned tiling; if (priv->shm || (priv->cpu && !replaces)) return false; @@ -4384,10 +4384,26 @@ create_upload_tiled_x(struct kgem *kgem, if ((priv->create & KGEM_CAN_CREATE_GPU) == 0) return false; + if (kgem->has_llc) + return true; + tiling = sna_pixmap_choose_tiling(pixmap, I915_TILING_X); assert(tiling != I915_TILING_Y && tiling != -I915_TILING_Y); + if (tiling != I915_TILING_NONE) + return false; - if (!kgem->has_llc && tiling != I915_TILING_NONE) + return true; +} + +static bool +create_upload_tiled_x(struct kgem *kgem, + PixmapPtr pixmap, + struct sna_pixmap *priv, + bool replaces) +{ + unsigned create; + + if (!can_create_upload_tiled_x(kgem, pixmap, priv, replaces)) return false; assert(priv->gpu_bo == NULL); @@ -4404,7 +4420,8 @@ create_upload_tiled_x(struct kgem *kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, - tiling, create); + sna_pixmap_choose_tiling(pixmap, I915_TILING_X), + create); return priv->gpu_bo != NULL; } @@ -4518,6 +4535,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); + bool ignore_cpu = false; bool replaces; BoxRec *box; uint8_t *dst; @@ -4540,11 +4558,15 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, if (priv->gpu_bo && replaces) { if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); - if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) { - DBG(("%s: discarding cached upload proxy\n", __FUNCTION__)); + if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, true) && + (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || + !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) { + DBG(("%s: discarding unusable target bo (busy? %d, mappable? %d)\n", __FUNCTION__, + kgem_bo_is_busy(priv->gpu_bo), + kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))); sna_pixmap_free_gpu(sna, priv); + ignore_cpu = true; } - replaces = true; /* Mark it all GPU damaged afterwards */ } assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); @@ -4557,15 +4579,19 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, if (priv->gpu_damage && region_subsumes_damage(region, priv->gpu_damage)) { if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo); - if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) { - DBG(("%s: discarding dirty pixmap\n", __FUNCTION__)); + if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, priv->cpu_damage == NULL) && + (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || + !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) { + DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__, + kgem_bo_is_busy(priv->gpu_bo), + kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))); sna_pixmap_free_gpu(sna, priv); + ignore_cpu = priv->cpu_damage == NULL; } - replaces = true; /* Mark it all GPU damaged afterwards */ } if (priv->gpu_bo == NULL && - !create_upload_tiled_x(&sna->kgem, pixmap, priv, replaces)) + !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu)) return false; DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling)); @@ -4692,6 +4718,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); sna_pixmap_free_cpu(sna, priv, priv->cpu); + priv->cpu = false; } } |