diff --git a/src/sna/gen6_common.h b/src/sna/gen6_common.h index 5da739e2..4bf69b11 100644 --- a/src/sna/gen6_common.h +++ b/src/sna/gen6_common.h @@ -52,6 +52,9 @@ inline static bool can_switch_to_blt(struct sna *sna, if (bo && RQ_IS_BLT(bo->rq)) return true; + if (bo && bo->tiling == I915_TILING_Y) + return false; + if (sna->render_state.gt < 2) return true; diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 7878e7bc..312d6afd 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -1965,54 +1965,77 @@ gen6_composite_set_target(struct sna *sna, static bool try_blt(struct sna *sna, - PicturePtr dst, PicturePtr src, - int width, int height) + uint8_t op, + PicturePtr src, + PicturePtr mask, + PicturePtr dst, + int16_t src_x, int16_t src_y, + int16_t msk_x, int16_t msk_y, + int16_t dst_x, int16_t dst_y, + int16_t width, int16_t height, + unsigned flags, + struct sna_composite_op *tmp) { struct kgem_bo *bo; if (sna->kgem.mode == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); - return true; + goto execute; } if (too_large(width, height)) { DBG(("%s: operation too large for 3D pipe (%d, %d)\n", __FUNCTION__, width, height)); - return true; + goto execute; } bo = __sna_drawable_peek_bo(dst->pDrawable); if (bo == NULL) - return true; + goto execute; if (untiled_tlb_miss(bo)) - return true; + goto execute; - if (bo->rq) - return RQ_IS_BLT(bo->rq); + if (bo->rq) { + if (RQ_IS_BLT(bo->rq)) + goto execute; + + return false; + } + + if (bo->tiling == I915_TILING_Y) + goto upload; if (src->pDrawable == dst->pDrawable && can_switch_to_blt(sna, bo, 0)) - return true; + goto execute; if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0)) - return true; + goto execute; if (src->pDrawable) { struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable); if (s == NULL) - return true; + goto execute; if (prefer_blt_bo(sna, s, bo)) - return true; + goto execute; } if (sna->kgem.ring == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); - return true; + goto execute; } - return false; +upload: + flags |= COMPOSITE_UPLOAD; +execute: + return sna_blt_composite(sna, op, + src, dst, + src_x, src_y, + dst_x, dst_y, + width, height, + flags, tmp); } static bool @@ -2242,13 +2265,13 @@ gen6_render_composite(struct sna *sna, width, height, sna->kgem.ring)); if (mask == NULL && - try_blt(sna, dst, src, width, height) && - sna_blt_composite(sna, op, - src, dst, - src_x, src_y, - dst_x, dst_y, - width, height, - flags, tmp)) + try_blt(sna, op, + src, mask, dst, + src_x, src_y, + msk_x, msk_y, + dst_x, dst_y, + width, height, + flags, tmp)) return true; if (gen6_composite_fallback(sna, src, mask, dst)) diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 39f0d385..d1de7522 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -2184,55 +2184,78 @@ gen7_composite_set_target(struct sna *sna, static bool try_blt(struct sna *sna, - PicturePtr dst, PicturePtr src, - int width, int height) + uint8_t op, + PicturePtr src, + PicturePtr mask, + PicturePtr dst, + int16_t src_x, int16_t src_y, + int16_t msk_x, int16_t msk_y, + int16_t dst_x, int16_t dst_y, + int16_t width, int16_t height, + unsigned flags, + struct sna_composite_op *tmp) { struct kgem_bo *bo; if (sna->kgem.mode == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); - return true; + goto execute; } if (too_large(width, height)) { DBG(("%s: operation too large for 3D pipe (%d, %d)\n", __FUNCTION__, width, height)); - return true; + goto execute; } bo = __sna_drawable_peek_bo(dst->pDrawable); if (bo == NULL) - return true; + goto execute; if (untiled_tlb_miss(bo)) - return true; + goto execute; - if (bo->rq) - return RQ_IS_BLT(bo->rq); + if (bo->rq) { + if (RQ_IS_BLT(bo->rq)) + goto execute; + + return false; + } + + if (bo->tiling == I915_TILING_Y) + goto upload; if (src->pDrawable == dst->pDrawable && (sna->render_state.gt < 3 || width*height < 1024) && can_switch_to_blt(sna, bo, 0)) - return true; + goto execute; if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0)) - return true; + goto execute; if (src->pDrawable) { struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable); if (s == NULL) - return true; + goto upload; if (prefer_blt_bo(sna, s, bo)) - return true; + goto execute; } if (sna->kgem.ring == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); - return true; + goto execute; } - return false; +upload: + flags |= COMPOSITE_UPLOAD; +execute: + return sna_blt_composite(sna, op, + src, dst, + src_x, src_y, + dst_x, dst_y, + width, height, + flags, tmp); } static bool @@ -2462,13 +2485,13 @@ gen7_render_composite(struct sna *sna, width, height, sna->kgem.mode, sna->kgem.ring)); if (mask == NULL && - try_blt(sna, dst, src, width, height) && - sna_blt_composite(sna, op, - src, dst, - src_x, src_y, - dst_x, dst_y, - width, height, - flags, tmp)) + try_blt(sna, op, + src, mask, dst, + src_x, src_y, + msk_x, msk_y, + dst_x, dst_y, + width, height, + flags, tmp)) return true; if (gen7_composite_fallback(sna, src, mask, dst)) diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c index c0fe9f9c..b40c582a 100644 --- a/src/sna/gen8_render.c +++ b/src/sna/gen8_render.c @@ -2029,55 +2029,78 @@ gen8_composite_set_target(struct sna *sna, static bool try_blt(struct sna *sna, - PicturePtr dst, PicturePtr src, - int width, int height) + uint8_t op, + PicturePtr src, + PicturePtr mask, + PicturePtr dst, + int16_t src_x, int16_t src_y, + int16_t msk_x, int16_t msk_y, + int16_t dst_x, int16_t dst_y, + int16_t width, int16_t height, + unsigned flags, + struct sna_composite_op *tmp) { struct kgem_bo *bo; if (sna->kgem.mode == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); - return true; + goto execute; } if (too_large(width, height)) { DBG(("%s: operation too large for 3D pipe (%d, %d)\n", __FUNCTION__, width, height)); - return true; + goto execute; } bo = __sna_drawable_peek_bo(dst->pDrawable); if (bo == NULL) - return true; + goto execute; if (untiled_tlb_miss(bo)) - return true; + goto execute; - if (bo->rq) - return RQ_IS_BLT(bo->rq); + if (bo->rq) { + if (RQ_IS_BLT(bo->rq)) + goto execute; + + return false; + } + + if (bo->tiling == I915_TILING_Y) + goto upload; if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0)) - return true; + goto execute; if (src->pDrawable == dst->pDrawable && (sna->render_state.gt < 3 || width*height < 1024) && can_switch_to_blt(sna, bo, 0)) - return true; + goto execute; if (src->pDrawable) { struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable); if (s == NULL) - return true; + goto upload; if (prefer_blt_bo(sna, s, bo)) - return true; + goto execute; } if (sna->kgem.ring == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); - return true; + goto execute; } - return false; +upload: + flags |= COMPOSITE_UPLOAD; +execute: + return sna_blt_composite(sna, op, + src, dst, + src_x, src_y, + dst_x, dst_y, + width, height, + flags, tmp); } static bool @@ -2307,13 +2330,13 @@ gen8_render_composite(struct sna *sna, width, height, sna->kgem.mode, sna->kgem.ring)); if (mask == NULL && - try_blt(sna, dst, src, width, height) && - sna_blt_composite(sna, op, - src, dst, - src_x, src_y, - dst_x, dst_y, - width, height, - flags, tmp)) + try_blt(sna, op, + src, mask, dst, + src_x, src_y, + msk_x, msk_y, + dst_x, dst_y, + width, height, + flags, tmp)) return true; if (gen8_composite_fallback(sna, src, mask, dst)) diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c index 9bb32674..1b82abcb 100644 --- a/src/sna/sna_blt.c +++ b/src/sna/sna_blt.c @@ -2606,6 +2606,8 @@ clear: } if (hint & REPLACES) kgem_bo_undo(&sna->kgem, tmp->dst.bo); + if (flags & COMPOSITE_UPLOAD) + return false; } else { RegionRec region; @@ -2692,6 +2694,8 @@ fill: } if (hint & REPLACES) kgem_bo_undo(&sna->kgem, tmp->dst.bo); + if (flags & COMPOSITE_UPLOAD) + return false; } else { RegionRec region; @@ -2830,7 +2834,7 @@ fill: if (src_pixmap->drawable.width <= sna->render.max_3d_size && src_pixmap->drawable.height <= sna->render.max_3d_size && bo->pitch <= sna->render.max_3d_pitch && - (flags & COMPOSITE_FALLBACK) == 0) + (flags & (COMPOSITE_UPLOAD | COMPOSITE_FALLBACK)) == 0) { return false; } @@ -2881,7 +2885,7 @@ fallback: DBG(("%s: fallback -- unaccelerated upload\n", __FUNCTION__)); goto fallback; - } else { + } else if ((flags & COMPOSITE_UPLOAD) == 0) { ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup); if (!ret) goto fallback; diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 723de80b..1baf9455 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -238,8 +238,9 @@ struct sna_render { int16_t w, int16_t h, unsigned flags, struct sna_composite_op *tmp); -#define COMPOSITE_PARTIAL 0x1 -#define COMPOSITE_FALLBACK 0x80000000 +#define COMPOSITE_PARTIAL 0x1 +#define COMPOSITE_UPLOAD 0x40000000 +#define COMPOSITE_FALLBACK 0x80000000 bool (*check_composite_spans)(struct sna *sna, uint8_t op, PicturePtr dst, PicturePtr src,