diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-03 15:50:21 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-03 21:35:03 +0000 |
commit | b2dc17678fa3a548be61e1055d4d321dbd6494c3 (patch) | |
tree | aa1554193fce4c71e65924d1459b92870f4ac3ed | |
parent | caf41ae23d263c7baed6b23a80693690c4dfe563 (diff) |
sna: Always search for an exact active match first from the bo-cache
And accept second-best only if permitted by flags.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 8812d23e..1e4d08fc 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1895,20 +1895,20 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, struct kgem_bo *bo, *next; uint32_t pitch, untiled_pitch, tiled_height[3], size; uint32_t handle; - int exact = flags & CREATE_EXACT; int i; if (tiling < 0) - tiling = -tiling, exact = 1; + tiling = -tiling, flags |= CREATE_EXACT; DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d)\n", __FUNCTION__, width, height, bpp, tiling, - !!exact, !!(flags & CREATE_INACTIVE), + !!(flags & CREATE_EXACT), + !!(flags & CREATE_INACTIVE), !!(flags & CREATE_CPU_MAP), !!(flags & CREATE_GTT_MAP), !!(flags & CREATE_SCANOUT))); - assert(_kgem_can_create_2d(kgem, width, height, bpp, exact ? -tiling : tiling)); + assert(_kgem_can_create_2d(kgem, width, height, bpp, flags & CREATE_EXACT ? -tiling : tiling)); size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags & CREATE_SCANOUT, @@ -1972,18 +1972,12 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, for (i = 0; i <= I915_TILING_Y; i++) tiled_height[i] = kgem_aligned_height(kgem, height, i); + next = NULL; + cache = active(kgem, size); search_active: /* Best active match first */ - list_for_each_entry(bo, active(kgem, size), list) { + list_for_each_entry(bo, cache, list) { uint32_t s; - if (exact) { - if (bo->tiling != tiling) - continue; - } else { - if (bo->tiling > tiling) - continue; - } - if (bo->tiling) { if (bo->pitch < pitch) { DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n", @@ -1996,6 +1990,12 @@ search_active: /* Best active match first */ s = bo->pitch * tiled_height[bo->tiling]; if (s <= bo->size) { + if (bo->tiling != tiling) { + if (next == NULL && bo->tiling < tiling) + next = bo; + continue; + } + list_del(&bo->list); if (bo->rq == &_kgem_static_request) list_del(&bo->request); @@ -2009,7 +2009,7 @@ search_active: /* Best active match first */ bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; - DBG((" from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", + DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->refcnt == 0); assert(bo->reusable); @@ -2017,6 +2017,25 @@ search_active: /* Best active match first */ } } + if (next && (flags & CREATE_EXACT) == 0) { + list_del(&next->list); + if (next->rq == &_kgem_static_request) + list_del(&next->request); + + if (next->purged && !kgem_bo_clear_purgeable(kgem, next)) { + kgem->need_purge |= next->domain == DOMAIN_GPU; + kgem_bo_free(kgem, next); + } else { + next->unique_id = kgem_get_unique_id(kgem); + next->delta = 0; + DBG((" 2:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", + next->pitch, next->tiling, next->handle, next->unique_id)); + assert(next->refcnt == 0); + assert(next->reusable); + return kgem_bo_reference(next); + } + } + skip_active_search: /* Now just look for a close match and prefer any currently active */ cache = inactive(kgem, size); |