diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-03-16 11:12:01 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-03-16 11:12:01 +0000 |
commit | b306dc20e3e92a62f60c4155e18cdcba650b1a62 (patch) | |
tree | 4b0baf7e8d58ab3e7be44120dc6214c181fe9325 | |
parent | e042b5d82558293ef06847f4833efc91a95b5d40 (diff) |
sna: Relax tiling requirements to cope with kernel errors
If the kernel can't accept our tiling requirements, don't fret until we
actually need that fence! If we do, then we either stop tiling with the
buffer or we use another.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 20 | ||||
-rw-r--r-- | src/sna/kgem.h | 1 | ||||
-rw-r--r-- | src/sna/sna_display.c | 3 | ||||
-rw-r--r-- | src/sna/sna_dri2.c | 2 |
4 files changed, 23 insertions, 3 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index abb9e029..06c16849 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -4945,6 +4945,8 @@ int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo) #if defined(DRM_IOCTL_PRIME_HANDLE_TO_FD) && defined(O_CLOEXEC) struct drm_prime_handle args; + assert(kgem_bo_is_fenced(kgem, bo)); + VG_CLEAR(args); args.handle = bo->handle; args.flags = O_CLOEXEC; @@ -5322,8 +5324,6 @@ static void set_gpu_tiling(struct kgem *kgem, DBG(("%s: handle=%d, tiling=%d, pitch=%d\n", __FUNCTION__, bo->handle, tiling, pitch)); - assert(!kgem->can_fence); - if (tiling_changed(bo, tiling, pitch) && bo->map__gtt) { if (!list_is_empty(&bo->vma)) { list_del(&bo->vma); @@ -5337,6 +5337,20 @@ static void set_gpu_tiling(struct kgem *kgem, bo->pitch = pitch; } +bool kgem_bo_is_fenced(struct kgem *kgem, struct kgem_bo *bo) +{ + struct drm_i915_gem_get_tiling tiling; + + assert(kgem); + assert(bo); + + VG_CLEAR(tiling); + tiling.handle = bo->handle; + tiling.tiling_mode = 0; + (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling); + return tiling.tiling_mode == bo->tiling; /* assume pitch is fine! */ +} + struct kgem_bo *kgem_create_2d(struct kgem *kgem, int width, int height, @@ -6954,6 +6968,8 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo) { struct drm_gem_flink flink; + assert(kgem_bo_is_fenced(kgem, bo)); + VG_CLEAR(flink); flink.handle = bo->handle; if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_FLINK, &flink)) diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 0a941e03..3630b5ce 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -326,6 +326,7 @@ bool kgem_bo_convert_to_gpu(struct kgem *kgem, struct kgem_bo *bo, unsigned flags); +bool kgem_bo_is_fenced(struct kgem *kgem, struct kgem_bo *bo); uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format); void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 92563008..7d2478cc 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -534,6 +534,9 @@ static unsigned get_fb(struct sna *sna, struct kgem_bo *bo, ScrnInfoPtr scrn = sna->scrn; struct drm_mode_fb_cmd arg; + if (!kgem_bo_is_fenced(&sna->kgem, bo)) + return 0; + assert(bo->refcnt); assert(bo->proxy == NULL); assert(!bo->snoop); diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index afd26037..18ff264e 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -528,7 +528,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna, assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); - if (!sna->kgem.can_fence) { + if (!kgem_bo_is_fenced(&sna->kgem, priv->gpu_bo)) { if (priv->gpu_bo->tiling && !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { DBG(("%s: failed to discard tiling (%d) for DRI2 protocol\n", __FUNCTION__, priv->gpu_bo->tiling)); |