xf86-video-intel: 2 commits - src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/sna.h src/sna/sna_render.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Jan 16 08:18:03 PST 2012


 src/sna/gen4_render.c |   89 +++++++++++++++++++-------------------------
 src/sna/gen5_render.c |  101 ++++++++++++++++++++++++--------------------------
 src/sna/gen6_render.c |   83 +++++++++++++++++++----------------------
 src/sna/gen7_render.c |   81 ++++++++++++++++++----------------------
 src/sna/sna.h         |    1 
 src/sna/sna_render.c  |   16 +++++++
 6 files changed, 182 insertions(+), 189 deletions(-)

New commits:
commit 377f5e16cd14bdf42e67b0c8f2e13b75526f3a85
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 16 15:51:33 2012 +0000

    sna/gen[45]: clear the state tracker before setting the formats
    
    When backporting the patches from gen6, I didn't notice the memset that
    came later, and this wasn't along the paths checked by rendercheck.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 7d1005d..6351fa9 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1459,7 +1459,7 @@ gen4_emit_vertex_elements(struct sna *sna,
 static void
 gen4_emit_state(struct sna *sna,
 		const struct sna_composite_op *op,
-	       	uint16_t wm_binding_table)
+		uint16_t wm_binding_table)
 {
 	gen4_emit_binding_table(sna, wm_binding_table);
 	gen4_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel);
@@ -2422,6 +2422,8 @@ fallback:
 						   box, n);
 	}
 
