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>
This commit is contained in:
Chris Wilson 2012-01-03 15:50:21 +00:00
parent caf41ae23d
commit b2dc17678f
1 changed files with 33 additions and 14 deletions

View File

@ -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);