@@ -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));
@@ -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);
@@ -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));
@@ -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);
... 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(+)