From 33b2ea0392fe944b210ef744398aa22989bfdf33 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2011 11:43:07 +0100 Subject: [PATCH] sna: Avoid using the BLT to copy between mismatching depths We either conflated bpp (which fails given a mixture of depth-24 and depth-30 pixmaps) or neglected to check at all. Signed-off-by: Chris Wilson --- src/sna/gen3_render.c | 19 +++++++++++++++---- src/sna/gen4_render.c | 20 ++++++++++++++++++-- src/sna/gen5_render.c | 14 ++++++++++++-- src/sna/gen6_render.c | 20 ++++++++++++++++++-- src/sna/sna_accel.c | 4 +--- src/sna/sna_blt.c | 8 ++++---- src/sna/sna_dri.c | 8 +++++--- src/sna/sna_render.c | 5 ++++- 8 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index 1252ba4f..37eb6c2e 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -3254,6 +3254,9 @@ gen3_render_copy_boxes(struct sna *sna, uint8_t alu, struct sna_composite_op tmp; #if NO_COPY_BOXES + if (src->drawable.depth != dst->drawable->depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -3264,7 +3267,8 @@ gen3_render_copy_boxes(struct sna *sna, uint8_t alu, DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); - if (sna_blt_copy_boxes(sna, alu, + if (src->drawable.depth == dst->drawable.depth && + sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->drawable.bitsPerPixel, @@ -3278,12 +3282,16 @@ gen3_render_copy_boxes(struct sna *sna, uint8_t alu, src->drawable.height > 2048 || dst_bo->pitch > 8192 || dst->drawable.width > 2048 || - dst->drawable.height > 2048) + dst->drawable.height > 2048) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->drawable.bitsPerPixel, box, n); + } if (!kgem_check_bo(&sna->kgem, dst_bo)) kgem_submit(&sna->kgem); @@ -3391,6 +3399,9 @@ gen3_render_copy(struct sna *sna, uint8_t alu, struct sna_copy_op *tmp) { #if NO_COPY + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -3399,7 +3410,7 @@ gen3_render_copy(struct sna *sna, uint8_t alu, /* Prefer to use the BLT */ if (sna->kgem.mode == KGEM_BLT && - src->drawable.bitsPerPixel == dst->drawable.bitsPerPixel && + src->drawable.depth == dst->drawable.depth && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -3411,7 +3422,7 @@ gen3_render_copy(struct sna *sna, uint8_t alu, src->drawable.width > 2048 || src->drawable.height > 2048 || dst->drawable.width > 2048 || dst->drawable.height > 2048 || src_bo->pitch > 8192 || dst_bo->pitch > 8192) { - if (src->drawable.bitsPerPixel != dst->drawable.bitsPerPixel) + if (src->drawable.depth != dst->drawable.depth) return FALSE; return sna_blt_copy(sna, alu, src_bo, dst_bo, diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 2a2ecab9..bb84de76 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -2150,6 +2150,9 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu, struct sna_composite_op tmp; #if NO_COPY_BOXES + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -2158,6 +2161,7 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu, #endif if (prefer_blt(sna) && + src->drawable.depth == dst->drawable.depth && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -2167,12 +2171,16 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu, if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || src->drawable.width > 8192 || src->drawable.height > 8192 || - dst->drawable.width > 8192 || dst->drawable.height > 8192) + dst->drawable.width > 8192 || dst->drawable.height > 8192) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->drawable.bitsPerPixel, box, n); + } DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); @@ -2249,6 +2257,9 @@ gen4_render_copy(struct sna *sna, uint8_t alu, struct sna_copy_op *op) { #if NO_COPY + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -2256,6 +2267,7 @@ gen4_render_copy(struct sna *sna, uint8_t alu, #endif if (prefer_blt(sna) && + src->drawable.depth == dst->drawable.depth && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -2264,10 +2276,14 @@ gen4_render_copy(struct sna *sna, uint8_t alu, if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || src->drawable.width > 8192 || src->drawable.height > 8192 || - dst->drawable.width > 8192 || dst->drawable.height > 8192) + dst->drawable.width > 8192 || dst->drawable.height > 8192) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); + } op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear; diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 77ad1bba..858a2f6b 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -2099,6 +2099,7 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu, struct sna_composite_op tmp; if (sna->kgem.mode == KGEM_BLT && + src->drawable.depth == dst->drawable.depth && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -2108,12 +2109,16 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu, if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || src->drawable.width > 8192 || src->drawable.height > 8192 || - dst->drawable.width > 8192 || dst->drawable.height > 8192) + dst->drawable.width > 8192 || dst->drawable.height > 8192) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->drawable.bitsPerPixel, box, n); + } DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); @@ -2236,6 +2241,7 @@ gen5_render_copy(struct sna *sna, uint8_t alu, DBG(("%s (alu=%d)\n", __FUNCTION__, alu)); if (sna->kgem.mode == KGEM_BLT && + src->drawable.depth == dst->drawable.depth && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -2244,10 +2250,14 @@ gen5_render_copy(struct sna *sna, uint8_t alu, if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || src->drawable.width > 8192 || src->drawable.height > 8192 || - dst->drawable.width > 8192 || dst->drawable.height > 8192) + dst->drawable.width > 8192 || dst->drawable.height > 8192) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); + } op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear; diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 4f3e41a4..b6d99736 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -2289,6 +2289,9 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu, struct sna_composite_op tmp; #if NO_COPY_BOXES + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -2301,6 +2304,7 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu, src_bo == dst_bo)); if (sna->kgem.mode == KGEM_BLT && + src->drawable.depth == dst->drawable.depth && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -2310,12 +2314,16 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu, if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || src->drawable.width > 8192 || src->drawable.height > 8192 || - dst->drawable.width > 8192 || dst->drawable.height > 8192) + dst->drawable.width > 8192 || dst->drawable.height > 8192) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->drawable.bitsPerPixel, box, n); + } tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear; tmp.dst.pixmap = dst; @@ -2436,6 +2444,9 @@ gen6_render_copy(struct sna *sna, uint8_t alu, struct sna_copy_op *op) { #if NO_COPY + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -2448,6 +2459,7 @@ gen6_render_copy(struct sna *sna, uint8_t alu, dst->drawable.width, dst->drawable.height)); if (sna->kgem.mode == KGEM_BLT && + src->drawable.depth == dst->drawable.depth && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, @@ -2456,10 +2468,14 @@ gen6_render_copy(struct sna *sna, uint8_t alu, if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || src->drawable.width > 8192 || src->drawable.height > 8192 || - dst->drawable.width > 8192 || dst->drawable.height > 8192) + dst->drawable.width > 8192 || dst->drawable.height > 8192) { + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); + } op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 0155ede0..37f8fb0a 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1359,9 +1359,7 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, DBG(("%s: src=(%d, %d)x(%d, %d) -> dst=(%d, %d)\n", __FUNCTION__, src_x, src_y, width, height, dst_x, dst_y)); - if (sna->kgem.wedged || - src->bitsPerPixel != dst->bitsPerPixel || - !PM_IS_SOLID(dst, gc->planemask)) { + if (sna->kgem.wedged || !PM_IS_SOLID(dst, gc->planemask)) { BoxRec box; RegionRec region; diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c index 35fdc12d..38b9113e 100644 --- a/src/sna/sna_blt.c +++ b/src/sna/sna_blt.c @@ -977,11 +977,11 @@ sna_blt_composite(struct sna *sna, return FALSE; } - if (src->pDrawable->bitsPerPixel != dst->pDrawable->bitsPerPixel) { - DBG(("%s: mismatching bpp src=%d, dst=%d\n", + if (src->pDrawable->depth != dst->pDrawable->depth) { + DBG(("%s: mismatching depth src=%d/%d, dst=%d/%d\n", __FUNCTION__, - src->pDrawable->bitsPerPixel, - dst->pDrawable->bitsPerPixel)); + src->pDrawable->depth, src->pDrawable->bitsPerPixel, + dst->pDrawable->depth, dst->pDrawable->bitsPerPixel)); return FALSE; } diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index d4a3e3f3..9d6369e1 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -206,7 +206,7 @@ sna_dri_create_buffer(DrawablePtr drawable, usage = 0; if (drawable->width == sna->front->drawable.width && drawable->height == sna->front->drawable.height && - drawable->bitsPerPixel == sna->front->drawable.bitsPerPixel) + drawable->depth == sna->front->drawable.depth) usage = SNA_CREATE_FB; case DRI2BufferFakeFrontLeft: @@ -777,10 +777,12 @@ can_flip(struct sna * sna, return FALSE; } - if (front_pixmap->drawable.bitsPerPixel != back_pixmap->drawable.bitsPerPixel) { - DBG(("%s -- no, depth mismatch: front bpp=%d, back=%d\n", + if (front_pixmap->drawable.depth != back_pixmap->drawable.depth) { + DBG(("%s -- no, depth mismatch: front bpp=%d/%d, back=%d/%d\n", __FUNCTION__, + front_pixmap->drawable.depth, front_pixmap->drawable.bitsPerPixel, + back_pixmap->drawable.depth, back_pixmap->drawable.bitsPerPixel)); return FALSE; } diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index b05689d1..58e9f206 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -92,6 +92,9 @@ no_render_copy_boxes(struct sna *sna, uint8_t alu, { DBG(("%s (n=%d)\n", __FUNCTION__, n)); + if (src->drawable.depth != dst->drawable.depth) + return FALSE; + return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, @@ -107,7 +110,7 @@ no_render_copy(struct sna *sna, uint8_t alu, { DBG(("%s ()\n", __FUNCTION__)); - if (src->drawable.bitsPerPixel != dst->drawable.bitsPerPixel && + if (src->drawable.depth == dst->drawable.depth && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp))