diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-29 12:09:04 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-29 12:23:17 +0000 |
commit | ccd895c61d9f409a36c70eaf02d7ab43cc6c03c2 (patch) | |
tree | f99e080e3a8f417e70ef4c1e978245d1d0618f06 | |
parent | f85a853455249fd782e907ce1d78d11f75362def (diff) |
sna: Allow uploading inplace to a freshly created GPU bo
If the operation is favoured to be performed using a WC upload, presume
that we will use the uploaded pixmap on the GPU and so prefer to create
a GPU buffer to hold the fresh data.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 04382e44..feb171f9 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -802,6 +802,23 @@ region_subsumes_drawable(RegionPtr region, DrawablePtr drawable) extents->y2 >= drawable->height; } +static bool +region_subsumes_gpu_damage(const RegionRec *region, struct sna_pixmap *priv) +{ + if (region->data) + return false; + + if (priv->gpu_damage) { + const BoxRec *extents = ®ion->extents; + const BoxRec *damage = &priv->gpu_damage->extents; + if (extents->x2 < damage->x2 || extents->x1 > damage->x1 || + extents->y2 < damage->y2 || extents->y1 > damage->y1) + return false; + } + + return true; +} + static bool sync_will_stall(struct kgem_bo *bo) { return kgem_bo_is_busy(bo); @@ -1715,6 +1732,10 @@ sna_put_image_upload_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, __FUNCTION__, nbox, box->x1, box->y1, box->x2, box->y2)); + if (priv->gpu_bo == NULL && + !sna_pixmap_create_mappable_gpu(pixmap)) + return FALSE; + assert(priv->gpu_bo); if (gc->alu == GXcopy && @@ -1780,15 +1801,21 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, goto blt; } + if (!priv->pinned && priv->gpu_bo && + region_subsumes_gpu_damage(region, priv) && + kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo)) { + sna_damage_destroy(&priv->gpu_damage); + sna_pixmap_destroy_gpu_bo(sna, priv); + } + /* XXX performing the upload inplace is currently about 20x slower * for putimage10 on gen6 -- mostly due to slow page faulting in kernel. * So we try again with vma caching and only for pixmaps who will be * immediately flushed... */ if ((priv->flush || - (priv->gpu_bo && - region_inplace(sna, pixmap, region, priv) && - !kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo))) && + (region_inplace(sna, pixmap, region, priv) && + (priv->gpu_bo == NULL || !kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo)))) && sna_put_image_upload_blt(drawable, gc, region, x, y, w, h, bits, stride)) { if (region_subsumes_drawable(region, &pixmap->drawable)) { |