diff mbox

[xf86-video-intel] sna: Opt-out of the Kernel mmap workaround

Message ID 1458846972-20338-3-git-send-email-paulo.r.zanoni@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zanoni, Paulo R March 24, 2016, 7:16 p.m. UTC
... by issuing dirtyfb calls upon framebuffer creation. Since the
non-working SNA versions just never ever issued dirtyfb or sw_finish
calls, the Kernel workaround disables itself in case it sees one of
those calls. The problem is that we've fixed the bug by forcing
TearFree, so we're still not sending dirtyfb or sw_finish calls, so
the Kernel keeps the workaround enabled since it doesn't know we're
properly behaving. So issue one dirtyfb call each time we create a
framebuffer, making sure the Kernel sets the FB_MMAP_WA_DISABLE flag.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 src/sna/kgem.c             | 14 ++++++++++++++
 src/sna/kgem.h             |  1 +
 src/sna/sna_display.c      |  1 +
 src/sna/sna_video_sprite.c |  2 ++
 4 files changed, 18 insertions(+)
diff mbox

Patch

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 06c1684..a5969ae 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -5257,6 +5257,18 @@  __kgem_bo_create_as_display(struct kgem *kgem, int size, int tiling, int pitch)
 	return bo;
 }
 
+void kgem_mmap_wa_opt_out(struct kgem *kgem, uint32_t fb_id)
+{
+	struct drm_mode_fb_dirty_cmd cmd;
+
+	if (kgem->gen != 0110 || !kgem->has_dirtyfb)
+		return;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.fb_id = fb_id;
+	(void)drmIoctl(kgem->fd, DRM_IOCTL_MODE_DIRTYFB, &cmd);
+}
+
 static void __kgem_bo_make_scanout(struct kgem *kgem,
 				   struct kgem_bo *bo,
 				   int width, int height)
@@ -5306,6 +5318,7 @@  static void __kgem_bo_make_scanout(struct kgem *kgem,
 		DBG(("%s: attached fb=%d to handle=%d\n",
 		     __FUNCTION__, arg.fb_id, arg.handle));
 		bo->delta = arg.fb_id;
+		kgem_mmap_wa_opt_out(kgem, bo->delta);
 	}
 }
 
@@ -5479,6 +5492,7 @@  struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 
 				bo->delta = arg.fb_id;
 				bo->unique_id = kgem_get_unique_id(kgem);
+				kgem_mmap_wa_opt_out(kgem, bo->delta);
 
 				DBG(("  2:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n",
 				     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 3630b5c..02521ae 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);
 
+void kgem_mmap_wa_opt_out(struct kgem *kgem, uint32_t fb_id);
 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 7d2478c..68eea42 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -636,6 +636,7 @@  fail:
 	}
 	assert(arg.fb_id != 0);
 	bo->delta = arg.fb_id;
+	kgem_mmap_wa_opt_out(&sna->kgem, bo->delta);
 	DBG(("%s: attached fb=%d to handle=%d\n",
 	     __FUNCTION__, bo->delta, arg.handle));
 
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index ae08ef7..d95abaa 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -325,6 +325,8 @@  sna_video_sprite_show(struct sna *sna,
 		frame->bo->scanout = true;
 		/* Don't allow the scanout to be cached if not suitable for front */
 		frame->bo->purged = purged;
+
+		kgem_mmap_wa_opt_out(&sna->kgem, frame->bo->delta);
 	}
 
 	assert(frame->bo->scanout);