diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-02-07 22:54:37 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-02-08 11:23:02 +0000 |
commit | c69b4389abc324533a9a311c17a667bf8a1e1673 (patch) | |
tree | ed7897e81fdfff4cb7724baa6eb5d8465d00ac28 /src/sna | |
parent | bec99de812ce6a1bbc2c8e4cfd05f4f74c560ea6 (diff) |
sna/gen4: Split the have_render flag in separate prefer_gpu hints
The idea is to implement more fine-grained checks as we may want
different heuristics for desktops with GT1s than for mobile GT2s, etc.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/gen2_render.c | 4 | ||||
-rw-r--r-- | src/sna/gen3_render.c | 15 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 50 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 43 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 28 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 28 | ||||
-rw-r--r-- | src/sna/sna.h | 3 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 23 | ||||
-rw-r--r-- | src/sna/sna_composite.c | 2 | ||||
-rw-r--r-- | src/sna/sna_glyphs.c | 19 | ||||
-rw-r--r-- | src/sna/sna_render.c | 15 | ||||
-rw-r--r-- | src/sna/sna_render.h | 5 | ||||
-rw-r--r-- | src/sna/sna_render_inline.h | 18 | ||||
-rw-r--r-- | src/sna/sna_trapezoids.c | 139 |
14 files changed, 226 insertions, 166 deletions
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c index b539e278..4d92adcf 100644 --- a/src/sna/gen2_render.c +++ b/src/sna/gen2_render.c @@ -2227,7 +2227,7 @@ gen2_check_composite_spans(struct sna *sna, return false; if (need_tiling(sna, width, height)) { - if (!is_gpu(dst->pDrawable)) { + if (!is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; @@ -3143,10 +3143,12 @@ bool gen2_render_init(struct sna *sna) */ #if !NO_COMPOSITE render->composite = gen2_render_composite; + render->prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS render->check_composite_spans = gen2_check_composite_spans; render->composite_spans = gen2_render_composite_spans; + render->prefer_gpu |= PREFER_GPU_SPANS; #endif render->fill_boxes = gen2_render_fill_boxes; render->fill = gen2_render_fill; diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index 6b9a2f81..95d44ab5 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -2658,7 +2658,7 @@ source_use_blt(struct sna *sna, PicturePtr picture) if (too_large(picture->pDrawable->width, picture->pDrawable->height)) return true; - return !is_gpu(picture->pDrawable); + return !is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER); } static bool @@ -3884,12 +3884,11 @@ gen3_check_composite_spans(struct sna *sna, if (gen3_composite_fallback(sna, op, src, NULL, dst)) return false; - if (need_tiling(sna, width, height)) { - if (!is_gpu(dst->pDrawable)) { - DBG(("%s: fallback, tiled operation not on GPU\n", - __FUNCTION__)); - return false; - } + if (need_tiling(sna, width, height) && + !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { + DBG(("%s: fallback, tiled operation not on GPU\n", + __FUNCTION__)); + return false; } return true; @@ -5205,10 +5204,12 @@ bool gen3_render_init(struct sna *sna) #if !NO_COMPOSITE render->composite = gen3_render_composite; + render->prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS render->check_composite_spans = gen3_check_composite_spans; render->composite_spans = gen3_render_composite_spans; + render->prefer_gpu |= PREFER_GPU_SPANS; #endif render->video = gen3_render_video; diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index cc1778ae..53fe52a9 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -1580,15 +1580,6 @@ gen4_composite_set_target(struct sna *sna, return true; } -static inline bool -picture_is_cpu(PicturePtr picture) -{ - if (!picture->pDrawable) - return false; - - return !is_gpu(picture->pDrawable); -} - static bool try_blt(struct sna *sna, PicturePtr dst, PicturePtr src, @@ -1613,7 +1604,7 @@ try_blt(struct sna *sna, return true; /* is the source picture only in cpu memory e.g. a shm pixmap? */ - return picture_is_cpu(src); + return picture_is_cpu(sna, src); } static bool @@ -1635,9 +1626,10 @@ has_alphamap(PicturePtr p) } static bool -need_upload(PicturePtr p) +need_upload(struct sna *sna, PicturePtr p) { - return p->pDrawable && untransformed(p) && !is_gpu(p->pDrawable); + return p->pDrawable && untransformed(p) && + !is_gpu(sna, p->pDrawable, PREFER_GPU_RENDER); } static bool @@ -1660,7 +1652,7 @@ source_is_busy(PixmapPtr pixmap) } static bool -source_fallback(PicturePtr p, PixmapPtr pixmap) +source_fallback(struct sna *sna, PicturePtr p, PixmapPtr pixmap) { if (sna_picture_is_solid(p, NULL)) return false; @@ -1675,7 +1667,7 @@ source_fallback(PicturePtr p, PixmapPtr pixmap) if (pixmap && source_is_busy(pixmap)) return false; - return has_alphamap(p) || !gen4_check_filter(p) || need_upload(p); + return has_alphamap(p) || !gen4_check_filter(p) || need_upload(sna, p); } static bool @@ -1698,11 +1690,11 @@ gen4_composite_fallback(struct sna *sna, dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; - src_fallback = source_fallback(src, src_pixmap); + src_fallback = source_fallback(sna, src, src_pixmap); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; - mask_fallback = source_fallback(mask, mask_pixmap); + mask_fallback = source_fallback(sna, mask, mask_pixmap); } else { mask_pixmap = NULL; mask_fallback = false; @@ -2098,7 +2090,8 @@ gen4_check_composite_spans(struct sna *sna, return false; } - if (need_tiling(sna, width, height) && !is_gpu(dst->pDrawable)) { + if (need_tiling(sna, width, height) && + !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; @@ -2108,24 +2101,20 @@ gen4_check_composite_spans(struct sna *sna, return FORCE_SPANS > 0; if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) { - struct sna_pixmap *priv; - - if (FORCE_NONRECTILINEAR_SPANS) - return FORCE_NONRECTILINEAR_SPANS > 0; - - priv = sna_pixmap_from_drawable(dst->pDrawable); + struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); assert(priv); if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; - if ((flags & COMPOSITE_SPANS_INPLACE_HINT) == 0 && - priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) - return true; + if (flags & COMPOSITE_SPANS_INPLACE_HINT) + return false; - DBG(("%s: fallback, non-rectilinear spans to idle bo\n", - __FUNCTION__)); - return false; + if ((sna->render.prefer_gpu & PREFER_GPU_SPANS) == 0 && + dst->format == PICT_a8) + return false; + + return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } return true; @@ -3124,10 +3113,13 @@ bool gen4_render_init(struct sna *sna) #if !NO_COMPOSITE sna->render.composite = gen4_render_composite; + sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen4_check_composite_spans; sna->render.composite_spans = gen4_render_composite_spans; + if (0) + sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif #if !NO_VIDEO diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 35f70f83..6e119963 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -1556,15 +1556,6 @@ gen5_composite_set_target(struct sna *sna, return true; } -static inline bool -picture_is_cpu(PicturePtr picture) -{ - if (!picture->pDrawable) - return false; - - return !is_gpu(picture->pDrawable); -} - static bool try_blt(struct sna *sna, PicturePtr dst, PicturePtr src, @@ -1589,7 +1580,7 @@ try_blt(struct sna *sna, return true; /* is the source picture only in cpu memory e.g. a shm pixmap? */ - return picture_is_cpu(src); + return picture_is_cpu(sna, src); } static bool @@ -1614,9 +1605,10 @@ has_alphamap(PicturePtr p) } static bool -need_upload(PicturePtr p) +need_upload(struct sna *sna, PicturePtr p) { - return p->pDrawable && untransformed(p) && !is_gpu(p->pDrawable); + return p->pDrawable && untransformed(p) && + !is_gpu(sna, p->pDrawable, PREFER_GPU_RENDER); } static bool @@ -1639,7 +1631,7 @@ source_is_busy(PixmapPtr pixmap) } static bool -source_fallback(PicturePtr p, PixmapPtr pixmap) +source_fallback(struct sna *sna, PicturePtr p, PixmapPtr pixmap) { if (sna_picture_is_solid(p, NULL)) return false; @@ -1652,7 +1644,7 @@ source_fallback(PicturePtr p, PixmapPtr pixmap) if (pixmap && source_is_busy(pixmap)) return false; - return has_alphamap(p) || !gen5_check_filter(p) || need_upload(p); + return has_alphamap(p) || !gen5_check_filter(p) || need_upload(sna, p); } static bool @@ -1675,11 +1667,11 @@ gen5_composite_fallback(struct sna *sna, dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; - src_fallback = source_fallback(src, src_pixmap); + src_fallback = source_fallback(sna, src, src_pixmap); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; - mask_fallback = source_fallback(mask, mask_pixmap); + mask_fallback = source_fallback(sna, mask, mask_pixmap); } else { mask_pixmap = NULL; mask_fallback = false; @@ -2075,7 +2067,8 @@ gen5_check_composite_spans(struct sna *sna, return false; } - if (need_tiling(sna, width, height) && !is_gpu(dst->pDrawable)) { + if (need_tiling(sna, width, height) && + !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; @@ -2088,13 +2081,14 @@ gen5_check_composite_spans(struct sna *sna, if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; - if ((flags & COMPOSITE_SPANS_INPLACE_HINT) == 0 && - priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) - return true; + if (flags & COMPOSITE_SPANS_INPLACE_HINT) + return false; - DBG(("%s: fallback, non-rectilinear spans to idle bo\n", - __FUNCTION__)); - return false; + if ((sna->render.prefer_gpu & PREFER_GPU_SPANS) == 0 && + dst->format == PICT_a8) + return false; + + return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } return true; @@ -3272,10 +3266,13 @@ bool gen5_render_init(struct sna *sna) #if !NO_COMPOSITE sna->render.composite = gen5_render_composite; + sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen5_check_composite_spans; sna->render.composite_spans = gen5_render_composite_spans; + if (DEVICE_ID(sna->PciInfo) == 0x0044) + sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif sna->render.video = gen5_render_video; diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index ec642504..76d0c8ca 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -2422,7 +2422,8 @@ gen6_check_composite_spans(struct sna *sna, return false; } - if (need_tiling(sna, width, height) && !is_gpu(dst->pDrawable)) { + if (need_tiling(sna, width, height) && + !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; @@ -2435,13 +2436,10 @@ gen6_check_composite_spans(struct sna *sna, if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; - if ((flags & COMPOSITE_SPANS_INPLACE_HINT) == 0 && - priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) - return true; + if (flags & COMPOSITE_SPANS_INPLACE_HINT) + return false; - DBG(("%s: fallback, non-rectilinear spans to idle bo\n", - __FUNCTION__)); - return false; + return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } return true; @@ -3557,6 +3555,16 @@ static void gen6_render_fini(struct sna *sna) kgem_bo_destroy(&sna->kgem, sna->render_state.gen6.general_bo); } +static bool is_gt2(struct sna *sna) +{ + return DEVICE_ID(sna->PciInfo) & 0x20; +} + +static bool is_mobile(struct sna *sna) +{ + return (DEVICE_ID(sna->PciInfo) & 0xf) == 0x6; +} + static bool gen6_render_setup(struct sna *sna) { struct gen6_render_state *state = &sna->render_state.gen6; @@ -3565,7 +3573,7 @@ static bool gen6_render_setup(struct sna *sna) int i, j, k, l, m; state->info = >1_info; - if (DEVICE_ID(sna->PciInfo) & 0x20) + if (is_gt2(sna)) state->info = >2_info; /* XXX requires GT_MODE WiZ disabled */ sna_static_stream_init(&general); @@ -3646,10 +3654,14 @@ bool gen6_render_init(struct sna *sna) #if !NO_COMPOSITE sna->render.composite = gen6_render_composite; + sna->render.prefer_gpu |= PREFER_GPU_RENDER; + #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen6_check_composite_spans; sna->render.composite_spans = gen6_render_composite_spans; + if (is_mobile(sna)) + sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif sna->render.video = gen6_render_video; diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 59b38f6c..f05d6f92 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -2553,12 +2553,11 @@ gen7_check_composite_spans(struct sna *sna, if (gen7_composite_fallback(sna, src, NULL, dst)) return false; - if (need_tiling(sna, width, height)) { - if (!is_gpu(dst->pDrawable)) { - DBG(("%s: fallback, tiled operation not on GPU\n", - __FUNCTION__)); - return false; - } + if (need_tiling(sna, width, height) && + !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { + DBG(("%s: fallback, tiled operation not on GPU\n", + __FUNCTION__)); + return false; } return true; @@ -3647,6 +3646,16 @@ static void gen7_render_fini(struct sna *sna) kgem_bo_destroy(&sna->kgem, sna->render_state.gen7.general_bo); } +static bool is_gt2(struct sna *sna) +{ + return DEVICE_ID(sna->PciInfo) & 0x20; +} + +static bool is_mobile(struct sna *sna) +{ + return (DEVICE_ID(sna->PciInfo) & 0xf) == 0x6; +} + static bool gen7_render_setup(struct sna *sna) { struct gen7_render_state *state = &sna->render_state.gen7; @@ -3658,14 +3667,14 @@ static bool gen7_render_setup(struct sna *sna) state->info = &ivb_gt_info; if (DEVICE_ID(sna->PciInfo) & 0xf) { state->info = &ivb_gt1_info; - if (DEVICE_ID(sna->PciInfo) & 0x20) + if (is_gt2(sna)) state->info = &ivb_gt2_info; /* XXX requires GT_MODE WiZ disabled */ } } else if (sna->kgem.gen == 075) { state->info = &hsw_gt_info; if (DEVICE_ID(sna->PciInfo) & 0xf) { state->info = &hsw_gt1_info; - if (DEVICE_ID(sna->PciInfo) & 0x20) + if (is_gt2(sna)) state->info = &hsw_gt2_info; } } else @@ -3744,10 +3753,13 @@ bool gen7_render_init(struct sna *sna) #if !NO_COMPOSITE sna->render.composite = gen7_render_composite; + sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen7_check_composite_spans; sna->render.composite_spans = gen7_render_composite_spans; + if (is_mobile(sna)) + sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif sna->render.video = gen7_render_video; diff --git a/src/sna/sna.h b/src/sna/sna.h index e4073596..5a57a6e2 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -256,7 +256,6 @@ struct sna { struct gen6_render_state gen6; struct gen7_render_state gen7; } render_state; - uint32_t have_render; bool dri_available; bool dri_open; @@ -672,7 +671,7 @@ static inline bool wedged(struct sna *sna) static inline bool can_render(struct sna *sna) { - return likely(!sna->kgem.wedged && sna->have_render); + return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER); } static inline uint32_t pixmap_size(PixmapPtr pixmap) diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 7c8a3609..0edc1e8b 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -879,7 +879,8 @@ sna_pixmap_create_scratch(ScreenPtr screen, width, height, depth, tiling)); bpp = bits_per_pixel(depth); - if (tiling == I915_TILING_Y && !sna->have_render) + if (tiling == I915_TILING_Y && + (sna->render.prefer_gpu & PREFER_GPU_RENDER) == 0) tiling = I915_TILING_X; if (tiling == I915_TILING_Y && @@ -1180,7 +1181,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, goto fallback; } - if (unlikely(!sna->have_render)) + if (unlikely((sna->render.prefer_gpu & PREFER_GPU_RENDER) == 0)) flags &= ~KGEM_CAN_CREATE_GPU; if (wedged(sna)) flags = 0; @@ -14199,31 +14200,30 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna) return false; backend = "no"; - sna->have_render = false; no_render_init(sna); if (sna_option_accel_blt(sna) || sna->info->gen >= 0100) { } else if (sna->info->gen >= 070) { - if ((sna->have_render = gen7_render_init(sna))) + if (gen7_render_init(sna)) backend = "IvyBridge"; } else if (sna->info->gen >= 060) { - if ((sna->have_render = gen6_render_init(sna))) + if (gen6_render_init(sna)) backend = "SandyBridge"; } else if (sna->info->gen >= 050) { - if ((sna->have_render = gen5_render_init(sna))) + if (gen5_render_init(sna)) backend = "Ironlake"; } else if (sna->info->gen >= 040) { - if ((sna->have_render = gen4_render_init(sna))) + if (gen4_render_init(sna)) backend = "Broadwater/Crestline"; } else if (sna->info->gen >= 030) { - if ((sna->have_render = gen3_render_init(sna))) + if (gen3_render_init(sna)) backend = "gen3"; } else if (sna->info->gen >= 020) { - if ((sna->have_render = gen2_render_init(sna))) + if (gen2_render_init(sna)) backend = "gen2"; } - DBG(("%s(backend=%s, have_render=%d)\n", - __FUNCTION__, backend, sna->have_render)); + DBG(("%s(backend=%s, prefer_gpu=%x)\n", + __FUNCTION__, backend, sna->render.prefer_gpu)); kgem_reset(&sna->kgem); @@ -14252,7 +14252,6 @@ void sna_accel_create(struct sna *sna) fail: xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Failed to allocate caches, disabling RENDER acceleration\n"); - sna->have_render = false; no_render_init(sna); } diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index e82d5f49..c329fb8b 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -584,7 +584,7 @@ sna_composite(CARD8 op, } if (use_cpu(pixmap, priv, op, width, height) && - !picture_is_gpu(src) && !picture_is_gpu(mask)) { + !picture_is_gpu(sna, src) && !picture_is_gpu(sna, mask)) { DBG(("%s: fallback, dst pixmap=%ld is too small (or completely damaged)\n", __FUNCTION__, pixmap->drawable.serialNumber)); goto fallback; diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index 130c1eaa..ad050df6 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -193,11 +193,17 @@ bool sna_glyphs_create(struct sna *sna) if (sna->render.white_image == NULL) goto bail; - if (!can_render(sna)) + if (!can_render(sna)) { + DBG(("%s: no render acceleration, no render glyph caches\n", + __FUNCTION__)); return true; + } - if (xf86IsEntityShared(sna->scrn->entityList[0])) + if (xf86IsEntityShared(sna->scrn->entityList[0])) { + DBG(("%s: shared GlyphPictures, no render glyph caches\n", + __FUNCTION__)); return true; + } for (i = 0; i < ARRAY_SIZE(formats); i++) { struct sna_glyph_cache *cache = &sna->render.glyph[i]; @@ -218,8 +224,11 @@ bool sna_glyphs_create(struct sna *sna) CACHE_PICTURE_SIZE, depth, SNA_CREATE_GLYPHS); - if (!pixmap) + if (!pixmap) { + DBG(("%s: failed to allocate pixmap for Glyph cache\n", + __FUNCTION__)); goto bail; + } priv = sna_pixmap(pixmap); if (priv != NULL) { @@ -1678,7 +1687,7 @@ sna_glyphs(CARD8 op, } if ((too_small(priv) || DAMAGE_IS_ALL(priv->cpu_damage)) && - !picture_is_gpu(src)) { + !picture_is_gpu(sna, src)) { DBG(("%s: fallback -- too small (%dx%d)\n", __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height)); goto fallback; @@ -2002,7 +2011,7 @@ sna_glyphs__shared(CARD8 op, } if ((too_small(priv) || DAMAGE_IS_ALL(priv->cpu_damage)) && - !picture_is_gpu(src)) { + !picture_is_gpu(sna, src)) { DBG(("%s: fallback -- too small (%dx%d)\n", __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height)); goto fallback; diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index 7784a5b1..6c5d962d 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -87,8 +87,8 @@ no_render_composite(struct sna *sna, if (mask) return false; - if (!is_gpu(dst->pDrawable) && - (src->pDrawable == NULL || !is_gpu(src->pDrawable))) + if (!is_gpu(sna, dst->pDrawable, PREFER_GPU_BLT) && + (src->pDrawable == NULL || !is_gpu(sna, src->pDrawable, PREFER_GPU_BLT))) return false; return sna_blt_composite(sna, @@ -279,7 +279,9 @@ void no_render_init(struct sna *sna) { struct sna_render *render = &sna->render; - memset (render,0, sizeof (*render)); + memset (render, 0, sizeof (*render)); + + render->prefer_gpu = PREFER_GPU_BLT; render->vertices = render->vertex_data; render->vertex_size = ARRAY_SIZE(render->vertex_data); @@ -1533,7 +1535,8 @@ sna_render_picture_fixup(struct sna *sna, if (picture->alphaMap) { DBG(("%s: alphamap\n", __FUNCTION__)); - if (is_gpu(picture->pDrawable) || is_gpu(picture->alphaMap->pDrawable)) { + if (is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER) || + is_gpu(sna, picture->alphaMap->pDrawable, PREFER_GPU_RENDER)) { return sna_render_picture_flatten(sna, picture, channel, x, y, w, h, dst_x, dst_y); } @@ -1543,7 +1546,7 @@ sna_render_picture_fixup(struct sna *sna, if (picture->filter == PictFilterConvolution) { DBG(("%s: convolution\n", __FUNCTION__)); - if (is_gpu(picture->pDrawable)) { + if (is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER)) { return sna_render_picture_convolve(sna, picture, channel, x, y, w, h, dst_x, dst_y); } @@ -1704,7 +1707,7 @@ sna_render_picture_convert(struct sna *sna, return 0; } - if (fixup_alpha && is_gpu(&pixmap->drawable)) { + if (fixup_alpha && is_gpu(sna, &pixmap->drawable, PREFER_GPU_RENDER)) { ScreenPtr screen = pixmap->drawable.pScreen; PixmapPtr tmp; PicturePtr src, dst; diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index a8084f27..01176c6a 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -215,6 +215,11 @@ struct sna_render { int max_3d_size; int max_3d_pitch; + unsigned prefer_gpu; +#define PREFER_GPU_BLT 0x1 +#define PREFER_GPU_RENDER 0x2 +#define PREFER_GPU_SPANS 0x4 + bool (*composite)(struct sna *sna, uint8_t op, PicturePtr dst, PicturePtr src, PicturePtr mask, int16_t src_x, int16_t src_y, diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h index 432201f5..7d9f2cac 100644 --- a/src/sna/sna_render_inline.h +++ b/src/sna/sna_render_inline.h @@ -67,7 +67,7 @@ static inline void batch_emit_float(struct sna *sna, float f) } static inline bool -is_gpu(DrawablePtr drawable) +is_gpu(struct sna *sna, DrawablePtr drawable, unsigned prefer) { struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable); @@ -77,7 +77,8 @@ is_gpu(DrawablePtr drawable) if (priv->cpu_damage == NULL) return true; - if (priv->gpu_damage && !priv->gpu_bo->proxy) + if (priv->gpu_damage && !priv->gpu_bo->proxy && + (sna->render.prefer_gpu & prefer)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) @@ -108,11 +109,20 @@ unattached(DrawablePtr drawable) } static inline bool -picture_is_gpu(PicturePtr picture) +picture_is_gpu(struct sna *sna, PicturePtr picture) { if (!picture || !picture->pDrawable) return false; - return is_gpu(picture->pDrawable); + return is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER); +} + +static inline bool +picture_is_cpu(struct sna *sna, PicturePtr picture) +{ + if (!picture->pDrawable) + return false; + + return !is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER); } static inline bool sna_blt_compare_depth(DrawablePtr src, DrawablePtr dst) diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 547e4f53..406a6b31 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -2457,7 +2457,8 @@ is_mono(PicturePtr dst, PictFormatPtr mask) } static bool -trapezoids_inplace_fallback(CARD8 op, +trapezoids_inplace_fallback(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask, int ntrap, xTrapezoid *traps) { @@ -2497,7 +2498,7 @@ trapezoids_inplace_fallback(CARD8 op, return false; } - if (is_gpu(dst->pDrawable)) { + if (is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: not performing inplace as dst is already on the GPU\n", __FUNCTION__)); return false; @@ -2581,7 +2582,8 @@ static void rasterize_traps_thread(void *arg) } static void -trapezoids_fallback(CARD8 op, PicturePtr src, PicturePtr dst, +trapezoids_fallback(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps) { @@ -2636,7 +2638,8 @@ trapezoids_fallback(CARD8 op, PicturePtr src, PicturePtr dst, DBG(("%s: mask (%dx%d) depth=%d, format=%08x\n", __FUNCTION__, width, height, depth, format)); - if (is_gpu(dst->pDrawable) || picture_is_gpu(src)) { + if (is_gpu(sna, dst->pDrawable, PREFER_GPU_RENDER) || + picture_is_gpu(sna, src)) { int num_threads; scratch = sna_pixmap_create_upload(screen, @@ -2760,7 +2763,7 @@ trapezoids_fallback(CARD8 op, PicturePtr src, PicturePtr dst, maskFormat = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) - trapezoids_fallback(op, + trapezoids_fallback(sna, op, src, dst, maskFormat, xSrc, ySrc, 1, traps); } @@ -3420,7 +3423,8 @@ pixsolid_unaligned_box_row(struct pixman_inplace *pi, } static bool -composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color, +composite_unaligned_boxes_inplace__solid(struct sna *sna, + CARD8 op, uint32_t color, PicturePtr dst, int n, xTrapezoid *t, bool force_fallback) { @@ -3428,9 +3432,9 @@ composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color, int16_t dx, dy; DBG(("%s: force=%d, is_gpu=%d, op=%d, color=%x\n", __FUNCTION__, - force_fallback, is_gpu(dst->pDrawable), op, color)); + force_fallback, is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS), op, color)); - if (!force_fallback && is_gpu(dst->pDrawable)) { + if (!force_fallback && is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback -- can not perform operation in place, destination busy\n", __FUNCTION__)); @@ -3744,13 +3748,15 @@ static void rectilinear_inplace_thread(void *arg) } static bool -composite_unaligned_boxes_inplace(CARD8 op, +composite_unaligned_boxes_inplace(struct sna *sna, + CARD8 op, PicturePtr src, int16_t src_x, int16_t src_y, PicturePtr dst, int n, xTrapezoid *t, bool force_fallback) { if (!force_fallback && - (is_gpu(dst->pDrawable) || picture_is_gpu(src))) { + (is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS) || + picture_is_gpu(sna, src))) { DBG(("%s: fallback -- not forcing\n", __FUNCTION__)); return false; } @@ -3894,7 +3900,8 @@ composite_unaligned_boxes_inplace(CARD8 op, } static bool -composite_unaligned_boxes_fallback(CARD8 op, +composite_unaligned_boxes_fallback(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, @@ -3908,12 +3915,12 @@ composite_unaligned_boxes_fallback(CARD8 op, int n; if (sna_picture_is_solid(src, &color) && - composite_unaligned_boxes_inplace__solid(op, color, dst, + composite_unaligned_boxes_inplace__solid(sna, op, color, dst, ntrap, traps, force_fallback)) return true; - if (composite_unaligned_boxes_inplace(op, src, src_x, src_y, + if (composite_unaligned_boxes_inplace(sna, op, src, src_x, src_y, dst, ntrap, traps, force_fallback)) return true; @@ -4037,7 +4044,7 @@ composite_unaligned_boxes(struct sna *sna, !sna->render.check_composite_spans(sna, op, src, dst, 0, 0, COMPOSITE_SPANS_RECTILINEAR)) { fallback: - return composite_unaligned_boxes_fallback(op, src, dst, + return composite_unaligned_boxes_fallback(sna, op, src, dst, src_x, src_y, ntrap, traps, force_fallback); @@ -4285,7 +4292,8 @@ mono_span_thread(void *arg) } static bool -mono_trapezoids_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, +mono_trapezoids_span_converter(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { @@ -4336,7 +4344,7 @@ mono_trapezoids_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, unbounded = (!sna_drawable_is_clear(dst->pDrawable) && !operator_is_bounded(op)); - mono.sna = to_sna_from_drawable(dst->pDrawable); + mono.sna = sna; if (!mono.sna->render.composite(mono.sna, op, src, NULL, dst, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy, @@ -4620,12 +4628,12 @@ span_thread(void *arg) } static bool -trapezoid_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, +trapezoid_span_converter(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned int flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { - struct sna *sna; struct sna_composite_spans_op tmp; BoxRec extents; pixman_region16_t clip; @@ -4638,7 +4646,7 @@ trapezoid_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, return false; if (is_mono(dst, maskFormat)) - return mono_trapezoids_span_converter(op, src, dst, + return mono_trapezoids_span_converter(sna, op, src, dst, src_x, src_y, ntrap, traps); @@ -4649,7 +4657,6 @@ trapezoid_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, return false; } - sna = to_sna_from_drawable(dst->pDrawable); if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, flags)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); @@ -5315,7 +5322,8 @@ mono_inplace_composite_boxes(struct sna *sna, } static bool -trapezoid_spans_maybe_inplace(CARD8 op, PicturePtr src, PicturePtr dst, +trapezoid_spans_maybe_inplace(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat) { struct sna_pixmap *priv; @@ -5348,7 +5356,7 @@ trapezoid_spans_maybe_inplace(CARD8 op, PicturePtr src, PicturePtr dst, case PICT_x8r8g8b8: case PICT_a8r8g8b8: - if (picture_is_gpu(src)) + if (picture_is_gpu(sna, src)) return false; switch (op) { @@ -5395,7 +5403,8 @@ out: } static bool -trapezoid_span_mono_inplace(CARD8 op, +trapezoid_span_mono_inplace(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, @@ -5441,7 +5450,7 @@ trapezoid_span_mono_inplace(CARD8 op, MOVE_WRITE | MOVE_READ)) return true; - mono.sna = to_sna_from_drawable(dst->pDrawable); + mono.sna = sna; if (!mono_init(&mono, 2*ntrap)) return false; @@ -6052,7 +6061,8 @@ static void inplace_thread(void *arg) } static bool -trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, +trapezoid_span_inplace(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback) @@ -6082,7 +6092,7 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, return false; } - if (!fallback && is_gpu(dst->pDrawable)) { + if (!fallback && is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback -- can not perform operation in place, destination busy\n", __FUNCTION__)); @@ -6090,7 +6100,7 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, } if (is_mono(dst, maskFormat)) - return trapezoid_span_mono_inplace(op, src, dst, + return trapezoid_span_mono_inplace(sna, op, src, dst, src_x, src_y, ntrap, traps); if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8) @@ -6165,7 +6175,7 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, __FUNCTION__)); do { /* XXX unwind errors? */ - if (!trapezoid_span_inplace(op, src, dst, NULL, + if (!trapezoid_span_inplace(sna, op, src, dst, NULL, src_x, src_y, 1, traps++, fallback)) return false; @@ -6476,14 +6486,14 @@ sna_composite_trapezoids(CARD8 op, force_fallback = FORCE_FALLBACK > 0; if ((too_small(priv) || DAMAGE_IS_ALL(priv->cpu_damage)) && - !picture_is_gpu(src) && untransformed(src)) { + !picture_is_gpu(sna, src) && untransformed(src)) { DBG(("%s: force fallbacks --too small, %dx%d? %d, all-cpu? %d, src-is-cpu? %d\n", __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height, too_small(priv), (int)DAMAGE_IS_ALL(priv->cpu_damage), - !picture_is_gpu(src))); + !picture_is_gpu(sna, src))); force_fallback = true; } if (FORCE_FALLBACK < 0) @@ -6550,24 +6560,24 @@ sna_composite_trapezoids(CARD8 op, goto fallback; if (is_mono(dst, maskFormat) && - mono_trapezoids_span_converter(op, src, dst, + mono_trapezoids_span_converter(sna, op, src, dst, xSrc, ySrc, ntrap, traps)) return; - if (trapezoid_spans_maybe_inplace(op, src, dst, maskFormat)) { + if (trapezoid_spans_maybe_inplace(sna, op, src, dst, maskFormat)) { flags |= COMPOSITE_SPANS_INPLACE_HINT; - if (trapezoid_span_inplace(op, src, dst, maskFormat, + if (trapezoid_span_inplace(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps, false)) return; } - if (trapezoid_span_converter(op, src, dst, maskFormat, flags, + if (trapezoid_span_converter(sna, op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps)) return; - if (trapezoid_span_inplace(op, src, dst, maskFormat, + if (trapezoid_span_inplace(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps, false)) return; @@ -6577,7 +6587,7 @@ sna_composite_trapezoids(CARD8 op, return; fallback: - if (trapezoid_span_inplace(op, src, dst, maskFormat, + if (trapezoid_span_inplace(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps, true)) return; @@ -6586,12 +6596,13 @@ fallback: xSrc, ySrc, ntrap, traps)) return; - if (trapezoids_inplace_fallback(op, src, dst, maskFormat, ntrap, traps)) + if (trapezoids_inplace_fallback(sna, op, src, dst, maskFormat, + ntrap, traps)) return; DBG(("%s: fallback mask=%08x, ntrap=%d\n", __FUNCTION__, maskFormat ? (unsigned)maskFormat->format : 0, ntrap)); - trapezoids_fallback(op, src, dst, maskFormat, + trapezoids_fallback(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps); } @@ -6613,7 +6624,8 @@ project_trap_onto_grid(const xTrap *in, } static bool -mono_trap_span_converter(PicturePtr dst, +mono_trap_span_converter(struct sna *sna, + PicturePtr dst, INT16 x, INT16 y, int ntrap, xTrap *traps) { @@ -6638,7 +6650,7 @@ mono_trap_span_converter(PicturePtr dst, mono.clip.extents.x2, mono.clip.extents.y2, x, y)); - mono.sna = to_sna_from_drawable(dst->pDrawable); + mono.sna = sna; if (!mono_init(&mono, 2*ntrap)) return false; @@ -6683,11 +6695,11 @@ mono_trap_span_converter(PicturePtr dst, } static bool -trap_span_converter(PicturePtr dst, +trap_span_converter(struct sna *sna, + PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrap *trap) { - struct sna *sna; struct sna_composite_spans_op tmp; struct tor tor; BoxRec extents; @@ -6701,9 +6713,8 @@ trap_span_converter(PicturePtr dst, return false; if (dst->polyEdge == PolyEdgeSharp) - return mono_trap_span_converter(dst, src_x, src_y, ntrap, trap); + return mono_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); - sna = to_sna_from_drawable(dst->pDrawable); if (!sna->render.check_composite_spans(sna, PictOpAdd, sna->render.white_picture, dst, dst->pCompositeClip->extents.x2 - dst->pCompositeClip->extents.x1, dst->pCompositeClip->extents.y2 - dst->pCompositeClip->extents.y1, @@ -6795,11 +6806,11 @@ static void mark_damaged(PixmapPtr pixmap, struct sna_pixmap *priv, } static bool -trap_mask_converter(PicturePtr picture, +trap_mask_converter(struct sna *sna, + PicturePtr picture, INT16 x, INT16 y, int ntrap, xTrap *trap) { - struct sna *sna; struct tor tor; ScreenPtr screen = picture->pDrawable->pScreen; PixmapPtr scratch, pixmap; @@ -6993,13 +7004,18 @@ trap_upload(PicturePtr picture, void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t) { + struct sna *sna; + DBG(("%s (%d, %d) x %d\n", __FUNCTION__, x, y, n)); - if (is_gpu(picture->pDrawable)) { - if (trap_span_converter(picture, x, y, n, t)) + sna = to_sna_from_drawable(picture->pDrawable); + if (is_gpu(sna, picture->pDrawable, PREFER_GPU_SPANS)) { + if (trap_span_converter(sna, picture, x, y, n, t)) return; + } - if (trap_mask_converter(picture, x, y, n, t)) + if (is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER)) { + if (trap_mask_converter(sna, picture, x, y, n, t)) return; if (trap_upload(picture, x, y, n, t)) @@ -7064,7 +7080,8 @@ project_triangle_onto_grid(const xTriangle *in, } static bool -mono_triangles_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, +mono_triangles_span_converter(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int count, xTriangle *tri) { @@ -7075,7 +7092,7 @@ mono_triangles_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, bool was_clear; int n; - mono.sna = to_sna_from_drawable(dst->pDrawable); + mono.sna = sna; dst_x = pixman_fixed_to_int(tri[0].p1.x); dst_y = pixman_fixed_to_int(tri[0].p1.y); @@ -7200,11 +7217,11 @@ mono_triangles_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, } static bool -triangles_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, +triangles_span_converter(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xTriangle *tri) { - struct sna *sna; struct sna_composite_spans_op tmp; struct tor tor; BoxRec extents; @@ -7217,7 +7234,7 @@ triangles_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, return false; if (is_mono(dst, maskFormat)) - return mono_triangles_span_converter(op, src, dst, + return mono_triangles_span_converter(sna, op, src, dst, src_x, src_y, count, tri); @@ -7228,7 +7245,6 @@ triangles_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, return false; } - sna = to_sna_from_drawable(dst->pDrawable); if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); @@ -7553,7 +7569,9 @@ sna_composite_triangles(CARD8 op, INT16 xSrc, INT16 ySrc, int n, xTriangle *tri) { - if (triangles_span_converter(op, src, dst, maskFormat, + struct sna *sna = to_sna_from_drawable(dst->pDrawable); + + if (triangles_span_converter(sna, op, src, dst, maskFormat, xSrc, ySrc, n, tri)) return; @@ -7567,11 +7585,11 @@ sna_composite_triangles(CARD8 op, } static bool -tristrip_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, +tristrip_span_converter(struct sna *sna, + CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xPointFixed *points) { - struct sna *sna; struct sna_composite_spans_op tmp; struct tor tor; BoxRec extents; @@ -7592,7 +7610,6 @@ tristrip_span_converter(CARD8 op, PicturePtr src, PicturePtr dst, return false; } - sna = to_sna_from_drawable(dst->pDrawable); if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); @@ -7833,7 +7850,9 @@ sna_composite_tristrip(CARD8 op, INT16 xSrc, INT16 ySrc, int n, xPointFixed *points) { - if (tristrip_span_converter(op, src, dst, maskFormat, xSrc, ySrc, n, points)) + struct sna *sna = to_sna_from_drawable(dst->pDrawable); + + if (tristrip_span_converter(sna, op, src, dst, maskFormat, xSrc, ySrc, n, points)) return; tristrip_fallback(op, src, dst, maskFormat, xSrc, ySrc, n, points); |