+	memset(&tmp, 0, sizeof(tmp));
+
 	DBG(("%s (%d, %d)->(%d, %d) x %d\n",
 	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
 
@@ -2435,8 +2437,6 @@ fallback:
 	if (!gen4_check_format(tmp.src.pict_format))
 		goto fallback;
 
-	memset(&tmp, 0, sizeof(tmp));
-
 	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
 	tmp.dst.pixmap = dst;
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index a06194e..5104cb7 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2689,7 +2689,7 @@ gen5_copy_bind_surfaces(struct sna *sna,
 	binding_table[0] =
 		gen5_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen5_get_dest_format(op->dst.pixmap->drawable.depth),
+			     gen5_get_dest_format(op->dst.format),
 			     TRUE);
 	binding_table[1] =
 		gen5_bind_bo(sna,
@@ -2745,6 +2745,8 @@ fallback:
 						   box, n);
 	}
 
+	memset(&tmp, 0, sizeof(tmp));
+
 	if (dst->drawable.depth == src->drawable.depth) {
 		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
 		tmp.src.pict_format = tmp.dst.format;
@@ -2752,14 +2754,15 @@ fallback:
 		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
 	}
-	if (!gen5_check_format(tmp.src.pict_format))
+	if (!gen5_check_format(tmp.src.pict_format)) {
+		DBG(("%s: unsupported source format, %x, use BLT\n",
+		     __FUNCTION__, tmp.src.pict_format));
 		goto fallback;
+	}
 
 	DBG(("%s (%d, %d)->(%d, %d) x %d\n",
 	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
 
-	memset(&tmp, 0, sizeof(tmp));
-
 	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
 	tmp.dst.pixmap = dst;
@@ -2917,7 +2920,6 @@ fallback:
 	op->base.dst.pixmap = dst;
 	op->base.dst.width  = dst->drawable.width;
 	op->base.dst.height = dst->drawable.height;
-	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
 	op->base.dst.bo = dst_bo;
 
 	op->base.src.bo = src_bo;
@@ -3057,11 +3059,11 @@ gen5_render_fill_boxes(struct sna *sna,
 	if (op == PictOpClear)
 		pixel = 0;
 	else if (!sna_get_pixel_from_rgba(&pixel,
-				     color->red,
-				     color->green,
-				     color->blue,
-				     color->alpha,
-				     PICT_a8r8g8b8))
+					  color->red,
+					  color->green,
+					  color->blue,
+					  color->alpha,
+					  PICT_a8r8g8b8))
 		return FALSE;
 
 	memset(&tmp, 0, sizeof(tmp));
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index b8e5565..75caa6f 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2985,7 +2985,7 @@ gen7_emit_copy_state(struct sna *sna,
 	binding_table[0] =
 		gen7_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen7_get_dest_format(op->dst.pixmap->drawable.depth),
+			     gen7_get_dest_format(op->dst.format),
 			     TRUE);
 	binding_table[1] =
 		gen7_bind_bo(sna,
commit 6387f2fb8a40f32cc4a3e4228983dcf0604ac4dc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 16 14:12:36 2012 +0000

    sna/gen[4567]: x1r5g5b5 is only a render target, not sampler
    
    Whilst we can render to and blend with an depth 15 target, we cannot use
    it as a texture with the sampling engine.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index d44ddd5..7d1005d 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -267,7 +267,6 @@ static const struct formatinfo {
 	{PICT_r8g8b8, GEN4_SURFACEFORMAT_R8G8B8_UNORM},
 	{PICT_r5g6b5, GEN4_SURFACEFORMAT_B5G6R5_UNORM},
 	{PICT_a1r5g5b5, GEN4_SURFACEFORMAT_B5G5R5A1_UNORM},
-	{PICT_x1r5g5b5, GEN4_SURFACEFORMAT_B5G5R5X1_UNORM},
 	{PICT_a2r10g10b10, GEN4_SURFACEFORMAT_B10G10R10A2_UNORM},
 	{PICT_x2r10g10b10, GEN4_SURFACEFORMAT_B10G10R10X2_UNORM},
 	{PICT_a2b10g10r10, GEN4_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -562,9 +561,9 @@ static Bool gen4_check_dst_format(PictFormat format)
 	}
 }
 
-static bool gen4_check_format(PicturePtr p)
+static bool gen4_check_format(uint32_t format)
 {
-	switch (p->format) {
+	switch (format) {
 	case PICT_a8r8g8b8:
 	case PICT_x8r8g8b8:
 	case PICT_a8b8g8r8:
@@ -573,14 +572,13 @@ static bool gen4_check_format(PicturePtr p)
 	case PICT_x2r10g10b10:
 	case PICT_r8g8b8:
 	case PICT_r5g6b5:
-	case PICT_x1r5g5b5:
 	case PICT_a1r5g5b5:
 	case PICT_a8:
 	case PICT_a4r4g4b4:
 	case PICT_x4r4g4b4:
 		return true;
 	default:
-		DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
 		return false;
 	}
 }
@@ -652,7 +650,6 @@ static uint32_t gen4_get_card_format(PictFormat format)
 		if (gen4_tex_formats[i].pict_fmt == format)
 			return gen4_tex_formats[i].card_fmt;
 	}
-	assert(0);
 	return -1;
 }
 
@@ -1845,12 +1842,6 @@ gen4_composite_picture(struct sna *sna,
 						x, y, w, h, dst_x, dst_y);
 	}
 
-	if (!gen4_check_format(picture)) {
-		DBG(("%s: unknown format fixup\n", __FUNCTION__));
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-	}
-
 	if (!gen4_check_repeat(picture)) {
 		DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__));
 		return sna_render_picture_fixup(sna, picture, channel,
@@ -1884,6 +1875,9 @@ gen4_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen4_get_card_format(picture->format);
+	if (channel->card_format == -1)
+		return sna_render_picture_convert(sna, picture, channel, pixmap,
+						  x, y, w, h, dst_x, dst_y);
 
 	if (pixmap->drawable.width > 8192 || pixmap->drawable.height > 8192)
 		return sna_render_picture_extract(sna, picture, channel,
@@ -2020,7 +2014,7 @@ has_alphamap(PicturePtr p)
 static bool
 source_fallback(PicturePtr p)
 {
-	return has_alphamap(p) || is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p) || !gen4_check_format(p);
+	return has_alphamap(p) || is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p) || !gen4_check_format(p->format);
 }
 
 static bool
