From 6c8fc4434330ee37a290b6cf466af3282d09a8b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 5 Nov 2016 23:40:28 +0000 Subject: [PATCH] sna: Mark up CPU writes for scanout flush When we flip to a bo, the kernel will flush it from the CPU write domain and so afterwards we need to do a new set-domain to mark up a subsequent CPU write (and flush before another flip). References: https://bugs.freedesktop.org/show_bug.cgi?id=95414 Signed-off-by: Chris Wilson --- src/sna/kgem.c | 8 ++++---- src/sna/kgem.h | 13 ++++++++++--- src/sna/sna_display.c | 8 +++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/sna/kgem.c b/src/sna/kgem.c index c57624cc..f0d171ac 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -6179,9 +6179,7 @@ void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo) /* Whatever actually happens, we can regard the GTT write domain * as being flushed. */ - bo->gtt_dirty = false; - bo->needs_flush = false; - bo->domain = DOMAIN_NONE; + __kgem_bo_clear_dirty(bo); } inline static bool nearly_idle(struct kgem *kgem) @@ -7107,6 +7105,7 @@ void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo) bo->needs_flush = false; kgem_bo_retire(kgem, bo); bo->domain = DOMAIN_CPU; + bo->gtt_dirty = true; } } @@ -7147,10 +7146,11 @@ void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write) DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } + bo->needs_flush = false; if (write) { - bo->needs_flush = false; kgem_bo_retire(kgem, bo); bo->domain = DOMAIN_CPU; + bo->gtt_dirty = true; } else { if (bo->exec == NULL) kgem_bo_maybe_retire(kgem, bo); diff --git a/src/sna/kgem.h b/src/sna/kgem.h index ded8f78f..08b4eb20 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -638,15 +638,22 @@ static inline void kgem_bo_mark_busy(struct kgem *kgem, struct kgem_bo *bo, int } } +static inline void __kgem_bo_clear_dirty(struct kgem_bo *bo) +{ + DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); + + bo->domain = DOMAIN_NONE; + bo->needs_flush = false; + bo->gtt_dirty = false; +} + inline static void __kgem_bo_clear_busy(struct kgem_bo *bo) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); bo->rq = NULL; list_del(&bo->request); - bo->domain = DOMAIN_NONE; - bo->needs_flush = false; - bo->gtt_dirty = false; + __kgem_bo_clear_dirty(bo); } static inline bool kgem_bo_is_busy(struct kgem_bo *bo) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 66c31476..59ecfd37 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -3037,8 +3037,10 @@ retry: /* Attach per-crtc pixmap or direct */ } /* Prevent recursion when enabling outputs during execbuffer */ - if (bo->exec && RQ(bo->rq)->bo == NULL) + if (bo->exec && RQ(bo->rq)->bo == NULL) { _kgem_submit(&sna->kgem); + __kgem_bo_clear_dirty(bo); + } sna_crtc->bo = bo; ret = sna_crtc_apply(crtc); @@ -6716,6 +6718,7 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, return false; crtc->offset = y << 16 | x; + __kgem_bo_clear_dirty(bo); return true; } @@ -6798,6 +6801,7 @@ sna_page_flip(struct sna *sna, return 0; kgem_bo_submit(&sna->kgem, bo); + __kgem_bo_clear_dirty(bo); sigio = sigio_block(); for (i = 0; i < sna->mode.num_real_crtc; i++) { @@ -8988,6 +8992,7 @@ void sna_mode_redisplay(struct sna *sna) sna_crtc_redisplay(crtc, &damage, bo); kgem_bo_submit(&sna->kgem, bo); + __kgem_bo_clear_dirty(bo); assert_crtc_fb(sna, sna_crtc); arg.crtc_id = __sna_crtc_id(sna_crtc); @@ -9092,6 +9097,7 @@ disable1: arg.reserved = 0; kgem_bo_submit(&sna->kgem, new); + __kgem_bo_clear_dirty(new); sigio = sigio_block(); for (i = 0; i < sna->mode.num_real_crtc; i++) {