xf86-video-intel: 6 commits - src/sna/blt.c src/sna/gen3_render.c src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_composite.c src/sna/sna_glyphs.c src/sna/sna_io.c src/sna/sna_render_inline.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Nov 7 12:09:33 PST 2011


 src/sna/blt.c               |    9 ++--
 src/sna/gen3_render.c       |   18 +++++---
 src/sna/sna_accel.c         |   91 ++++++++++++++++++++++++++++++++++++++------
 src/sna/sna_blt.c           |   75 ++++++++++++++----------------------
 src/sna/sna_composite.c     |   90 +++++++++++++++++--------------------------
 src/sna/sna_glyphs.c        |   27 +++++++------
 src/sna/sna_io.c            |   10 ++++
 src/sna/sna_render_inline.h |    2 
 8 files changed, 189 insertions(+), 133 deletions(-)

New commits:
commit 8f7a8a80237db77452f02273bd8ade68dfba575f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 7 20:08:25 2011 +0000

    sna/composite: Minor fixes in operator and colour reduction
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 725a3cf..a6f867f 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -41,25 +41,6 @@
 #define DBG(x) ErrorF x
 #endif
 
-static void dst_move_area_to_cpu(PicturePtr picture,
-				 uint8_t op,
-				 BoxPtr box)
-{
-	RegionRec area;
-
-	DBG(("%s: (%d, %d), (%d %d)\n", __FUNCTION__,
-	     box->x1, box->y1, box->x2, box->y2));
-
-	RegionInit(&area, box, 1);
-	if (picture->pCompositeClip)
-		RegionIntersect(&area, &area, picture->pCompositeClip);
-	sna_drawable_move_region_to_cpu(picture->pDrawable, &area, true);
-	RegionUninit(&area);
-
-	/* XXX use op to avoid a readback? */
-	(void)op;
-}
-
 #define BOUND(v)	(INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
 
 static inline bool
@@ -492,7 +473,7 @@ fallback:
 	     dst->pDrawable->x, dst->pDrawable->y,
 	     width, height));
 
-	dst_move_area_to_cpu(dst, op, &region.extents);
+	sna_drawable_move_region_to_cpu(dst->pDrawable, &region, true);
 	if (dst->alphaMap)
 		sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, true);
 	if (src->pDrawable) {
@@ -506,7 +487,7 @@ fallback:
 			sna_drawable_move_to_cpu(mask->alphaMap->pDrawable, false);
 	}
 
-	DBG(("%s: fallback -- fbCompposite\n", __FUNCTION__));
+	DBG(("%s: fallback -- fbComposite\n", __FUNCTION__));
 	fbComposite(op, src, mask, dst,
 		    src_x, src_y,
 		    mask_x, mask_y,
@@ -540,13 +521,15 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t *region,
 	}
 
 	for (i = j = 0; i < num_rects; i++) {
-		boxes[j].x1 = rects[i].x + tx;
+		boxes[j].x1 = rects[i].x;
 		if (boxes[j].x1 < 0)
 			boxes[j].x1 = 0;
+		boxes[j].x1 += tx;
 
-		boxes[j].y1 = rects[i].y + ty;
+		boxes[j].y1 = rects[i].y;
 		if (boxes[j].y1 < 0)
 			boxes[j].y1 = 0;
+		boxes[j].y1 += ty;
 
 		boxes[j].x2 = bound(rects[i].x, rects[i].width);
 		if (boxes[j].x2 > maxx)
@@ -642,6 +625,7 @@ sna_composite_rectangles(CARD8		 op,
 			break;
 		}
 	}
