diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-19 21:09:01 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-19 21:09:01 +0100 |
commit | 50b980f12e02401cdd4bc21b970d92e7bd1e6459 (patch) | |
tree | 80396ea7fb659b770bf33c9c1a157ae3c1dbe9f1 | |
parent | 972989276dd3f84c1cedca0494d04f907875f8f3 (diff) |
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>
-rw-r--r-- | src/sna/kgem.c | 34 | ||||
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna_io.c | 2 |
3 files changed, 21 insertions, 17 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 073fed7e..ed0e12ff 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -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); } diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 60a23def..eb89c633 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -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); diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index 321247a2..5a6fdd9b 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -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 { |