xf86-video-intel: 9 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h

Chris Wilson ickle at kemper.freedesktop.org
Sun Jan 15 01:50:22 PST 2012


 src/sna/gen2_render.c |   42 ++++++++++++++-
 src/sna/gen3_render.c |   66 ++++++++++++++++++++++--
 src/sna/gen4_render.c |   63 ++++++++++++++++++++---
 src/sna/gen5_render.c |   68 ++++++++++++++++++++++---
 src/sna/gen6_render.c |   49 +++++++++++++++---
 src/sna/gen7_render.c |   57 ++++++++++++++++++---
 src/sna/kgem.c        |  135 ++++++++++++++++++++++----------------------------
 src/sna/kgem.h        |    1 
 8 files changed, 368 insertions(+), 113 deletions(-)

New commits:
commit 09dc8b1b358aa33836d511b75f92e8d096bc7e59
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:21:29 2012 +0000

    sna/gen7: Check reused source for validity
    
    Be sure the mask picture has a valid format even though it points to the
    same pixels as the valid source. And also be wary if the source was
    converted to a solid, but the mask is not.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 22038ea..9665b3c 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -319,6 +319,29 @@ static Bool gen7_check_dst_format(PictFormat format)
 	return FALSE;
 }
 
+static bool gen7_check_format(PicturePtr p)
+{
+	switch (p->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	case PICT_a2r10g10b10:
+	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));
+		return false;
+	}
+}
+
 static uint32_t gen7_get_dest_format_for_depth(int depth)
 {
 	switch (depth) {
@@ -1212,6 +1235,7 @@ 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;
 }
 
@@ -2165,6 +2189,10 @@ 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;
 
@@ -2186,9 +2214,6 @@ gen7_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen7_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__,
@@ -2332,7 +2357,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);
+	return has_alphamap(p) || is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p) || !gen7_check_format(p);
 }
 
 static bool
@@ -2420,14 +2445,29 @@ reuse_source(struct sna *sna,
 	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
 	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
 {
-	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+	uint32_t color;
+
+	if (src_x != msk_x || src_y != msk_y)
 		return FALSE;
 
-	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+	if (src == mask) {
+		DBG(("%s: mask is source\n", __FUNCTION__));
+		*mc = *sc;
+		mc->bo = kgem_bo_reference(mc->bo);
+		return TRUE;
+	}
 
-	if (src_x != msk_x || src_y != msk_y)
+	if (sna_picture_is_solid(mask, &color))
+		return gen7_composite_solid_init(sna, mc, color);
+
+	if (sc->is_solid)
+		return FALSE;
+
+	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
 		return FALSE;
 
+	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+
 	if (!sna_transform_equal(src->transform, mask->transform))
 		return FALSE;
 
@@ -2440,6 +2480,9 @@ reuse_source(struct sna *sna,
 	if (!gen7_check_filter(mask))
 		return FALSE;
 
+	if (!gen7_check_format(mask))
+		return FALSE;
+
 	DBG(("%s: reusing source channel for mask with a twist\n",
 	     __FUNCTION__));
 
commit d9871f01d8c4584c1f39eb09b51d5461863934e9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:21:29 2012 +0000

    sna/gen6: Check reused source for validity
    
    Be sure the mask picture has a valid format even though it points to the
    same pixels as the valid source. And also be wary if the source was
    converted to a solid, but the mask is not.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index d25ece1..b155e86 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -311,6 +311,29 @@ static Bool gen6_check_dst_format(PictFormat format)
 	return FALSE;
 }
 
+static bool gen6_check_format(PicturePtr p)
+{
+	switch (p->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	case PICT_a2r10g10b10:
+	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));
+		return false;
+	}
+}
+
 static uint32_t gen6_get_dest_format_for_depth(int depth)
 {
 	switch (depth) {
@@ -2064,6 +2087,10 @@ 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;
 
@@ -2085,9 +2112,6 @@ 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__,
@@ -2231,7 +2255,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);
+	return has_alphamap(p) || is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p) || !gen6_check_format(p);
 }
 
 static bool