@@ -2143,7 +2137,7 @@ reuse_source(struct sna *sna,
 	if (!gen4_check_filter(mask))
 		return FALSE;
 
-	if (!gen4_check_format(mask))
+	if (!gen4_check_format(mask->format))
 		return FALSE;
 
 	DBG(("%s: reusing source channel for mask with a twist\n",
@@ -2330,32 +2324,6 @@ cleanup_dst:
 	return FALSE;
 }
 
-static uint32_t gen4_get_dest_format_for_depth(int depth)
-{
-	switch (depth) {
-	case 32:
-	case 24:
-	default: return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM;
-	case 16: return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM;
-	case 8:  return GEN4_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
-static uint32_t gen4_get_card_format_for_depth(int depth)
-{
-	switch (depth) {
-	case 32:
-	default: return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN4_SURFACEFORMAT_B10G10R10X2_UNORM;
-	case 24: return GEN4_SURFACEFORMAT_B8G8R8X8_UNORM;
-	case 16: return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN4_SURFACEFORMAT_B5G5R5X1_UNORM;
-	case 8:  return GEN4_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
 static void
 gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
 {
@@ -2369,7 +2337,7 @@ gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
 	binding_table[0] =
 		gen4_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen4_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+			     gen4_get_dest_format(op->dst.format),
 			     TRUE);
 	binding_table[1] =
 		gen4_bind_bo(sna,
@@ -2443,15 +2411,30 @@ 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) {
+fallback:
+		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+			return FALSE;
+
 		return sna_blt_copy_boxes_fallback(sna, alu,
 						   src, src_bo, src_dx, src_dy,
 						   dst, dst_bo, dst_dx, dst_dy,
 						   box, n);
+	}
 
 	DBG(("%s (%d, %d)->(%d, %d) x %d\n",
 	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
 
+	if (dst->drawable.depth == src->drawable.depth) {
+		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = tmp.dst.format;
+	} else {
+		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen4_check_format(tmp.src.pict_format))
+		goto fallback;
+
 	memset(&tmp, 0, sizeof(tmp));
 
 	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
@@ -2459,7 +2442,6 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.pixmap = dst;
 	tmp.dst.width  = dst->drawable.width;
 	tmp.dst.height = dst->drawable.height;
-	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = dst_dx;
 	tmp.dst.y = dst_dy;
@@ -2468,7 +2450,7 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
 	tmp.src.repeat = SAMPLER_EXTEND_NONE;
 	tmp.src.card_format =
-		gen4_get_card_format_for_depth(src->drawable.depth),
+		gen4_get_card_format(tmp.src.pict_format),
 	tmp.src.width  = src->drawable.width;
 	tmp.src.height = src->drawable.height;
 
@@ -2541,6 +2523,7 @@ 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) {
+fallback:
 		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
 			return FALSE;
 
@@ -2548,18 +2531,26 @@ gen4_render_copy(struct sna *sna, uint8_t alu,
 				    dst->drawable.bitsPerPixel,
 				    op);
 	}
+	if (dst->drawable.depth == src->drawable.depth) {
+		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = op->base.dst.format;
+	} else {
+		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen4_check_format(op->base.src.pict_format))
+		goto fallback;
 
 	op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
 	op->base.dst.pixmap = dst;
 	op->base.dst.width  = dst->drawable.width;
 	op->base.dst.height = dst->drawable.height;
-	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
 	op->base.dst.bo = dst_bo;
 
 	op->base.src.bo = src_bo;
 	op->base.src.card_format =
-		gen4_get_card_format_for_depth(src->drawable.depth),
+		gen4_get_card_format(op->base.src.pict_format);
 	op->base.src.width  = src->drawable.width;
 	op->base.src.height = src->drawable.height;
 	op->base.src.scale[0] = 1.f/src->drawable.width;
@@ -2599,7 +2590,7 @@ gen4_fill_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
 	binding_table[0] =
 		gen4_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen4_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+			     gen4_get_dest_format(op->dst.format),
 			     TRUE);
 	binding_table[1] =
 		gen4_bind_bo(sna,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index f8d8d10..a06194e 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -257,7 +257,6 @@ static const struct formatinfo {
 	{PICT_r8g8b8, GEN5_SURFACEFORMAT_R8G8B8_UNORM},
 	{PICT_r5g6b5, GEN5_SURFACEFORMAT_B5G6R5_UNORM},
 	{PICT_a1r5g5b5, GEN5_SURFACEFORMAT_B5G5R5A1_UNORM},
-	{PICT_x1r5g5b5, GEN5_SURFACEFORMAT_B5G5R5X1_UNORM},
 	{PICT_a2r10g10b10, GEN5_SURFACEFORMAT_B10G10R10A2_UNORM},
 	{PICT_x2r10g10b10, GEN5_SURFACEFORMAT_B10G10R10X2_UNORM},
 	{PICT_a2b10g10r10, GEN5_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -563,9 +562,9 @@ static Bool gen5_check_dst_format(PictFormat format)
 	}
 }
 
-static bool gen5_check_format(PicturePtr p)
+static bool gen5_check_format(uint32_t format)
 {
-	switch (p->format) {
+	switch (format) {
 	case PICT_a8r8g8b8:
 	case PICT_x8r8g8b8:
 	case PICT_a8b8g8r8:
@@ -574,44 +573,17 @@ static bool gen5_check_format(PicturePtr p)
 	case PICT_x2r10g10b10:
 	case PICT_r8g8b8:
 	case PICT_r5g6b5:
-	case PICT_x1r5g5b5:
 	case PICT_a1r5g5b5:
 	case PICT_a8:
 	case PICT_a4r4g4b4:
 	case PICT_x4r4g4b4:
 		return true;
 	default:
-		DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
 		return false;
 	}
 }
 
-static uint32_t gen5_get_dest_format_for_depth(int depth)
-{
-	switch (depth) {
-	case 32:
-	case 24:
-	default: return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN5_SURFACEFORMAT_B10G10R10A2_UNORM;
-	case 16: return GEN5_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN5_SURFACEFORMAT_B5G5R5A1_UNORM;
-	case 8:  return GEN5_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
-static uint32_t gen5_get_card_format_for_depth(int depth)
-{
-	switch (depth) {
-	case 32:
-	default: return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN5_SURFACEFORMAT_B10G10R10X2_UNORM;
-	case 24: return GEN5_SURFACEFORMAT_B8G8R8X8_UNORM;
-	case 16: return GEN5_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN5_SURFACEFORMAT_B5G5R5X1_UNORM;
-	case 8:  return GEN5_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
 typedef struct gen5_surface_state_padded {
 	struct gen5_surface_state state;
 	char pad[32 - sizeof(struct gen5_surface_state)];
@@ -679,7 +651,6 @@ static uint32_t gen5_get_card_format(PictFormat format)
 		if (gen5_tex_formats[i].pict_fmt == format)
 			return gen5_tex_formats[i].card_fmt;
 	}
-	assert(0);
 	return -1;
 }
 
@@ -1725,7 +1696,7 @@ static void gen5_video_bind_surfaces(struct sna *sna,
 	binding_table[0] =
 		gen5_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen5_get_dest_format_for_depth(op->dst.format),
+			     gen5_get_dest_format(op->dst.format),
 			     TRUE);
 	for (n = 0; n < n_src; n++) {
 		binding_table[1+n] =
@@ -1897,10 +1868,6 @@ gen5_composite_picture(struct sna *sna,
 						x, y, w, h, dst_x, dst_y);
 	}
 
-	if (!gen5_check_format(picture))
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-
 	if (!gen5_check_repeat(picture))
 		return sna_render_picture_fixup(sna, picture, channel,
 						x, y, w, h, dst_x, dst_y);
@@ -1930,6 +1897,9 @@ gen5_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen5_get_card_format(picture->format);
+	if (channel->card_format == -1)
+		return sna_render_picture_convert(sna, picture, channel, pixmap,
+						  x, y, w, h, dst_x, dst_y);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
 		return sna_render_picture_extract(sna, picture, channel,
@@ -2079,7 +2049,7 @@ source_fallback(PicturePtr p)
 		is_gradient(p) ||
 		!gen5_check_filter(p) ||
 		!gen5_check_repeat(p) ||
-		!gen5_check_format(p));
+		!gen5_check_format(p->format));
 }
 
 static bool
@@ -2202,7 +2172,7 @@ reuse_source(struct sna *sna,
 	if (!gen5_check_filter(mask))
 		return FALSE;
 
-	if (!gen5_check_format(mask))
+	if (!gen5_check_format(mask->format))
 		return FALSE;
 
 	DBG(("%s: reusing source channel for mask with a twist\n",
@@ -2719,7 +2689,7 @@ gen5_copy_bind_surfaces(struct sna *sna,
 	binding_table[0] =
 		gen5_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen5_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+			     gen5_get_dest_format(op->dst.pixmap->drawable.depth),
 			     TRUE);
 	binding_table[1] =
 		gen5_bind_bo(sna,
@@ -2764,11 +2734,26 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
 
 	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
 	    too_large(src->drawable.width, src->drawable.height) ||
-	    too_large(dst->drawable.width, dst->drawable.height))
+	    too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
+	    if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+		    return FALSE;
+
 		return sna_blt_copy_boxes_fallback(sna, alu,
 						   src, src_bo, src_dx, src_dy,
 						   dst, dst_bo, dst_dx, dst_dy,
 						   box, n);
+	}
+
+	if (dst->drawable.depth == src->drawable.depth) {
+		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = tmp.dst.format;
+	} else {
+		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen5_check_format(tmp.src.pict_format))
+		goto fallback;
 
 	DBG(("%s (%d, %d)->(%d, %d) x %d\n",
 	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
@@ -2780,7 +2765,6 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.pixmap = dst;
 	tmp.dst.width  = dst->drawable.width;
 	tmp.dst.height = dst->drawable.height;
-	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = dst_dx;
 	tmp.dst.y = dst_dy;
@@ -2789,7 +2773,7 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
 	tmp.src.repeat = SAMPLER_EXTEND_NONE;
 	tmp.src.card_format =
-		gen5_get_card_format_for_depth(src->drawable.depth),
+		gen5_get_card_format(tmp.src.pict_format);
 	tmp.src.width  = src->drawable.width;
 	tmp.src.height = src->drawable.height;
 
@@ -2909,6 +2893,7 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
 	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
 	    too_large(src->drawable.width, src->drawable.height) ||
 	    too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
 		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
 			return FALSE;
 
@@ -2917,6 +2902,16 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
 				    op);
 	}
 
+	if (dst->drawable.depth == src->drawable.depth) {
+		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = op->base.dst.format;
+	} else {
+		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen5_check_format(op->base.src.pict_format))
+		goto fallback;
+
 	op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
 	op->base.dst.pixmap = dst;
@@ -2927,7 +2922,7 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
 
 	op->base.src.bo = src_bo;
 	op->base.src.card_format =
-		gen5_get_card_format_for_depth(src->drawable.depth),
+		gen5_get_card_format(op->base.src.pict_format);
 	op->base.src.width  = src->drawable.width;
 	op->base.src.height = src->drawable.height;
 	op->base.src.scale[0] = 1.f/src->drawable.width;
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 0801e04..8d3c031 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -208,7 +208,6 @@ static const struct formatinfo {
 	{PICT_r8g8b8, GEN6_SURFACEFORMAT_R8G8B8_UNORM},
 	{PICT_r5g6b5, GEN6_SURFACEFORMAT_B5G6R5_UNORM},
 	{PICT_a1r5g5b5, GEN6_SURFACEFORMAT_B5G5R5A1_UNORM},
-	{PICT_x1r5g5b5, GEN6_SURFACEFORMAT_B5G5R5X1_UNORM},
 	{PICT_a2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10A2_UNORM},
 	{PICT_x2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10X2_UNORM},
 	{PICT_a2b10g10r10, GEN6_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -311,9 +310,9 @@ static Bool gen6_check_dst_format(PictFormat format)
 	return FALSE;
 }
 
-static bool gen6_check_format(PicturePtr p)
+static bool gen6_check_format(uint32_t format)
 {
-	switch (p->format) {
+	switch (format) {
 	case PICT_a8r8g8b8:
 	case PICT_x8r8g8b8:
 	case PICT_a8b8g8r8:
@@ -322,44 +321,17 @@ static bool gen6_check_format(PicturePtr p)
 	case PICT_x2r10g10b10:
 	case PICT_r8g8b8:
 	case PICT_r5g6b5:
-	case PICT_x1r5g5b5:
 	case PICT_a1r5g5b5:
 	case PICT_a8:
 	case PICT_a4r4g4b4:
 	case PICT_x4r4g4b4:
 		return true;
 	default:
-		DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
 		return false;
 	}
 }
 
-static uint32_t gen6_get_dest_format_for_depth(int depth)
-{
-	switch (depth) {
-	default: assert(0);
-	case 32:
-	case 24: return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
-	case 16: return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
-	case 8:  return GEN6_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
-static uint32_t gen6_get_card_format_for_depth(int depth)
-{
-	switch (depth) {
-	default: assert(0);
-	case 32: return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN6_SURFACEFORMAT_B10G10R10X2_UNORM;
-	case 24: return GEN6_SURFACEFORMAT_B8G8R8X8_UNORM;
-	case 16: return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN6_SURFACEFORMAT_B5G5R5X1_UNORM;
-	case 8:  return GEN6_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
 static uint32_t gen6_filter(uint32_t filter)
 {
 	switch (filter) {
@@ -1937,7 +1909,7 @@ gen6_render_video(struct sna *sna,
 	tmp.dst.pixmap = pixmap;
 	tmp.dst.width  = pixmap->drawable.width;
 	tmp.dst.height = pixmap->drawable.height;
-	tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth);
+	tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth);
 	tmp.dst.bo = priv->gpu_bo;
 
 	tmp.src.filter = SAMPLER_FILTER_BILINEAR;
@@ -2093,10 +2065,6 @@ gen6_composite_picture(struct sna *sna,
 		return sna_render_picture_fixup(sna, picture, channel,
 						x, y, w, h, dst_x, dst_y);
 
-	if (!gen6_check_format(picture))
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-
 	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
 	channel->filter = picture->filter;
 
@@ -2118,6 +2086,9 @@ gen6_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen6_get_card_format(picture->format);
+	if (channel->card_format == (unsigned)-1)
+		return sna_render_picture_convert(sna, picture, channel, pixmap,
+						  x, y, w, h, dst_x, dst_y);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
 		DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
@@ -2261,7 +2232,7 @@ has_alphamap(PicturePtr p)
 static bool
 source_fallback(PicturePtr p)
 {
-	return has_alphamap(p) || is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p) || !gen6_check_format(p);
+	return has_alphamap(p) || is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p) || !gen6_check_format(p->format);
 }
 
 static bool
@@ -2384,7 +2355,7 @@ reuse_source(struct sna *sna,
 	if (!gen6_check_filter(mask))
 		return FALSE;
 
-	if (!gen6_check_format(mask))
+	if (!gen6_check_format(mask->format))
 		return FALSE;
 
 	DBG(("%s: reusing source channel for mask with a twist\n",
@@ -3011,7 +2982,7 @@ gen6_emit_copy_state(struct sna *sna,
 	binding_table[0] =
 		gen6_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen6_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+			     gen6_get_dest_format(op->dst.format),
 			     TRUE);
 	binding_table[1] =
 		gen6_bind_bo(sna,
@@ -3113,11 +3084,26 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
 		     dst_bo, dst_dx, dst_dy,
 		     box, n) ||
 	    too_large(src->drawable.width, src->drawable.height) ||
-	    too_large(dst->drawable.width, dst->drawable.height))
+	    too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
+	    if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+		    return false;
+
 		return sna_blt_copy_boxes_fallback(sna, alu,
 						   src, src_bo, src_dx, src_dy,
 						   dst, dst_bo, dst_dx, dst_dy,
 						   box, n);
+	}
+
+	if (dst->drawable.depth == src->drawable.depth) {
+		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = tmp.dst.format;
+	} else {
+		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen6_check_format(tmp.src.pict_format))
+		goto fallback;
 
 	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
@@ -3125,7 +3111,6 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.x = tmp.dst.y = 0;
 	tmp.dst.width  = dst->drawable.width;
 	tmp.dst.height = dst->drawable.height;
-	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = dst_dx;
 	tmp.dst.y = dst_dy;
@@ -3134,7 +3119,7 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
 	tmp.src.repeat = SAMPLER_EXTEND_NONE;
 	tmp.src.card_format =
-		gen6_get_card_format_for_depth(src->drawable.depth),
+		gen6_get_card_format(tmp.src.pict_format);
 	tmp.src.width  = src->drawable.width;
 	tmp.src.height = src->drawable.height;
 
@@ -3269,6 +3254,7 @@ gen6_render_copy(struct sna *sna, uint8_t alu,
 	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
 	    too_large(src->drawable.width, src->drawable.height) ||
 	    too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
 		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
 			return FALSE;
 
@@ -3277,17 +3263,26 @@ gen6_render_copy(struct sna *sna, uint8_t alu,
 				    op);
 	}
 
+	if (dst->drawable.depth == src->drawable.depth) {
+		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = op->base.dst.format;
+	} else {
+		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen6_check_format(op->base.src.pict_format))
+		goto fallback;
+
 	op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
 	op->base.dst.pixmap = dst;
 	op->base.dst.width  = dst->drawable.width;
 	op->base.dst.height = dst->drawable.height;
-	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
 	op->base.dst.bo = dst_bo;
 
 	op->base.src.bo = src_bo;
 	op->base.src.card_format =
-		gen6_get_card_format_for_depth(src->drawable.depth),
+		gen6_get_card_format(op->base.src.pict_format);
 	op->base.src.width  = src->drawable.width;
 	op->base.src.height = src->drawable.height;
 	op->base.src.scale[0] = 1.f/src->drawable.width;
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 9665b3c..b8e5565 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -216,7 +216,6 @@ static const struct formatinfo {
 	{PICT_r8g8b8, GEN7_SURFACEFORMAT_R8G8B8_UNORM},
 	{PICT_r5g6b5, GEN7_SURFACEFORMAT_B5G6R5_UNORM},
 	{PICT_a1r5g5b5, GEN7_SURFACEFORMAT_B5G5R5A1_UNORM},
-	{PICT_x1r5g5b5, GEN7_SURFACEFORMAT_B5G5R5X1_UNORM},
 	{PICT_a2r10g10b10, GEN7_SURFACEFORMAT_B10G10R10A2_UNORM},
 	{PICT_x2r10g10b10, GEN7_SURFACEFORMAT_B10G10R10X2_UNORM},
 	{PICT_a2b10g10r10, GEN7_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -319,9 +318,9 @@ static Bool gen7_check_dst_format(PictFormat format)
 	return FALSE;
 }
 
-static bool gen7_check_format(PicturePtr p)
+static bool gen7_check_format(uint32_t format)
 {
-	switch (p->format) {
+	switch (format) {
 	case PICT_a8r8g8b8:
 	case PICT_x8r8g8b8:
 	case PICT_a8b8g8r8:
@@ -330,44 +329,17 @@ static bool gen7_check_format(PicturePtr p)
 	case PICT_x2r10g10b10:
 	case PICT_r8g8b8:
 	case PICT_r5g6b5:
-	case PICT_x1r5g5b5:
 	case PICT_a1r5g5b5:
 	case PICT_a8:
 	case PICT_a4r4g4b4:
 	case PICT_x4r4g4b4:
 		return true;
 	default:
-		DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
 		return false;
 	}
 }
 
-static uint32_t gen7_get_dest_format_for_depth(int depth)
-{
-	switch (depth) {
-	default: assert(0);
-	case 32:
-	case 24: return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN7_SURFACEFORMAT_B10G10R10A2_UNORM;
-	case 16: return GEN7_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN7_SURFACEFORMAT_B5G5R5A1_UNORM;
-	case 8:  return GEN7_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
-static uint32_t gen7_get_card_format_for_depth(int depth)
-{
-	switch (depth) {
-	default: assert(0);
-	case 32: return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case 30: return GEN7_SURFACEFORMAT_B10G10R10X2_UNORM;
-	case 24: return GEN7_SURFACEFORMAT_B8G8R8X8_UNORM;
-	case 16: return GEN7_SURFACEFORMAT_B5G6R5_UNORM;
-	case 15: return GEN7_SURFACEFORMAT_B5G5R5X1_UNORM;
-	case 8:  return GEN7_SURFACEFORMAT_A8_UNORM;
-	}
-}
-
 static uint32_t gen7_filter(uint32_t filter)
 {
 	switch (filter) {
@@ -1235,7 +1207,6 @@ static uint32_t gen7_get_card_format(PictFormat format)
 		if (gen7_tex_formats[i].pict_fmt == format)
 			return gen7_tex_formats[i].card_fmt;
 	}
-	assert(0);
 	return -1;
 }
 
@@ -2189,10 +2160,6 @@ gen7_composite_picture(struct sna *sna,
 		return sna_render_picture_fixup(sna, picture, channel,
 						x, y, w, h, dst_x, dst_y);
 
-	if (!gen7_check_format(picture))
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-
 	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
 	channel->filter = picture->filter;
 
@@ -2214,6 +2181,9 @@ gen7_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen7_get_card_format(picture->format);
+	if (channel->card_format == -1)
+		return sna_render_picture_convert(sna, picture, channel, pixmap,
+						  x, y, w, h, dst_x, dst_y);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
 		DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
@@ -2357,7 +2327,7 @@ has_alphamap(PicturePtr p)
 static bool
 source_fallback(PicturePtr p)
 {
-	return has_alphamap(p) || is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p) || !gen7_check_format(p);
+	return has_alphamap(p) || is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p) || !gen7_check_format(p->format);
 }
 
 static bool
@@ -2480,7 +2450,7 @@ reuse_source(struct sna *sna,
 	if (!gen7_check_filter(mask))
 		return FALSE;
 
-	if (!gen7_check_format(mask))
+	if (!gen7_check_format(mask->format))
 		return FALSE;
 
 	DBG(("%s: reusing source channel for mask with a twist\n",
@@ -3015,7 +2985,7 @@ gen7_emit_copy_state(struct sna *sna,
 	binding_table[0] =
 		gen7_bind_bo(sna,
 			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen7_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+			     gen7_get_dest_format(op->dst.pixmap->drawable.depth),
 			     TRUE);
 	binding_table[1] =
 		gen7_bind_bo(sna,
@@ -3080,11 +3050,26 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
 
 	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
 	    too_large(src->drawable.width, src->drawable.height) ||
-	    too_large(dst->drawable.width, dst->drawable.height))
+	    too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
+		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+			return FALSE;
+
 		return sna_blt_copy_boxes_fallback(sna, alu,
 						   src, src_bo, src_dx, src_dy,
 						   dst, dst_bo, dst_dx, dst_dy,
 						   box, n);
+	}
+
+	if (dst->drawable.depth == src->drawable.depth) {
+		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = tmp.dst.format;
+	} else {
+		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen7_check_format(tmp.src.pict_format))
+		goto fallback;
 
 	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
@@ -3092,7 +3077,6 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.x = tmp.dst.y = 0;
 	tmp.dst.width  = dst->drawable.width;
 	tmp.dst.height = dst->drawable.height;
-	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = dst_dx;
 	tmp.dst.y = dst_dy;
@@ -3101,7 +3085,7 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
 	tmp.src.repeat = SAMPLER_EXTEND_NONE;
 	tmp.src.card_format =
-		gen7_get_card_format_for_depth(src->drawable.depth),
+		gen7_get_card_format(tmp.src.pict_format);
 	tmp.src.width  = src->drawable.width;
 	tmp.src.height = src->drawable.height;
 
@@ -3234,6 +3218,7 @@ gen7_render_copy(struct sna *sna, uint8_t alu,
 	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
 	    too_large(src->drawable.width, src->drawable.height) ||
 	    too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
 		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
 			return FALSE;
 
@@ -3241,18 +3226,26 @@ gen7_render_copy(struct sna *sna, uint8_t alu,
 				    dst->drawable.bitsPerPixel,
 				    op);
 	}
+	if (dst->drawable.depth == src->drawable.depth) {
+		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = op->base.dst.format;
+	} else {
+		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+	}
+	if (!gen7_check_format(op->base.src.pict_format))
+		goto fallback;
 
 	op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 
 	op->base.dst.pixmap = dst;
 	op->base.dst.width  = dst->drawable.width;
 	op->base.dst.height = dst->drawable.height;
-	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
 	op->base.dst.bo = dst_bo;
 
 	op->base.src.bo = src_bo;
 	op->base.src.card_format =
-		gen7_get_card_format_for_depth(src->drawable.depth),
+		gen7_get_card_format(op->base.src.pict_format);
 	op->base.src.width  = src->drawable.width;
 	op->base.src.height = src->drawable.height;
 	op->base.src.scale[0] = 1.f/src->drawable.width;
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 5153d33..e9c85b7 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -379,6 +379,7 @@ void sna_kgem_flush(struct kgem *kgem);
 void sna_kgem_context_switch(struct kgem *kgem, int new_mode);
 
 CARD32 sna_format_for_depth(int depth);
+CARD32 sna_render_format_for_depth(int depth);
 
 void sna_debug_flush(struct sna *sna);
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 979b2b0..a9a170a 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -57,6 +57,22 @@ sna_format_for_depth(int depth)
 	}
 }
 
+CARD32
+sna_render_format_for_depth(int depth)
+{
+	switch (depth) {
+	case 1: return PICT_a1;
+	case 4: return PICT_a4;
+	case 8: return PICT_a8;
+	case 15: return PICT_a1r5g5b5;
+	case 16: return PICT_r5g6b5;
+	case 30: return PICT_a2r10g10b10;
+	default: assert(0);
+	case 24:
+	case 32: return PICT_a8r8g8b8;
+	}
+}
+
 static Bool
 no_render_composite(struct sna *sna,
 		    uint8_t op,


More information about the xorg-commit mailing list