+	DBG(("%s: converted to op %d\n", __FUNCTION__, op));
 
 	if (!pixman_region_not_empty(dst->pCompositeClip)) {
 		DBG(("%s: empty clip, skipping\n", __FUNCTION__));
@@ -696,13 +680,6 @@ sna_composite_rectangles(CARD8		 op,
 
 	boxes = pixman_region_rectangles(&region, &num_boxes);
 
-	if (op == PictOpClear) {
-		color->red = color->green = color->blue = color->alpha = 0;
-	} else if (color->alpha >= 0xff00 && op == PictOpOver) {
-		color->alpha = 0xffff;
-		op = PictOpSrc;
-	}
-
 	if (too_small(dst->pDrawable)) {
 		DBG(("%s: fallback, dst is too small\n", __FUNCTION__));
 		goto fallback;
@@ -750,33 +727,38 @@ fallback:
 		BoxPtr box = REGION_RECTS(&region);
 		uint32_t pixel;
 
-		if (sna_get_pixel_from_rgba(&pixel,
-					     color->red,
-					     color->green,
-					     color->blue,
-					     color->alpha,
-					     dst->format)) {
-			do {
-				DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n",
-				     __FUNCTION__,
-				     box->x1, box->y1,
-				     box->x2 - box->x1,
-				     box->y2 - box->y1,
-				     pixel));
-
-				pixman_fill(pixmap->devPrivate.ptr,
-					    pixmap->devKind/sizeof(uint32_t),
-					    pixmap->drawable.bitsPerPixel,
-					    box->x1, box->y1,
-					    box->x2 - box->x1,
-					    box->y2 - box->y1,
-					    pixel);
-				box++;
-			} while (--nbox);
-		}
+		if (op == PictOpClear)
+			pixel = 0;
+		else if (!sna_get_pixel_from_rgba(&pixel,
+						  color->red,
+						  color->green,
+						  color->blue,
+						  color->alpha,
+						  dst->format))
+			goto fallback_composite;
+
+		do {
+			DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n",
+			     __FUNCTION__,
+			     box->x1, box->y1,
+			     box->x2 - box->x1,
+			     box->y2 - box->y1,
+			     pixel));
+
+			pixman_fill(pixmap->devPrivate.ptr,
+				    pixmap->devKind/sizeof(uint32_t),
+				    pixmap->drawable.bitsPerPixel,
+				    box->x1, box->y1,
+				    box->x2 - box->x1,
+				    box->y2 - box->y1,
+				    pixel);
+			box++;
+		} while (--nbox);
 	} else {
 		PicturePtr src;
 
+fallback_composite:
+		DBG(("%s: fallback -- fbComposite()\n", __FUNCTION__));
 		src = CreateSolidPicture(0, color, &error);
 		if (src) {
 			do {
commit b1234f3d3a27f326b8048e3d6b476021a26e9101
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 7 20:07:37 2011 +0000

    sna: Expand multiplies of two 16-bit values to a full 32-bit range
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index a9dbed7..acec111 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -723,7 +723,7 @@ glyphs_via_mask(struct sna *sna,
 	}
 
 	component_alpha = NeedsComponent(format->format);
-	if (width * height * format->depth < 8 * 256) {
+	if ((uint32_t)width * height * format->depth < 8 * 256) {
 		pixman_image_t *mask_image;
 		int s;
 
@@ -1137,27 +1137,30 @@ glyphs_fallback(CARD8 op,
 						       g->info.width,
 						       g->info.height);
 			} else {
-				DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d)\n",
+				int xi = x - g->info.x;
+				int yi = y - g->info.y;
+
+				DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d), src (%d, %d) [op=%d]\n",
 				     __FUNCTION__,
 				     dx, dy,
-				     x - g->info.x,
-				     y - g->info.y,
-				     g->info.width,
-				     g->info.height));
+				     xi, yi,
+				     g->info.width, g->info.height,
+				     src_x + xi,
+				     src_y + yi,
+				     op));
 
 				pixman_image_composite(op,
 						       src_image,
 						       glyph_image,
 						       dst_image,
-						       src_x + (x - g->info.x),
-						       src_y + (y - g->info.y),
+						       src_x + xi,
+						       src_y + yi,
 						       dx, dy,
-						       x - g->info.x,
-						       y - g->info.y,
+						       xi, yi,
 						       g->info.width,
 						       g->info.height);
 			}
