sna: Reuse the same upload buffer for the duration of the batch
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
8b9abe2be1
commit
2ea58256f5
|
|
@ -1381,7 +1381,9 @@ static void kgem_commit(struct kgem *kgem)
|
|||
{
|
||||
struct kgem_request *rq = kgem->next_request;
|
||||
struct kgem_bo *bo, *next;
|
||||
struct list release;
|
||||
|
||||
list_init(&release);
|
||||
list_for_each_entry_safe(bo, next, &rq->buffers, request) {
|
||||
assert(next->request.prev == &bo->request);
|
||||
|
||||
|
|
@ -1408,8 +1410,21 @@ static void kgem_commit(struct kgem *kgem)
|
|||
/* proxies are not used for domain tracking */
|
||||
list_del(&bo->request);
|
||||
bo->rq = NULL;
|
||||
bo->exec = &_kgem_dummy_exec;
|
||||
if (bo->map)
|
||||
list_add_tail(&bo->request, &release);
|
||||
}
|
||||
}
|
||||
while (!list_is_empty(&release)) {
|
||||
bo = list_first_entry(&release, struct kgem_bo, request);
|
||||
DBG(("%s: releasing upload cache, handle=%d\n",
|
||||
__FUNCTION__, bo->handle));
|
||||
list_del(&bo->request);
|
||||
assert(*(struct kgem_bo **)bo->map == bo);
|
||||
*(struct kgem_bo **)bo->map = NULL;
|
||||
bo->map = NULL;
|
||||
kgem_bo_destroy(kgem, bo);
|
||||
}
|
||||
|
||||
if (rq == &_kgem_static_request) {
|
||||
struct drm_i915_gem_set_domain set_domain;
|
||||
|
|
@ -2842,7 +2857,7 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo)
|
|||
DBG(("%s: size=%d, offset=%d, parent used=%d\n",
|
||||
__FUNCTION__, bo->size.bytes, bo->delta, io->used));
|
||||
|
||||
if (bo->delta + bo->size.bytes == io->used) {
|
||||
if (ALIGN(bo->delta + bo->size.bytes, 64) == io->used) {
|
||||
io->used = bo->delta;
|
||||
bubble_sort_partial(&kgem->active_partials, io);
|
||||
}
|
||||
|
|
@ -2850,9 +2865,11 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo)
|
|||
|
||||
void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
|
||||
{
|
||||
DBG(("%s: handle=%d, proxy? %d\n",
|
||||
__FUNCTION__, bo->handle, bo->proxy != NULL));
|
||||
|
||||
if (bo->proxy) {
|
||||
assert(bo->map == NULL);
|
||||
if (bo->io && bo->exec == NULL)
|
||||
if (bo->io && (bo->exec == NULL || bo->proxy->rq == NULL))
|
||||
_kgem_bo_delete_partial(kgem, bo);
|
||||
kgem_bo_unref(kgem, bo->proxy);
|
||||
kgem_bo_binding_free(kgem, bo);
|
||||
|
|
@ -3873,6 +3890,15 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
|
|||
return bo;
|
||||
}
|
||||
|
||||
void kgem_proxy_bo_attach(struct kgem_bo *bo,
|
||||
struct kgem_bo **ptr)
|
||||
{
|
||||
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
|
||||
assert(bo->map == NULL);
|
||||
bo->map = ptr;
|
||||
*ptr = kgem_bo_reference(bo);
|
||||
}
|
||||
|
||||
void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
|
||||
{
|
||||
struct kgem_partial_bo *bo;
|
||||
|
|
@ -3880,7 +3906,8 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
|
|||
int domain;
|
||||
|
||||
assert(_bo->io);
|
||||
assert(_bo->exec == NULL);
|
||||
assert(_bo->exec == &_kgem_dummy_exec);
|
||||
assert(_bo->rq == NULL);
|
||||
if (_bo->proxy)
|
||||
_bo = _bo->proxy;
|
||||
assert(_bo->exec == NULL);
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
|
|||
const void *data,
|
||||
BoxPtr box,
|
||||
int stride, int bpp);
|
||||
void kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr);
|
||||
|
||||
int kgem_choose_tiling(struct kgem *kgem,
|
||||
int tiling, int width, int height, int bpp);
|
||||
|
|
|
|||
|
|
@ -1064,8 +1064,10 @@ skip_inplace_map:
|
|||
}
|
||||
|
||||
done:
|
||||
if (flags & MOVE_WRITE)
|
||||
if (flags & MOVE_WRITE) {
|
||||
priv->source_count = SOURCE_BIAS;
|
||||
assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
|
||||
}
|
||||
|
||||
if ((flags & MOVE_ASYNC_HINT) == 0 && priv->cpu_bo) {
|
||||
DBG(("%s: syncing CPU bo\n", __FUNCTION__));
|
||||
|
|
@ -1260,6 +1262,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
|
|||
|
||||
if (priv->stride && priv->gpu_bo &&
|
||||
region_inplace(sna, pixmap, region, priv)) {
|
||||
assert(priv->gpu_bo->proxy == NULL);
|
||||
if (sync_will_stall(priv->gpu_bo) &&
|
||||
priv->gpu_bo->exec == NULL)
|
||||
kgem_retire(&sna->kgem);
|
||||
|
|
@ -1371,6 +1374,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
|
|||
if (priv->gpu_bo == NULL)
|
||||
goto done;
|
||||
|
||||
assert(priv->gpu_bo->proxy == NULL);
|
||||
if (priv->clear) {
|
||||
int n = REGION_NUM_RECTS(region);
|
||||
BoxPtr box = REGION_RECTS(region);
|
||||
|
|
@ -1581,8 +1585,10 @@ done:
|
|||
RegionTranslate(region, -dx, -dy);
|
||||
|
||||
out:
|
||||
if (flags & MOVE_WRITE)
|
||||
if (flags & MOVE_WRITE) {
|
||||
priv->source_count = SOURCE_BIAS;
|
||||
assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
|
||||
}
|
||||
if (priv->cpu_bo) {
|
||||
DBG(("%s: syncing cpu bo\n", __FUNCTION__));
|
||||
kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
|
||||
|
|
@ -1942,6 +1948,7 @@ done:
|
|||
|
||||
DBG(("%s: using GPU bo with damage? %d\n",
|
||||
__FUNCTION__, *damage != NULL));
|
||||
assert(priv->gpu_bo->proxy == NULL);
|
||||
return priv->gpu_bo;
|
||||
|
||||
use_gpu_bo:
|
||||
|
|
@ -1951,6 +1958,7 @@ use_gpu_bo:
|
|||
&to_sna_from_pixmap(pixmap)->active_pixmaps);
|
||||
*damage = NULL;
|
||||
DBG(("%s: using whole GPU bo\n", __FUNCTION__));
|
||||
assert(priv->gpu_bo->proxy == NULL);
|
||||
return priv->gpu_bo;
|
||||
|
||||
use_cpu_bo:
|
||||
|
|
@ -2083,6 +2091,7 @@ sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags)
|
|||
|
||||
if (DAMAGE_IS_ALL(priv->gpu_damage)) {
|
||||
DBG(("%s: GPU all-damaged\n", __FUNCTION__));
|
||||
assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0);
|
||||
return sna_pixmap_mark_active(to_sna_from_pixmap(pixmap), priv);
|
||||
}
|
||||
|
||||
|
|
@ -2285,6 +2294,7 @@ done:
|
|||
}
|
||||
}
|
||||
active:
|
||||
assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0);
|
||||
return sna_pixmap_mark_active(sna, priv);
|
||||
}
|
||||
|
||||
|
|
@ -2532,6 +2542,8 @@ static bool upload_inplace(struct sna *sna,
|
|||
return false;
|
||||
|
||||
if (priv->gpu_bo) {
|
||||
assert(priv->gpu_bo->proxy == NULL);
|
||||
|
||||
if (!kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo))
|
||||
return true;
|
||||
|
||||
|
|
@ -3389,6 +3401,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
|||
dst_priv->clear = false;
|
||||
}
|
||||
|
||||
assert(dst_priv->gpu_bo == NULL || dst_priv->gpu_bo->proxy == NULL);
|
||||
|
||||
/* Try to maintain the data on the GPU */
|
||||
if (dst_priv->gpu_bo == NULL &&
|
||||
((dst_priv->cpu_damage == NULL && copy_use_gpu_bo(sna, dst_priv, ®ion)) ||
|
||||
|
|
|
|||
|
|
@ -496,6 +496,14 @@ static struct kgem_bo *upload(struct sna *sna,
|
|||
channel->offset[1] -= box->y1;
|
||||
channel->scale[0] = 1.f/channel->width;
|
||||
channel->scale[1] = 1.f/channel->height;
|
||||
|
||||
if (pixmap->usage_hint == 0 &&
|
||||
channel->width == pixmap->drawable.width &&
|
||||
channel->height == pixmap->drawable.height) {
|
||||
struct sna_pixmap *priv = sna_pixmap(pixmap);
|
||||
if (priv)
|
||||
kgem_proxy_bo_attach(bo, &priv->gpu_bo);
|
||||
}
|
||||
}
|
||||
|
||||
return bo;
|
||||
|
|
@ -526,7 +534,8 @@ sna_render_pixmap_bo(struct sna *sna,
|
|||
priv = sna_pixmap(pixmap);
|
||||
if (priv) {
|
||||
if (priv->gpu_bo &&
|
||||
(DAMAGE_IS_ALL(priv->gpu_damage) || !priv->cpu_damage)) {
|
||||
(DAMAGE_IS_ALL(priv->gpu_damage) || !priv->cpu_damage ||
|
||||
priv->gpu_bo->proxy)) {
|
||||
channel->bo = kgem_bo_reference(priv->gpu_bo);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1148,12 +1157,20 @@ sna_render_picture_extract(struct sna *sna,
|
|||
upload = false;
|
||||
}
|
||||
}
|
||||
if (upload)
|
||||
if (upload) {
|
||||
bo = kgem_upload_source_image(&sna->kgem,
|
||||
pixmap->devPrivate.ptr,
|
||||
&box,
|
||||
pixmap->devKind,
|
||||
pixmap->drawable.bitsPerPixel);
|
||||
if (pixmap->usage_hint == 0 &&
|
||||
box.x2 - box.x1 == pixmap->drawable.width &&
|
||||
box.y2 - box.y1 == pixmap->drawable.height) {
|
||||
struct sna_pixmap *priv = sna_pixmap(pixmap);
|
||||
if (priv)
|
||||
kgem_proxy_bo_attach(bo, &priv->gpu_bo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (src_bo) {
|
||||
bo = kgem_create_2d(&sna->kgem, w, h,
|
||||
|
|
|
|||
Loading…
Reference in New Issue