From 3ea748b46c668f4d69d89ccabe7f8a19bcb30664 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 May 2015 07:37:35 +0100 Subject: [PATCH] sna/dri2: Refine ring selection with multiple active rings The preference given multiple rings is to the previous writer, or if none, to the render ring if active. References: https://bugs.freedesktop.org/show_bug.cgi?id=90671 Signed-off-by: Chris Wilson --- src/sna/sna_dri2.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index dbdde32..72efe20 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -870,6 +870,22 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) } } +#if defined(__GNUC__) +#define popcount(x) __builtin_popcount(x) +#else +static int popcount(unsigned int x) +{ + int count = 0; + + while (x) { + count += x&1; + x >>= 1; + } + + return count; +} +#endif + static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kgem_bo *src, bool sync) { struct drm_i915_gem_busy busy; @@ -941,7 +957,9 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg * the cost of the query. */ mode = KGEM_RENDER; - if (busy.busy & (0xfffe << 16)) + if (popcount(busy.busy >> 16) > 1) + mode = busy.busy & 0xffff ? KGEM_BLT : KGEM_RENDER; + else if (busy.busy & (0xfffe << 16)) mode = KGEM_BLT; kgem_bo_mark_busy(&sna->kgem, busy.handle == src->handle ? src : dst, mode); _kgem_set_mode(&sna->kgem, mode); -- 1.9.1