diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-12 11:38:56 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-12 12:23:34 +0000 |
commit | 978e1aeceab3c1a524f7d7a070fe04f37530c8d9 (patch) | |
tree | 8cf4f6156e5d216c562deb1dd8513b52ae7ee885 | |
parent | d3169154d18600e0d41db5f833fad52970e17b55 (diff) |
sna: Only shrink a partial buffer if it is no longer used.
The condition on being able to shrink a buffer is more severe than just
whether we are reading from the buffer, but also we cannot swap the
handles if the existing handle remains exposed via a proxy.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index a9ccb41e..c7ce7779 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -112,7 +112,6 @@ struct kgem_partial_bo { uint32_t used; uint32_t need_io : 1; uint32_t write : 1; - uint32_t shrink : 1; uint32_t mmapped : 1; }; @@ -294,6 +293,8 @@ static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo) kgem_retire(kgem); if (bo->exec == NULL) { + DBG(("%s: retiring bo handle=%d (needed flush? %d)\n", + __FUNCTION__, bo->handle, bo->needs_flush)); bo->rq = NULL; list_del(&bo->request); bo->needs_flush = bo->flush; @@ -1079,8 +1080,9 @@ static void kgem_commit(struct kgem *kgem) struct kgem_bo *bo, *next; list_for_each_entry_safe(bo, next, &rq->buffers, request) { - DBG(("%s: release handle=%d (proxy? %d)\n", - __FUNCTION__, bo->handle, bo->proxy != NULL)); + DBG(("%s: release handle=%d (proxy? %d), dirty? %d flush? %d\n", + __FUNCTION__, bo->handle, bo->proxy != NULL, + bo->dirty, bo->needs_flush)); assert(!bo->purged); assert(bo->proxy || bo->rq == rq); @@ -1193,7 +1195,7 @@ static void kgem_finish_partials(struct kgem *kgem) } assert(bo->base.rq == kgem->next_request); - if (bo->shrink && bo->used < bo->base.size / 2) { + if (bo->base.refcnt == 1 && bo->used < bo->base.size / 2) { struct kgem_bo *shrink; shrink = search_linear_cache(kgem, @@ -1227,9 +1229,12 @@ static void kgem_finish_partials(struct kgem *kgem) list_replace(&bo->base.request, &shrink->request); list_init(&bo->base.request); + shrink->needs_flush = bo->base.dirty; bo->base.exec = NULL; bo->base.rq = NULL; + bo->base.dirty = false; + bo->base.needs_flush = false; bo->used = 0; bubble_sort_partial(kgem, bo); @@ -2497,8 +2502,11 @@ uint32_t kgem_add_reloc(struct kgem *kgem, kgem->reloc[index].target_handle = bo->handle; kgem->reloc[index].presumed_offset = bo->presumed_offset; - if (read_write_domain & 0x7fff) + if (read_write_domain & 0x7fff) { + DBG(("%s: marking handle=%d dirty\n", + __FUNCTION__, bo->handle)); bo->needs_flush = bo->dirty = true; + } delta += bo->presumed_offset; } else { @@ -2898,13 +2906,11 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem, DBG(("%s: reusing write buffer for read of %d bytes? used=%d, total=%d\n", __FUNCTION__, size, bo->used, bo->base.size)); offset = 0; - bo->shrink = 0; goto done; } else if (bo->used + size <= bo->base.size) { DBG(("%s: reusing unfinished write buffer for read of %d bytes? used=%d, total=%d\n", __FUNCTION__, size, bo->used, bo->base.size)); offset = bo->used; - bo->shrink = 0; goto done; } } @@ -3046,7 +3052,6 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem, bo->used = size; bo->write = write; - bo->shrink = bo->need_io; offset = 0; list_add(&bo->base.list, &kgem->partial); |