@@ -2319,16 +2343,24 @@ reuse_source(struct sna *sna,
 	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
 	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
 {
+	uint32_t color;
+
 	if (src_x != msk_x || src_y != msk_y)
 		return FALSE;
 
-	if (mask == src) {
-		DBG(("%s: mask is source picture\n", __FUNCTION__));
+	if (src == mask) {
+		DBG(("%s: mask is source\n", __FUNCTION__));
 		*mc = *sc;
-		kgem_bo_reference(mc->bo);
+		mc->bo = kgem_bo_reference(mc->bo);
 		return TRUE;
 	}
 
+	if (sna_picture_is_solid(mask, &color))
+		return gen6_composite_solid_init(sna, mc, color);
+
+	if (sc->is_solid)
+		return FALSE;
+
 	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
 		return FALSE;
 
@@ -2346,6 +2378,9 @@ reuse_source(struct sna *sna,
 	if (!gen6_check_filter(mask))
 		return FALSE;
 
+	if (!gen6_check_format(mask))
+		return FALSE;
+
 	DBG(("%s: reusing source channel for mask with a twist\n",
 	     __FUNCTION__));
 
commit 1d6030322e2c3bae87a0173a32fb8d341dea560c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:21:29 2012 +0000

    sna/gen5: Check reused source for validity
    
    Be sure the mask picture has a valid format even though it points to the
    same pixels as the valid source. And also be wary if the source was
    converted to a solid, but the mask is not.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 560830e..f8d8d10 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -557,8 +557,33 @@ static Bool gen5_check_dst_format(PictFormat format)
 	case PICT_a4r4g4b4:
 	case PICT_x4r4g4b4:
 		return TRUE;
+	default:
+		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
+		return FALSE;
+	}
+}
+
+static bool gen5_check_format(PicturePtr p)
+{
+	switch (p->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	case PICT_a2r10g10b10:
+	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));
+		return false;
 	}
-	return FALSE;
 }
 
 static uint32_t gen5_get_dest_format_for_depth(int depth)
@@ -654,6 +679,7 @@ 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;
 }
 
@@ -676,6 +702,7 @@ static uint32_t gen5_check_filter(PicturePtr picture)
 	case PictFilterBilinear:
 		return TRUE;
 	default:
+		DBG(("%s: unknown filter: %x\n", __FUNCTION__, picture->filter));
 		return FALSE;
 	}
 }
@@ -708,6 +735,8 @@ static bool gen5_check_repeat(PicturePtr picture)
 	case RepeatReflect:
 		return TRUE;
 	default:
+		DBG(("%s: unknown repeat: %x\n",
+		     __FUNCTION__, picture->repeatType));
 		return FALSE;
 	}
 }
@@ -1868,6 +1897,10 @@ 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);
@@ -1897,9 +1930,6 @@ gen5_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen5_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))
 		return sna_render_picture_extract(sna, picture, channel,
@@ -2045,7 +2075,11 @@ has_alphamap(PicturePtr p)
 static bool
 source_fallback(PicturePtr p)
 {
-	return has_alphamap(p) || is_gradient(p) || !gen5_check_filter(p) || !gen5_check_repeat(p);
+	return (has_alphamap(p) ||
+		is_gradient(p) ||
+		!gen5_check_filter(p) ||
+		!gen5_check_repeat(p) ||
+		!gen5_check_format(p));
 }
 
 static bool
@@ -2133,14 +2167,29 @@ reuse_source(struct sna *sna,
 	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
 	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
 {
-	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+	uint32_t color;
+
+	if (src_x != msk_x || src_y != msk_y)
 		return FALSE;
 
-	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+	if (src == mask) {
+		DBG(("%s: mask is source\n", __FUNCTION__));
+		*mc = *sc;
+		mc->bo = kgem_bo_reference(mc->bo);
+		return TRUE;
+	}
 
-	if (src_x != msk_x || src_y != msk_y)
+	if (sna_picture_is_solid(mask, &color))
+		return gen5_composite_solid_init(sna, mc, color);
+
+	if (sc->is_solid)
+		return FALSE;
+
+	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
 		return FALSE;
 
+	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+
 	if (!sna_transform_equal(src->transform, mask->transform))
 		return FALSE;
 
@@ -2153,6 +2202,9 @@ reuse_source(struct sna *sna,
 	if (!gen5_check_filter(mask))
 		return FALSE;
 
+	if (!gen5_check_format(mask))
+		return FALSE;
+
 	DBG(("%s: reusing source channel for mask with a twist\n",
 	     __FUNCTION__));
 
commit 0e4a24ef6c186909c99a501cb606994b5c10a813
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:21:29 2012 +0000

    sna/gen4: Check reused source for validity
    
    Be sure the mask picture has a valid format even though it points to the
    same pixels as the valid source. And also be wary if the source was
    converted to a solid, but the mask is not.
    
    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 12281e3..d44ddd5 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -556,8 +556,33 @@ static Bool gen4_check_dst_format(PictFormat format)
 	case PICT_a4r4g4b4:
 	case PICT_x4r4g4b4:
 		return TRUE;
+	default:
+		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
+		return FALSE;
+	}
+}
+
+static bool gen4_check_format(PicturePtr p)
+{
+	switch (p->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	case PICT_a2r10g10b10:
+	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));
+		return false;
 	}
-	return FALSE;
 }
 
 typedef struct gen4_surface_state_padded {
@@ -627,6 +652,7 @@ 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;
 }
 