-			free_pixman_pict(picture,glyph_image);
+			free_pixman_pict(picture, glyph_image);
 
 next_glyph:
 			x += g->info.xOff;
@@ -1207,7 +1210,7 @@ sna_glyphs(CARD8 op,
 	if (REGION_NUM_RECTS(dst->pCompositeClip) == 0)
 		return;
 
-	if (FALLBACK)
+	if (FALLBACK || DEBUG_NO_RENDER)
 		goto fallback;
 
 	if (sna->kgem.wedged || !sna->have_render) {
diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 8ad755c..91aa7e4 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -90,7 +90,7 @@ is_dirty_gpu(DrawablePtr drawable)
 static inline Bool
 too_small(DrawablePtr drawable)
 {
-	return (drawable->width * drawable->height * drawable->bitsPerPixel <= 8*4096) &&
+	return ((uint32_t)drawable->width * drawable->height * drawable->bitsPerPixel <= 8*4096) &&
 		!is_dirty_gpu(drawable);
 }
 
commit afdf931e61821985b31b339d1f346ddd7c4e9e3c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 7 20:06:35 2011 +0000

    sna: Add some more debugging in the hunt for overflows
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e33d45a..9fddd4f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1087,11 +1087,15 @@ static void sna_gc_move_to_cpu(GCPtr gc, DrawablePtr drawable)
 	}
 	sgc->changes = 0;
 
-	if (gc->stipple)
-		sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
-
-	if (gc->fillStyle == FillTiled)
+	switch (gc->fillStyle) {
+	case FillTiled:
 		sna_drawable_move_to_cpu(&gc->tile.pixmap->drawable, false);
+		break;
+	case FillStippled:
+	case FillOpaqueStippled:
+		sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
+		break;
+	}
 }
 
 static inline bool clip_box(BoxPtr box, GCPtr gc)
@@ -2142,6 +2146,10 @@ fallback:
 				     __FUNCTION__,
 				     box->x1, box->y1,
 				     box->x2, box->y2));
