diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-24 00:15:33 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-24 01:09:56 +0000 |
commit | ef66c5b5ad221211948ec795ade031591c3f0ac7 (patch) | |
tree | f0d35f731672e7ce2166b871008d2b1852f09d74 | |
parent | 1cc07fa2d24b10ac95c7a84908290ec06539d447 (diff) |
sna: Search the inactive VMA cache first for a linear mapping
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index c733da53..b8c05faa 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1507,6 +1507,44 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags) bool use_active = (flags & CREATE_INACTIVE) == 0; struct list *cache; + if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { + int for_cpu = !!(flags & CREATE_CPU_MAP); + assert(use_active == false); + list_for_each_entry(bo, &kgem->vma_inactive, vma) { + if (IS_CPU_MAP(bo->map) != for_cpu) + continue; + + if (size > bo->size || 2*size < bo->size) + continue; + + if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { + kgem->need_purge |= bo->domain == DOMAIN_GPU; + kgem_bo_free(kgem, bo); + break; + } + + if (I915_TILING_NONE != bo->tiling && + gem_set_tiling(kgem->fd, bo->handle, + I915_TILING_NONE, 0) != I915_TILING_NONE) + continue; + + list_del(&bo->list); + if (bo->rq == &_kgem_static_request) + list_del(&bo->request); + list_move_tail(&bo->vma, &kgem->vma_cache); + + bo->tiling = I915_TILING_NONE; + bo->pitch = 0; + bo->delta = 0; + DBG((" %s: found handle=%d (size=%d) in linear vma cache\n", + __FUNCTION__, bo->handle, bo->size)); + assert(use_active || bo->domain != DOMAIN_GPU); + assert(!bo->needs_flush || use_active); + //assert(use_active || !kgem_busy(kgem, bo->handle)); + return bo; + } + } + cache = use_active ? active(kgem, size): inactive(kgem, size); list_for_each_entry_safe(bo, next, cache, list) { assert(bo->refcnt == 0); @@ -1529,19 +1567,25 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags) if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { int for_cpu = !!(flags & CREATE_CPU_MAP); if (IS_CPU_MAP(bo->map) != for_cpu) { - if (first == NULL) - first = bo; + if (first != NULL) + break; + + first = bo; continue; } } else { - if (first == NULL) - first = bo; + if (first != NULL) + break; + + first = bo; continue; } } else { if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { - if (first == NULL) - first = bo; + if (first != NULL) + break; + + first = bo; continue; } } |