diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-05 23:18:37 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-05 23:44:13 +0000 |
commit | 34c4dbe825a45315b05f0bd49539cbcf5de276f1 (patch) | |
tree | a8169c8e7a9e5f92b8400afd902b5d35b9482223 /src/sna/gen6_render.c | |
parent | fc79af7a4abf1f0ceccacf23e8467ee2872eec09 (diff) |
sna/gen6: Only force BLT if the src and dst overlaps for self-copy
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/gen6_render.c')
-rw-r--r-- | src/sna/gen6_render.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index aeef29d6..37b10167 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -2817,6 +2817,37 @@ static inline bool prefer_blt_copy(struct sna *sna, untiled_tlb_miss(dst_bo)); } +static inline bool +overlaps(struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, + struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, + const BoxRec *box, int n) +{ + BoxRec extents; + + if (src_bo != dst_bo) + return false; + + extents = box[0]; + while (--n) { + box++; + + if (box->x1 < extents.x1) + extents.x1 = box->x1; + if (box->x2 > extents.x2) + extents.x2 = box->x2; + + if (box->y1 < extents.y1) + extents.y1 = box->y1; + if (box->y2 > extents.y2) + extents.y2 = box->y2; + } + + return (extents.x2 + src_dx > extents.x1 + dst_dx && + extents.x1 + src_dx < extents.x2 + dst_dx && + extents.y2 + src_dy > extents.y1 + dst_dy && + extents.y1 + src_dy < extents.y2 + dst_dy); +} + static Bool gen6_render_copy_boxes(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, @@ -2836,9 +2867,12 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu, box, n); #endif - DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, self-copy=%d\n", + DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, self-copy=%d, overlaps? %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n, alu, - src_bo == dst_bo)); + src_bo == dst_bo, + overlaps(src_bo, src_dx, src_dy, + dst_bo, dst_dx, dst_dy, + box, n))); if (prefer_blt_copy(sna, src_bo, dst_bo) && sna_blt_compare_depth(&src->drawable, &dst->drawable) && @@ -2849,7 +2883,10 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu, box, n)) return TRUE; - if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || + if (!(alu == GXcopy || alu == GXclear) || + overlaps(src_bo, src_dx, src_dy, + dst_bo, dst_dx, dst_dy, + box, n) || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height)) return sna_blt_copy_boxes_fallback(sna, alu, |