+				assert(box->x1 + src_dx >= 0);
+				assert(box->y1 + src_dy >= 0);
+				assert(box->x1 + dst_dx >= 0);
+				assert(box->y1 + dst_dy >= 0);
 				fbBlt(src_bits + (box->y1 + src_dy) * src_stride,
 				      src_stride,
 				      (box->x1 + src_dx) * bpp,
@@ -4717,7 +4725,7 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
 	if (gc->capStyle != CapProjecting)
 		extra >>= 1;
 
-	if (seg->x2 > seg->x1) {
+	if (seg->x2 >= seg->x1) {
 		box.x1 = seg->x1;
 		box.x2 = seg->x2;
 	} else {
@@ -4725,7 +4733,7 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
 		box.x1 = seg->x2;
 	}
 
-	if (seg->y2 > seg->y1) {
+	if (seg->y2 >= seg->y1) {
 		box.y1 = seg->y1;
 		box.y2 = seg->y2;
 	} else {
@@ -4766,9 +4774,13 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
 		box.y2 += extra;
 	}
 
+	DBG(("%s: unclipped, untranslated extents (%d, %d), (%d, %d)\n",
+	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+
 	clipped = trim_and_translate_box(&box, drawable, gc);
 	if (box_empty(&box))
 		return 0;
+
 	*out = box;
 	return 1 | clipped << 1 | can_blit << 2;
 }
@@ -5575,9 +5587,10 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 	BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes);
 	int16_t dx, dy;
 
-	DBG(("%s x %d [(%d, %d)+(%d, %d)...], clipped?=%d\n",
-	     __FUNCTION__,
-	     n, rect->x, rect->y, rect->width, rect->height,
+	DBG(("%s x %d [(%d, %d)x(%d, %d)...]+(%d,%d), clipped?=%d\n",
+	     __FUNCTION__, n,
+	     rect->x, rect->y, rect->width, rect->height,
+	     drawable->x, drawable->y,
 	     clipped));
 
 	if (n == 1 && gc->pCompositeClip->data == NULL) {
@@ -6764,10 +6777,66 @@ fallback:
 
 	sna_gc_move_to_cpu(gc, draw);
 	sna_drawable_move_region_to_cpu(draw, &region, true);
-	RegionUninit(&region);
 
 	DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__));
-	fbPolyFillRect(draw, gc, n, rect);
+	if (region.data == NULL) {
+		do {
+			BoxRec box;
+
+			box.x1 = rect->x + draw->x;
+			box.y1 = rect->y + draw->y;
+			box.x2 = bound(box.x1, rect->width);
+			box.y2 = bound(box.y1, rect->height);
+			rect++;
+
+			if (box_intersect(&box, &region.extents)) {
+				DBG(("%s: fallback - fbFill((%d, %d), (%d, %d))\n",
+				     __FUNCTION__,
+				     box.x1, box.y1,
+				     box.x2-box.x1, box.y2-box.y1));
+				fbFill(draw, gc,
+				       box.x1, box.y1,
+				       box.x2-box.x1, box.y2-box.y1);
+			}
+		} while (--n);
+	} else {
+		const BoxRec * const clip_start = RegionBoxptr(&region);
+		const BoxRec * const clip_end = clip_start + region.data->numRects;
+		const BoxRec *c;
+
+		do {
+			BoxRec box;
+
+			box.x1 = rect->x + draw->x;
+			box.y1 = rect->y + draw->y;
+			box.x2 = bound(box.x1, rect->width);
+			box.y2 = bound(box.y1, rect->height);
+			rect++;
+
+			c = find_clip_box_for_y(clip_start,
+						clip_end,
+						box.y1);
+
+			while (c != clip_end) {
+				BoxRec b;
+
+				if (box.y2 <= c->y1)
+					break;
+
+				b = box;
+				if (box_intersect(&b, c++)) {
+					DBG(("%s: fallback - fbFill((%d, %d), (%d, %d))\n",
+					     __FUNCTION__,
+					       b.x1, b.y1,
+					       b.x2-b.x1, b.y2-b.y1));
+					fbFill(draw, gc,
+					       b.x1, b.y1,
+					       b.x2-b.x1, b.y2-b.y1);
+				}
+			}
+		} while (--n);
+	}
+	RegionUninit(&region);
 }
 
 struct sna_font {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index a36adc9..963efb3 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -61,6 +61,16 @@ static void read_boxes_inplace(struct kgem *kgem,
 		return;
 
 	do {
+		assert(box->x1 + src_dx >= 0);
+		assert(box->y1 + src_dy >= 0);
+		assert(box->x2 + src_dx <= pixmap->drawable.width);
+		assert(box->y2 + src_dy <= pixmap->drawable.height);
+
+		assert(box->x1 + dst_dx >= 0);
+		assert(box->y1 + dst_dy >= 0);
+		assert(box->x2 + dst_dx <= pixmap->drawable.width);
+		assert(box->y2 + dst_dy <= pixmap->drawable.height);
+
 		memcpy_blt(src, dst, bpp,
 			   src_pitch, dst_pitch,
 			   box->x1 + src_dx, box->y1 + src_dy,
commit 8f3c845782fdb2fa8bdf751bdd7dd83ca02c42ac
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 7 20:05:41 2011 +0000

    sna/blt: Small cleanups
    
    Whilst perusing for overflows, remove some redundant conditionals.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 6965cbd..2e61bb9 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -137,8 +137,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 		blt->cmd |= 1 << 11;
 		pitch >>= 2;
 	}
-	if (pitch > MAXSHORT)
-		return FALSE;
+	assert(pitch < MAXSHORT);
 
 	if (alu == GXclear)
 		pixel = 0;
@@ -280,16 +279,14 @@ static Bool sna_blt_copy_init(struct sna *sna,
 		blt->cmd |= BLT_SRC_TILED;
 		blt->pitch[0] >>= 2;
 	}
-	if (blt->pitch[0] > MAXSHORT)
-		return FALSE;
+	assert(blt->pitch[0] < MAXSHORT);
 
 	blt->pitch[1] = dst->pitch;
 	if (kgem->gen >= 40 && dst->tiling) {
 		blt->cmd |= BLT_DST_TILED;
 		blt->pitch[1] >>= 2;
 	}
-	if (blt->pitch[1] > MAXSHORT)
-		return FALSE;
+	assert(blt->pitch[1] < MAXSHORT);
 
 	blt->overwrites = alu == GXcopy || alu == GXclear || alu == GXset;
 	blt->br13 = (copy_ROP[alu] << 16) | blt->pitch[1];
@@ -1078,9 +1075,10 @@ static void blt_put_composite_boxes(struct sna *sna,
 	PixmapPtr src = op->u.blt.src_pixmap;
 	struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap);
 
-	DBG(("%s: src=(%d, %d), dst=(%d, %d) x %d\n", __FUNCTION__,
+	DBG(("%s: src=(%d, %d), dst=(%d, %d), [(%d, %d), (%d, %d) x %d]\n", __FUNCTION__,
 	     op->u.blt.sx, op->u.blt.sy,
-	     op->dst.x, op->dst.y, n));
+	     op->dst.x, op->dst.y,
+	     box->x1, box->y1, box->x2, box->y2, n));
 
 	if (n == 1 && !dst_priv->pinned &&
 	    box->x2 - box->x1 == op->dst.width &&
@@ -1176,6 +1174,7 @@ has_gpu_area(PixmapPtr pixmap, int x, int y, int w, int h)
 	area.y1 = y;
 	area.x2 = x + w;
 	area.y2 = y + h;
+
 	return sna_damage_contains_box(priv->cpu_damage,
 				       &area) == PIXMAN_REGION_OUT;
 }
@@ -1220,7 +1219,10 @@ reduce_damage(struct sna_composite_op *op,
 	r.y1 = dst_y + op->dst.y;
 	r.y2 = r.y1 + height;
 
-	if (sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
+	if (sna_damage_is_all(op->damage,
+			      op->dst.pixmap->drawable.width,
+			      op->dst.pixmap->drawable.width) ||
+	    sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
 		op->damage = NULL;
 }
 
@@ -1310,11 +1312,9 @@ sna_blt_composite(struct sna *sna,
 		return FALSE;
 	}
 
-	if (!sna_blt_compare_depth(src->pDrawable, dst->pDrawable)) {
-		DBG(("%s: mismatching depth src=%d/%d, dst=%d/%d\n",
-		     __FUNCTION__,
-		     src->pDrawable->depth, src->pDrawable->bitsPerPixel,
-		     dst->pDrawable->depth, dst->pDrawable->bitsPerPixel));
+	if (src->filter == PictFilterConvolution) {
+		DBG(("%s: convolutions filters not handled\n",
+		     __FUNCTION__));
 		return FALSE;
 	}
 
@@ -1327,12 +1327,6 @@ sna_blt_composite(struct sna *sna,
 		return FALSE;
 	}
 
-	if (src->filter == PictFilterConvolution) {
-		DBG(("%s: convolutions filters not handled\n",
-		     __FUNCTION__));
-		return FALSE;
-	}
-
 	if (!(dst->format == src_format ||
 	      dst->format == PICT_FORMAT(PICT_FORMAT_BPP(src_format),
 					 PICT_FORMAT_TYPE(src_format),
@@ -1505,8 +1499,7 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 			     const BoxRec *box)
 {
 	struct kgem *kgem = &sna->kgem;
-	uint32_t br13, cmd;
-	uint32_t *b;
+	uint32_t br13, cmd, *b;
 
 	DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__,
 	     box->x1, box->y1, box->x2, box->y2));
@@ -1515,27 +1508,27 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	assert(box->y1 >= 0);
 
 	cmd = XY_COLOR_BLT;
-	if (bpp == 32)
-		cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
-
 	br13 = bo->pitch;
 	if (kgem->gen >= 40 && bo->tiling) {
 		cmd |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
-	if (br13 > MAXSHORT) {
-		DBG(("%s: fallback -- pitch is too large %d [%d]\n",
-		     __FUNCTION__, bo->pitch, br13));
-		return FALSE;
-	}
+	assert(br13 < MAXSHORT);
 
-	if (color == 0)
-		alu = GXclear;
+	if (alu == GXclear)
+		color = 0;
+	else if (alu == GXcopy) {
+		if (color == 0)
+			alu = GXclear;
+		else if (color == -1)
+			alu = GXset;
+	}
 
 	br13 |= fill_ROP[alu] << 16;
 	switch (bpp) {
 	default: assert(0);
-	case 32: br13 |= 1 << 25; /* RGB8888 */
+	case 32: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+		 br13 |= 1 << 25; /* RGB8888 */
 	case 16: br13 |= 1 << 24; /* RGB565 */
 	case 8: break;
 	}
@@ -1544,8 +1537,7 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	if (kgem->nbatch >= 6 &&
 	    (alu == GXcopy || alu == GXclear || alu == GXset) &&
 	    kgem->batch[kgem->nbatch-6] == cmd &&
-	    kgem->batch[kgem->nbatch-4] == ((uint32_t)box[0].y1 << 16 | (uint16_t)box[0].x1) &&
-	    kgem->batch[kgem->nbatch-3] == ((uint32_t)box[0].y2 << 16 | (uint16_t)box[0].x2) &&
+	    *(uint64_t *)&kgem->batch[kgem->nbatch-4] == *(uint64_t *)box &&
 	    kgem->reloc[kgem->nreloc-1].target_handle == bo->handle) {
 		DBG(("%s: replacing last fill\n", __FUNCTION__));
 		kgem->batch[kgem->nbatch-5] = br13;
@@ -1562,12 +1554,10 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	}
 
 	b = kgem->batch + kgem->nbatch;
-
 	b[0] = cmd;
 	b[1] = br13;
 	*(uint64_t *)(b+2) = *(uint64_t *)box;
-	b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4,
-			      bo,
+	b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
 			      I915_GEM_DOMAIN_RENDER << 16 |
 			      I915_GEM_DOMAIN_RENDER |
 			      KGEM_RELOC_FENCED,
@@ -1608,8 +1598,7 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 		cmd |= 1 << 11;
 		br13 >>= 2;
 	}
-	if (br13 > MAXSHORT)
-		return FALSE;
+	assert(br13 < MAXSHORT);
 
 	if (alu == GXclear)
 		pixel = 0;
@@ -1756,16 +1745,14 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		cmd |= BLT_SRC_TILED;
 		src_pitch >>= 2;
 	}
-	if (src_pitch > MAXSHORT)
-		return FALSE;
+	assert(src_pitch < MAXSHORT);
 
 	br13 = dst_bo->pitch;
 	if (kgem->gen >= 40 && dst_bo->tiling) {
 		cmd |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
-	if (br13 > MAXSHORT)
-		return FALSE;
+	assert(br13 < MAXSHORT);
 
 	br13 |= copy_ROP[alu] << 16;
 	switch (bpp) {
commit 8e775cecccebe543d344721d45b2d43ee9f122b3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 7 20:01:33 2011 +0000

    sna/gen3: Fix false reduction of ComponentAlpha with white source
    
    The principle behind the opertator reduction of WHITE * maskca is valid,
    except that we failed to account for the src/mask transposition when
    emitting the vertices - garbage ensued.
    
    Given that we agressively reduce the shader required for WHITE * maskca,
    it does not seem worthwhile to special case the primitive emitter as
    well.
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42676
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 5439672..c8ad209 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1078,7 +1078,6 @@ gen3_composite_emit_shader(struct sna *sna,
 			 */
 			if (op->has_component_alpha) {
 				switch (src->u.gen3.type) {
-				case SHADER_WHITE:
 				case SHADER_BLACK:
 					if (gen3_blend_op[blend].src_alpha)
 						gen3_fs_mov(out_reg,
@@ -1087,6 +1086,10 @@ gen3_composite_emit_shader(struct sna *sna,
 						gen3_fs_mov(out_reg,
 							    gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
 					break;
+				case SHADER_WHITE:
+					gen3_fs_mov(out_reg,
+						    gen3_fs_operand_reg(mask_reg));
+					break;
 				default:
 					if (gen3_blend_op[blend].src_alpha)
 						gen3_fs_mul(out_reg,
@@ -1853,6 +1856,9 @@ gen3_init_solid(struct sna_composite_channel *channel, uint32_t color)
 	channel->alpha_fixup = 0;
 	channel->rb_reversed = 0;
 
+	DBG(("%s: color=%08x, is_opaque=%d, type=%d\n",
+	     __FUNCTION__, color, channel->is_opaque, channel->u.gen3.type));
+
 	/* for consistency */
 	channel->repeat = RepeatNormal;
 	channel->filter = PictFilterNearest;
@@ -2182,7 +2188,10 @@ reduce_damage(struct sna_composite_op *op,
 	r.y1 = dst_y + op->dst.y;
 	r.y2 = r.y1 + height;
 
-	if (sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
+	if (sna_damage_is_all(op->damage,
+			      op->dst.pixmap->drawable.width,
+			      op->dst.pixmap->drawable.width) ||
+	    sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
 		op->damage = NULL;
 }
 
@@ -2378,11 +2387,6 @@ gen3_render_composite(struct sna *sna,
 			if (tmp->mask.u.gen3.type == SHADER_WHITE) {
 				tmp->mask.u.gen3.type = SHADER_NONE;
 				tmp->has_component_alpha = FALSE;
-			} else if (tmp->src.u.gen3.type == SHADER_WHITE) {
-				tmp->src = tmp->mask;
-				tmp->mask.u.gen3.type = SHADER_NONE;
-				tmp->mask.bo = NULL;
-				tmp->has_component_alpha = FALSE;
 			} else if (is_constant_ps(tmp->src.u.gen3.type) &&
 				   is_constant_ps(tmp->mask.u.gen3.type)) {
 				uint32_t a,r,g,b;
commit 65a440543b13e3e605a4a2d6209a460fbbe55736
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 7 20:00:20 2011 +0000

    sna: Fix 16-bit overflow of rowlength for memcpy
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42619
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/blt.c b/src/sna/blt.c
index 5dc318c..ca15453 100644
--- a/src/sna/blt.c
+++ b/src/sna/blt.c
@@ -45,6 +45,7 @@ memcpy_blt(const void *src, void *dst, int bpp,
 {
 	uint8_t *src_bytes;
 	uint8_t *dst_bytes;
+	int byte_width;
 
 	assert(width && height);
 	assert(bpp >= 8);
@@ -53,18 +54,18 @@ memcpy_blt(const void *src, void *dst, int bpp,
 	     __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride));
 
 	bpp /= 8;
-	width *= bpp;
 
 	src_bytes = (uint8_t *)src + src_stride * src_y + src_x * bpp;
 	dst_bytes = (uint8_t *)dst + dst_stride * dst_y + dst_x * bpp;
 
-	if (width == src_stride && width == dst_stride) {
-		memcpy(dst_bytes, src_bytes, width * height);
+	byte_width = width * bpp;
+	if (byte_width == src_stride && byte_width == dst_stride) {
+		memcpy(dst_bytes, src_bytes, byte_width * height);
 		return;
 	}
 
 	do {
-		memcpy(dst_bytes, src_bytes, width);
+		memcpy(dst_bytes, src_bytes, byte_width);
 		src_bytes += src_stride;
 		dst_bytes += dst_stride;
 	} while (--height);


More information about the xorg-commit mailing list