From c80db9bc2ef0a37a4abb78c9ef667c8b36ab6fba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 20 Aug 2012 10:45:36 +0100 Subject: [PATCH] sna: Flush the batch before preparing for a FlushCallback As we end up submitting and maybe synchronising upon a batch within FlushCallback (or our client will) it is important that we start that serialized batch as early as possible to minimise the impending stalls. Signed-off-by: Chris Wilson --- src/sna/sna.h | 2 ++ src/sna/sna_accel.c | 37 +++++++++++++++++++++---------------- src/sna/sna_render.c | 3 +-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 3c83ac59..cd55afdf 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -458,6 +458,8 @@ sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags) return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL; } +void sna_add_flush_pixmap(struct sna *sna, struct sna_pixmap *priv); + struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling); #define PREFER_GPU 0x1 diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 04dacf1f..8941be93 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1012,11 +1012,19 @@ fallback: return create_pixmap(sna, screen, width, height, depth, usage); } -static inline void add_flush_pixmap(struct sna *sna, struct sna_pixmap *priv) +void sna_add_flush_pixmap(struct sna *sna, struct sna_pixmap *priv) { DBG(("%s: marking pixmap=%ld for flushing\n", __FUNCTION__, priv->pixmap->drawable.serialNumber)); list_move(&priv->list, &sna->flush_pixmaps); + + if (sna->kgem.need_retire) + kgem_retire(&sna->kgem); + if (!sna->kgem.need_retire || !sna->kgem.flush) { + DBG(("%s: GPU idle, flushing\n", __FUNCTION__)); + kgem_submit(&sna->kgem); + } + sna->kgem.flush = true; } @@ -1065,7 +1073,7 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap) if (priv->shm && kgem_bo_is_busy(priv->cpu_bo)) { kgem_bo_submit(&sna->kgem, priv->cpu_bo); /* XXX ShmDetach */ - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } else __sna_free_pixmap(sna, pixmap, priv); return TRUE; @@ -1404,7 +1412,7 @@ skip_inplace_map: if (priv->flush) { assert(!priv->shm); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } @@ -2006,7 +2014,7 @@ done: } if (priv->flush) { assert(!priv->shm); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } @@ -2220,7 +2228,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl box, n, 0); if (ok && priv->shm) { assert(!priv->flush); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } if (!ok) { @@ -2264,7 +2272,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl box, 1, 0); if (ok && priv->shm) { assert(!priv->flush); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } if (!ok) { @@ -2299,7 +2307,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl box, n, 0); if (ok && priv->shm) { assert(!priv->flush); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } if (!ok) { @@ -2325,7 +2333,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl if (priv->shm) { assert(!priv->flush); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } done: @@ -2576,11 +2584,8 @@ use_cpu_bo: *damage = &priv->cpu_damage; if (priv->shm) { - struct sna *sna = to_sna_from_pixmap(pixmap); assert(!priv->flush); - add_flush_pixmap(sna, priv); - if (!kgem_bo_is_busy(priv->cpu_bo)) - kgem_submit(&sna->kgem); + sna_add_flush_pixmap(to_sna_from_pixmap(pixmap), priv); } DBG(("%s: using CPU bo with damage? %d\n", @@ -2802,7 +2807,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) box, n, 0); if (ok && priv->shm) { assert(!priv->flush); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } if (!ok) { @@ -2837,7 +2842,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) if (priv->shm) { assert(!priv->flush); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } /* For large bo, try to keep only a single copy around */ @@ -3392,7 +3397,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, } if (priv->flush) { assert(!priv->shm); - add_flush_pixmap(sna, priv); + sna_add_flush_pixmap(sna, priv); } } priv->cpu = true; @@ -4270,7 +4275,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (src_priv->shm) { assert(!src_priv->flush); - add_flush_pixmap(sna, src_priv); + sna_add_flush_pixmap(sna, src_priv); } if (damage) diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index 7b54f23a..13822b8a 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -378,8 +378,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt) if (priv->shm) { assert(!priv->flush); - list_move(&priv->list, &sna->flush_pixmaps); - sna->kgem.flush |= 1; + sna_add_flush_pixmap(sna, priv); } DBG(("%s for box=(%d, %d), (%d, %d)\n",