diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-02-20 16:30:53 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-02-20 16:30:53 +0000 |
commit | dbe0580e207ad85cb6a659f86c5746a7ecbcd036 (patch) | |
tree | 8ed04f4a98b99ae066f93d886e6a689841e4f9ed | |
parent | b68b76cf54a322e80685f1ec93538cd6c5813ea4 (diff) |
sna: gen4+ suffer no penalty for changing tiling
On gen4, the tiling/fence constraints are fairly lax, only requiring
page alignment of the object and its size, and so we can switch
tiling modes without incurring a GPU stall on active bo.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index f107f145..e7c49874 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -2403,15 +2403,28 @@ search_again: assert(bo->reusable); assert(bo->tiling == tiling); - if (bo->pitch < pitch) { - DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n", - bo->tiling, tiling, - bo->pitch, pitch)); - continue; - } + if (kgem->gen < 40) { + if (bo->pitch < pitch) { + DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n", + bo->tiling, tiling, + bo->pitch, pitch)); + continue; + } - if (bo->pitch * tiled_height > bytes(bo)) - continue; + if (bo->pitch * tiled_height > bytes(bo)) + continue; + } else { + if (num_pages(bo) < size) + continue; + + if (bo->pitch != pitch) { + gem_set_tiling(kgem->fd, + bo->handle, + tiling, pitch); + + bo->pitch = pitch; + } + } kgem_bo_remove_from_active(kgem, bo); @@ -2444,6 +2457,38 @@ search_again: } if (--retry && flags & CREATE_EXACT) { + if (kgem->gen >= 40) { + for (i = I915_TILING_NONE; i <= I915_TILING_Y; i++) { + if (i == tiling) + continue; + + cache = &kgem->active[bucket][i]; + list_for_each_entry(bo, cache, list) { + assert(!bo->purged); + assert(bo->refcnt == 0); + assert(bo->reusable); + + if (num_pages(bo) < size) + continue; + + if (tiling != gem_set_tiling(kgem->fd, + bo->handle, + tiling, pitch)) + continue; + + kgem_bo_remove_from_active(kgem, bo); + + bo->unique_id = kgem_get_unique_id(kgem); + bo->pitch = pitch; + bo->tiling = tiling; + bo->delta = 0; + DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", + bo->pitch, bo->tiling, bo->handle, bo->unique_id)); + return kgem_bo_reference(bo); + } + } + } + bucket++; goto search_again; } |