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 <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2016-11-05 23:40:28 +00:00
parent bf7316a453
commit 6c8fc44343
3 changed files with 21 additions and 8 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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++) {