sna: Reuse any partial write buffer for readback

Take advantage of any available temporary buffer that we reuse for
readback knowing that it is the last operation in the batch.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-10-19 21:09:01 +01:00
parent 972989276d
commit 50b980f12e
3 changed files with 21 additions and 17 deletions

View File

@ -1944,6 +1944,16 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
__FUNCTION__, size, flags, write, flags & KGEM_BUFFER_LAST));
list_for_each_entry(bo, &kgem->partial, base.list) {
if (flags == KGEM_BUFFER_LAST && bo->write) {
/* We can reuse any write buffer which we can fit */
if (size < bo->alloc) {
DBG(("%s: reusing write buffer for read of %d bytes? used=%d, total=%d\n",
__FUNCTION__, size, bo->used, bo->alloc));
offset = 0;
goto done;
}
}
if (bo->write != write) {
DBG(("%s: skip write %d buffer, need %d\n",
__FUNCTION__, bo->write, write));
@ -2133,31 +2143,25 @@ cleanup_bo:
return NULL;
}
void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *_bo)
void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
{
struct kgem_partial_bo *bo;
uint32_t offset = _bo->delta, length = _bo->size;
if (_bo->proxy)
_bo = _bo->proxy;
bo = (struct kgem_partial_bo *)_bo;
DBG(("%s(need_io=%s, sync=%d)\n", __FUNCTION__,
bo->need_io ? bo->write ? "write" : "read" : "none",
bo->base.sync));
DBG(("%s(offset=%d, length=%d, sync=%d)\n", __FUNCTION__,
offset, length, bo->base.sync));
if (bo->need_io) {
if (bo->write)
gem_write(kgem->fd, bo->base.handle,
0, bo->used, bo+1);
else
gem_read(kgem->fd, bo->base.handle, bo+1, bo->used);
if (!bo->base.sync) {
gem_read(kgem->fd, bo->base.handle,
(char *)(bo+1)+offset, length);
bo->base.needs_flush = false;
if (bo->base.gpu)
kgem_retire(kgem);
bo->need_io = 0;
}
if (bo->base.sync)
kgem_bo_sync(kgem, &bo->base, bo->write);
} else
kgem_bo_sync(kgem, &bo->base, false);
}

View File

@ -330,7 +330,7 @@ void kgem_bo_sync(struct kgem *kgem, struct kgem_bo *bo, bool for_write);
struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
uint32_t size, uint32_t flags,
void **ret);
void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *bo);
void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
void kgem_throttle(struct kgem *kgem);
bool kgem_expire_cache(struct kgem *kgem);

View File

@ -202,7 +202,7 @@ void sna_read_boxes(struct sna *sna,
} while (tmp_nbox);
assert(offset == dst_bo->size);
kgem_buffer_sync(kgem, dst_bo);
kgem_buffer_read_sync(kgem, dst_bo);
src = ptr;
do {