summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-03-16 11:12:01 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-03-16 11:12:01 +0000
commitb306dc20e3e92a62f60c4155e18cdcba650b1a62 (patch)
tree4b0baf7e8d58ab3e7be44120dc6214c181fe9325
parente042b5d82558293ef06847f4833efc91a95b5d40 (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.c20
-rw-r--r--src/sna/kgem.h1
-rw-r--r--src/sna/sna_display.c3
-rw-r--r--src/sna/sna_dri2.c2
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));