diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-06-01 08:25:12 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-06-01 08:25:12 +0100 |
commit | 14b5ab3fef80afdb204fe399e0340f028ab7839c (patch) | |
tree | 912fa64b5e0b0de9a8227c3e7c641db27d68aacf | |
parent | 834bdb0344f1e71c3c0e8c31e47bd44cec28e584 (diff) |
sna: Enable use of GPU tiling even when SET_TILING fails
On gen4+, we no longer need to setup a fence for tiled operations and so
can program the GPU irrespective of the kernel tiled settings. However,
this means that we then cannot access the object through a GTT mmapping
(as we have no fence to do detiling) and nor can we use a WC mmap as the
swizzle is unknown.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 76 | ||||
-rw-r--r-- | src/sna/kgem.h | 1 |
2 files changed, 59 insertions, 18 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 59352634..e4960eac 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -562,6 +562,9 @@ static void *__kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo) DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__, bo->handle, bytes(bo))); + if (!kgem->can_fence) + return NULL; + VG_CLEAR(gtt); retry_gtt: gtt.handle = bo->handle; @@ -1599,6 +1602,8 @@ static void kgem_init_swizzling(struct kgem *kgem) if (!DBG_NO_DETILING) choose_memcpy_tiled_x(kgem, tiling.swizzle_mode); + + kgem->can_fence = tiling.swizzle_mode != I915_BIT_6_SWIZZLE_UNKNOWN; out: gem_close(kgem->fd, tiling.handle); } @@ -5273,8 +5278,11 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, if (num_pages(bo) < size) continue; - if (!kgem_set_tiling(kgem, bo, tiling, pitch)) - continue; + if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; + } } kgem_bo_remove_from_active(kgem, bo); @@ -5300,8 +5308,14 @@ large_inactive: if (size > num_pages(bo)) continue; - if (!kgem_set_tiling(kgem, bo, tiling, pitch)) - continue; + if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { + if (kgem->gen >= 040) { + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; + } else + continue; + } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { kgem_bo_free(kgem, bo); @@ -5364,7 +5378,8 @@ large_inactive: tiling, pitch)) { DBG(("inactive GTT vma with wrong tiling: %d < %d\n", bo->tiling, tiling)); - continue; + kgem_bo_free(kgem, bo); + break; } } @@ -5444,8 +5459,9 @@ search_active: continue; if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { - kgem_bo_free(kgem, bo); - break; + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; } } assert(bo->tiling == tiling); @@ -5505,8 +5521,14 @@ search_active: continue; if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { - kgem_bo_free(kgem, bo); - break; + if (kgem->gen >= 040) { + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; + } else { + kgem_bo_free(kgem, bo); + break; + } } assert(bo->tiling == tiling); assert(bo->pitch >= pitch); @@ -5592,8 +5614,14 @@ search_inactive: } if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { - kgem_bo_free(kgem, bo); - break; + if (kgem->gen >= 040) { + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; + } else { + kgem_bo_free(kgem, bo); + break; + } } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { @@ -5654,8 +5682,14 @@ search_inactive: __kgem_bo_clear_busy(bo); if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { - kgem_bo_free(kgem, bo); - goto no_retire; + if (kgem->gen >= 040) { + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; + } else { + kgem_bo_free(kgem, bo); + goto no_retire; + } } assert(bo->tiling == tiling); assert(bo->pitch >= pitch); @@ -5708,11 +5742,17 @@ create: if (flags & CREATE_SCANOUT) __kgem_bo_make_scanout(kgem, bo, width, height); } else { - if (flags & CREATE_EXACT) { - DBG(("%s: failed to set exact tiling (gem_set_tiling)\n", __FUNCTION__)); - gem_close(kgem->fd, handle); - free(bo); - return NULL; + if (kgem->gen >= 040) { + assert(!kgem->can_fence); + bo->tiling = tiling; + bo->pitch = pitch; + } else { + if (flags & CREATE_EXACT) { + DBG(("%s: failed to set exact tiling (gem_set_tiling)\n", __FUNCTION__)); + gem_close(kgem->fd, handle); + free(bo); + return NULL; + } } } diff --git a/src/sna/kgem.h b/src/sna/kgem.h index bdcb9f14..9e6db0f2 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -190,6 +190,7 @@ struct kgem { uint32_t has_handle_lut :1; uint32_t has_wc_mmap :1; + uint32_t can_fence :1; uint32_t can_blt_cpu :1; uint32_t can_blt_y :1; uint32_t can_render_y :1; |