@@ -1819,6 +1845,12 @@ 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,
@@ -1852,9 +1884,6 @@ gen4_composite_picture(struct sna *sna,
 		channel->transform = picture->transform;
 
 	channel->card_format = gen4_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 (pixmap->drawable.width > 8192 || pixmap->drawable.height > 8192)
 		return sna_render_picture_extract(sna, picture, channel,
@@ -1991,7 +2020,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);
+	return has_alphamap(p) || is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p) || !gen4_check_format(p);
 }
 
 static bool
@@ -2079,14 +2108,29 @@ reuse_source(struct sna *sna,
 	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
 	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
 {
-	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+	uint32_t color;
+
+	if (src_x != msk_x || src_y != msk_y)
 		return FALSE;
 
-	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+	if (src == mask) {
+		DBG(("%s: mask is source\n", __FUNCTION__));
+		*mc = *sc;
+		mc->bo = kgem_bo_reference(mc->bo);
+		return TRUE;
+	}
 
-	if (src_x != msk_x || src_y != msk_y)
+	if (sna_picture_is_solid(mask, &color))
+		return gen4_composite_solid_init(sna, mc, color);
+
+	if (sc->is_solid)
 		return FALSE;
 
+	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+		return FALSE;
+
+	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+
 	if (!sna_transform_equal(src->transform, mask->transform))
 		return FALSE;
 
@@ -2099,6 +2143,9 @@ reuse_source(struct sna *sna,
 	if (!gen4_check_filter(mask))
 		return FALSE;
 
+	if (!gen4_check_format(mask))
+		return FALSE;
+
 	DBG(("%s: reusing source channel for mask with a twist\n",
 	     __FUNCTION__));
 
commit ea299f2523d5adeca84274bb7003cde8ec743a44
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:21:29 2012 +0000

    sna/gen3: Check reused source for validity
    
    Be sure the mask picture has a valid format even though it points to the
    same pixels as the valid source. And also be wary if the source was
    converted to a solid, but the mask is not.
    
    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 a3db4bb..cd59a08 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -281,6 +281,56 @@ static uint32_t gen3_get_dst_format(uint32_t format)
 #undef BIAS
 }
 
+static Bool gen3_check_format(PicturePtr p)
+{
+	switch (p->format) {
+	case PICT_a8:
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	case PICT_a2r10g10b10:
+	case PICT_a2b10g10r10:
+	case PICT_r5g6b5:
+	case PICT_b5g6r5:
+	case PICT_a1r5g5b5:
+	case PICT_a1b5g5r5:
+	case PICT_a4r4g4b4:
+	case PICT_a4b4g4r4:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
+static Bool gen3_check_xformat(PicturePtr p)
+{
+	switch (p->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	case PICT_r5g6b5:
+	case PICT_b5g6r5:
+	case PICT_a1r5g5b5:
+	case PICT_x1r5g5b5:
+	case PICT_a1b5g5r5:
+	case PICT_x1b5g5r5:
+	case PICT_a2r10g10b10:
+	case PICT_x2r10g10b10:
+	case PICT_a2b10g10r10:
+	case PICT_x2b10g10r10:
+	case PICT_a8:
+	case PICT_a4r4g4b4:
+	case PICT_x4r4g4b4:
+	case PICT_a4b4g4r4:
+	case PICT_x4b4g4r4:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
 static uint32_t gen3_texture_repeat(uint32_t repeat)
 {
 #define REPEAT(x) \
@@ -353,9 +403,9 @@ static uint32_t gen3_filter(uint32_t filter)
 	}
 }
 
-static bool gen3_check_filter(uint32_t filter)
+static bool gen3_check_filter(PicturePtr p)
 {
-	switch (filter) {
+	switch (p->filter) {
 	case PictFilterNearest:
 	case PictFilterBilinear:
 		return TRUE;
@@ -2153,7 +2203,7 @@ gen3_composite_picture(struct sna *sna,
 		return sna_render_picture_fixup(sna, picture, channel,
 						x, y, w, h, dst_x, dst_y);
 
-	if (!gen3_check_filter(picture->filter))
+	if (!gen3_check_filter(picture))
 		return sna_render_picture_fixup(sna, picture, channel,
 						x, y, w, h, dst_x, dst_y);
 
@@ -2354,7 +2404,7 @@ has_alphamap(PicturePtr p)
 static bool
 source_fallback(PicturePtr p)
 {
-	return has_alphamap(p) || !gen3_check_filter(p->filter) || !gen3_check_repeat(p);
+	return has_alphamap(p) || !gen3_check_xformat(p) || !gen3_check_filter(p) || !gen3_check_repeat(p);
 }
 
 static bool
@@ -2465,6 +2515,9 @@ reuse_source(struct sna *sna,
 	if ((src->pDrawable == NULL || mask->pDrawable != src->pDrawable))
 		return FALSE;
 
+	if (sc->is_solid)
+		return FALSE;
+
 	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
 
 	if (!sna_transform_equal(src->transform, mask->transform))
@@ -2476,7 +2529,10 @@ reuse_source(struct sna *sna,
 	if (!gen3_check_repeat(mask))
 		return FALSE;
 
-	if (!gen3_check_filter(mask->filter))
+	if (!gen3_check_filter(mask))
+		return FALSE;
+
+	if (!gen3_check_format(mask))
 		return FALSE;
 
 	DBG(("%s: reusing source channel for mask with a twist\n",
commit 007da2f97894814eaded4d24e0481f950ca7bd00
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:21:29 2012 +0000

    sna/gen2: Check reused source for validity
    
    Be sure the mask picture has a valid format even though it points to the
    same pixels as the valid source. And also be wary if the source was
    converted to a solid, but the mask is not.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index b448145..e5e5884 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -199,6 +199,24 @@ gen2_get_card_format(struct sna *sna, uint32_t format)
 }
 
 static uint32_t
+gen2_check_format(struct sna *sna, PicturePtr p)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++)
+		if (i8xx_tex_formats[i].fmt == p->format)
+			return true;
+
+	if (sna->kgem.gen > 21) {
+		for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++)
+			if (i85x_tex_formats[i].fmt == p->format)
+				return true;
+	}
+
+	return false;
+}
+
+static uint32_t
 gen2_sampler_tiling_bits(uint32_t tiling)
 {
 	uint32_t bits = 0;
@@ -1578,14 +1596,29 @@ reuse_source(struct sna *sna,
 	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
 	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
 {
-	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+	uint32_t color;
+
+	if (src_x != msk_x || src_y != msk_y)
 		return FALSE;
 
-	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+	if (src == mask) {
+		DBG(("%s: mask is source\n", __FUNCTION__));
+		*mc = *sc;
+		mc->bo = kgem_bo_reference(mc->bo);
+		return TRUE;
+	}
 
-	if (src_x != msk_x || src_y != msk_y)
+	if (sna_picture_is_solid(mask, &color))
+		return gen2_composite_solid_init(sna, mc, color);
+
+	if (sc->is_solid)
 		return FALSE;
 
+	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+		return FALSE;
+
+	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+
 	if (!sna_transform_equal(src->transform, mask->transform))
 		return FALSE;
 
@@ -1598,6 +1631,9 @@ reuse_source(struct sna *sna,
 	if (!gen2_check_filter(mask))
 		return FALSE;
 
+	if (!gen2_check_format(sna, mask))
+		return FALSE;
+
 	DBG(("%s: reusing source channel for mask with a twist\n",
 	     __FUNCTION__));
 
commit 1d55b42fbd77e85ab8930b78bb5a9e3bccbca49e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:44:23 2012 +0000

    sna: Fix read back of partial mmapped buffers
    
    Do not move a GTT mapped buffer into the CPU domain, it causes untold
    pain for no benefit!
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 5b93aba..2c77bc5 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2730,7 +2730,6 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
 }
 
 #if defined(USE_VMAP) && defined(I915_PARAM_HAS_VMAP)
-#define HAVE_VMAP 1
 static uint32_t gem_vmap(int fd, void *ptr, int size, int read_only)
 {
 	struct drm_i915_gem_vmap vmap;
@@ -2776,27 +2775,6 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
 	     __FUNCTION__, ptr, size, read_only, handle));
 	return bo;
 }
-#else
-#define HAVE_VMAP 0
-static uint32_t gem_vmap(int fd, void *ptr, int size, int read_only)
-{
-	return 0;
-	(void)fd;
-	(void)ptr;
-	(void)size;
-	(void)read_only;
-}
-
-struct kgem_bo *kgem_create_map(struct kgem *kgem,
-				void *ptr, uint32_t size,
-				bool read_only)
-{
-	return NULL;
-	(void)kgem;
-	(void)ptr;
-	(void)size;
-	(void)read_only;
-}
 #endif
 
 void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
@@ -2929,7 +2907,6 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 {
 	struct kgem_partial_bo *bo;
 	unsigned offset, alloc;
-	uint32_t handle;
 
 	DBG(("%s: size=%d, flags=%x [write?=%d, inplace?=%d, last?=%d]\n",
 	     __FUNCTION__, size, flags,
@@ -3098,65 +3075,48 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 #endif
 
 	if (bo == NULL) {
+		struct kgem_bo *old;
+
 		/* Be more parsimonious with pwrite/pread buffers */
 		if ((flags & KGEM_BUFFER_INPLACE) == 0)
 			alloc = PAGE_ALIGN(size);
 		flags &= ~KGEM_BUFFER_INPLACE;
 
-		if (HAVE_VMAP && kgem->has_vmap) {
+		old = NULL;
+		if ((flags & KGEM_BUFFER_WRITE) == 0)
+			old = search_linear_cache(kgem, alloc, 0);
+		if (old == NULL)
+			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
+		if (old) {
+			alloc = old->size;
 			bo = partial_bo_alloc(alloc);
 			if (bo == NULL)
 				return NULL;
 
-			handle = gem_vmap(kgem->fd, bo->mem, alloc,
-					  (flags & KGEM_BUFFER_WRITE) == 0);
-			if (handle) {
-				__kgem_bo_init(&bo->base, handle, alloc);
-				bo->base.vmap = true;
-				bo->need_io = false;
-			} else {
+			memcpy(&bo->base, old, sizeof(*old));
+			if (old->rq)
+				list_replace(&old->request,
+					     &bo->base.request);
+			else
+				list_init(&bo->base.request);
+			list_replace(&old->vma, &bo->base.vma);
+			list_init(&bo->base.list);
+			free(old);
+			bo->base.refcnt = 1;
+		} else {
+			bo = partial_bo_alloc(alloc);
+			if (bo == NULL)
+				return NULL;
+
+			if (!__kgem_bo_init(&bo->base,
+					    gem_create(kgem->fd, alloc),
+					    alloc)) {
 				free(bo);
 				return NULL;
 			}
-		} else {
-			struct kgem_bo *old;
-
-			old = NULL;
-			if ((flags & KGEM_BUFFER_WRITE) == 0)
-				old = search_linear_cache(kgem, alloc, 0);
-			if (old == NULL)
-				old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
-			if (old) {
-				alloc = old->size;
-				bo = partial_bo_alloc(alloc);
-				if (bo == NULL)
-					return NULL;
-
-				memcpy(&bo->base, old, sizeof(*old));
-				if (old->rq)
-					list_replace(&old->request,
-						     &bo->base.request);
-				else
-					list_init(&bo->base.request);
-				list_replace(&old->vma, &bo->base.vma);
-				list_init(&bo->base.list);
-				free(old);
-				bo->base.refcnt = 1;
-			} else {
-				bo = partial_bo_alloc(alloc);
-				if (bo == NULL)
-					return NULL;
-
-				if (!__kgem_bo_init(&bo->base,
-						    gem_create(kgem->fd, alloc),
-						    alloc)) {
-					free(bo);
-					return NULL;
-				}
-			}
-			bo->need_io = flags & KGEM_BUFFER_WRITE;
-			bo->base.io = true;
 		}
+		bo->need_io = flags & KGEM_BUFFER_WRITE;
+		bo->base.io = true;
 	}
 	bo->base.reusable = false;
 	assert(bo->base.size == alloc);
@@ -3329,15 +3289,33 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
 	DBG(("%s(offset=%d, length=%d, vmap=%d)\n", __FUNCTION__,
 	     offset, length, bo->base.vmap));
 
-	if (!bo->base.vmap && !bo->mmapped) {
+	if (bo->mmapped) {
+		struct drm_i915_gem_set_domain set_domain;
+
+		DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__,
+		     bo->needs_flush, bo->domain, kgem_busy(kgem, bo->handle)));
+
+		VG_CLEAR(set_domain);
+		set_domain.handle = bo->base.handle;
+		if (IS_CPU_MAP(bo->base.map)) {
+			set_domain.read_domains = I915_GEM_DOMAIN_CPU;
+			set_domain.write_domain = I915_GEM_DOMAIN_CPU;
+			bo->base.domain = DOMAIN_CPU;
+		} else {
+			set_domain.read_domains = I915_GEM_DOMAIN_GTT;
+			set_domain.write_domain = I915_GEM_DOMAIN_GTT;
+			bo->base.domain = DOMAIN_GTT;
+		}
+
+		drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
+	} else {
 		gem_read(kgem->fd,
 			 bo->base.handle, (char *)bo->mem+offset,
 			 offset, length);
-		kgem_bo_retire(kgem, &bo->base);
 		bo->base.domain = DOMAIN_NONE;
 		bo->base.reusable = false; /* in the CPU cache now */
-	} else
-		kgem_bo_sync__cpu(kgem, &bo->base);
+	}
+	kgem_bo_retire(kgem, &bo->base);
 }
 
 uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
commit 046e945173397e5fee36a231303b68a6bc9d809d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 14 23:25:52 2012 +0000

    sna: Discard read buffers after use
    
    Rather than pollute the cache with bo that are known not to be in the
    GTT and are no longer useful, drop the bo after we read from it.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 53af280..5b93aba 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3335,6 +3335,7 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
 			 offset, length);
 		kgem_bo_retire(kgem, &bo->base);
 		bo->base.domain = DOMAIN_NONE;
+		bo->base.reusable = false; /* in the CPU cache now */
 	} else
 		kgem_bo_sync__cpu(kgem, &bo->base);
 }
commit 421ee0bb53321e9fb2f17c850c51b80cc385bf57
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 00:46:47 2012 +0000

    sna: Do not assume that the mappable aperture size is a power of two
    
    And instead derive a power-of-two alignment value for partial buffer
    sizes from the mappable aperture size and use that during
    kgem_create_buffer()
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=44682
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 43feadb..53af280 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -622,9 +622,15 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	if (kgem->aperture_mappable == 0 ||
 	    kgem->aperture_mappable > aperture.aper_size)
 		kgem->aperture_mappable = aperture.aper_size;
-	DBG(("%s: aperture mappable=%d [%d]\n", __FUNCTION__,
+	DBG(("%s: aperture mappable=%d [%d MiB]\n", __FUNCTION__,
 	     kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
 
+	kgem->partial_buffer_size = 64 * 1024;
+	while (kgem->partial_buffer_size < kgem->aperture_mappable >> 10)
+		kgem->partial_buffer_size *= 2;
+	DBG(("%s: partial buffer size=%d [%d KiB]\n", __FUNCTION__,
+	     kgem->partial_buffer_size, kgem->partial_buffer_zie / 1024));
+
 	kgem->min_alignment = 4;
 	if (gen < 60)
 		/* XXX workaround an issue where we appear to fail to
@@ -2971,7 +2977,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 	}
 
 	/* Be a little more generous and hope to hold fewer mmappings */
-	alloc = ALIGN(size, kgem->aperture_mappable >> 10);
+	alloc = ALIGN(size, kgem->partial_buffer_size);
 	bo = NULL;
 
 #if !DBG_NO_MAP_UPLOAD
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index d9fdd68..421c84f 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -151,6 +151,7 @@ struct kgem {
 	uint32_t aperture_fenced, aperture_mappable;
 	uint32_t min_alignment;
 	uint32_t max_object_size;
+	uint32_t partial_buffer_size;
 
 	void (*context_switch)(struct kgem *kgem, int new_mode);
 	uint32_t batch[4*1024];


More information about the xorg-commit mailing list