[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 NEWS                         |   39 +++
 configure.ac                 |    2 
 src/intel_dri.c              |    8 
 src/intel_module.c           |  123 +++--------
 src/intel_options.c          |    2 
 src/intel_options.h          |    2 
 src/sna/gen2_render.c        |   73 ++++--
 src/sna/gen3_render.c        |   49 ++--
 src/sna/gen4_render.c        |  146 ++++++++++---
 src/sna/gen5_render.c        |  102 +++++++--
 src/sna/gen6_render.c        |  117 +++++++---
 src/sna/gen7_render.c        |   95 ++++++--
 src/sna/kgem.c               |  466 +++++++++++++++++++++++++++----------------
 src/sna/kgem.h               |   48 ++--
 src/sna/sna.h                |    1 
 src/sna/sna_accel.c          |   49 ++--
 src/sna/sna_blt.c            |   20 -
 src/sna/sna_display.c        |   57 ++---
 src/sna/sna_dri.c            |  152 ++++++++------
 src/sna/sna_driver.c         |   50 ++++
 src/sna/sna_io.c             |   14 -
 src/sna/sna_render.c         |    2 
 src/sna/sna_render.h         |    1 
 src/sna/sna_render_inline.h  |    9 
 src/sna/sna_trapezoids.c     |   35 +++
 src/sna/sna_video_sprite.c   |    1 
 src/sna/sna_video_textured.c |    5 
 27 files changed, 1111 insertions(+), 557 deletions(-)

New commits:
commit a467102a9539c7f4fa8d0700ecdcaba49d77b3f7
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 15 10:00:48 2012 +0000

    2.20.16 release
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/NEWS b/NEWS
index 2809dcb..36c81d7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,42 @@
+Release 2.20.16 (2012-12-15)
+============================
+Rejoice! We have found a trick to make 830gm/845g stable at long last.
+Ever since the switch to GEM and dynamic video memory, those early
+second generation chipsets have been plagued by instability. The lack of
+flushing cachelines from the CPU to GMCH was eventually solved by using
+an undocmented bit, but 830/845 were still hanging under memory pressure.
+These deaths were all due to garbage finding its way into the command
+streamer, and they go away if we take a leaf out of the original driver
+and never reuse those pages for anything else. So for the first time
+ever, I have been able to complete running the test suite on an 845g,
+even whilst thrashing the page and buffer caches!
+
+ * Run the SF stage as single-threaded on gen4 to workaround a few issues
+   https://bugs.freedesktop.org/show_bug.cgi?id=57410
+
+ * Keep the scanout SURFACE_STATE separate to avoid overriding its
+   memory access control on gen6/7 (i.e. writes to the scanout need to
+   be kept out of the render cache)
+
+ * Tune batch flushing after an operation to an exported surface under a
+   compositor.
+
+ * Make sure the source is on the CPU for inplace composition of trapezoids
+   using the CPU
+   https://bugs.freedesktop.org/show_bug.cgi?id=56825
+
+ * Immediately flush in the block hander after a split batch to reduce
+   latency between the two halves of an operation.
+   https://bugs.freedesktop.org/show_bug.cgi?id=51718
+
+ * Install a fallback config if we fail to install the desired config
+   at VT switch (i.e. booting, after resume with 3 incompatible pipes on
+   Ivybridge)
+
+ * Pin batches to avoid CS incoherence on 830/845
+   https://bugs.freedesktop.org/show_bug.cgi?id=26345
+
+
 Release 2.20.15 (2012-12-03)
 ============================
 And lo, enabling more of the common acceleration paths for gen4 revealed
diff --git a/configure.ac b/configure.ac
index 8ada660..9354437 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-intel],
-        [2.20.15],
+        [2.20.16],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-video-intel])
 AC_CONFIG_SRCDIR([Makefile.am])

commit b0f8c823b6cafdfdd064c09d58174f946e290541
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 15 09:28:04 2012 +0000

    sna/dri: Fallback to a blit after a failed flip
    
    ...rather than force the exchange.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 522549a..fc84e94 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1798,15 +1798,8 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 		sna_dri_page_flip(sna, info);
 
 		if (info->count == 0) {
-			info->back->name = info->old_front.name;
-			get_private(info->back)->bo = info->old_front.bo;
-			info->old_front.bo = NULL;
-
-			DRI2SwapComplete(info->client, draw, 0, 0, 0,
-					 DRI2_EXCHANGE_COMPLETE,
-					 info->event_complete,
-					 info->event_data);
 			sna_dri_frame_event_info_free(sna, draw, info);
+			return false;
 		} else if (info->type != DRI2_FLIP) {
 			get_private(info->back)->bo =
 				kgem_create_2d(&sna->kgem,

commit 2c71a8e08abce74b269687d3a6c1edd7f9d643d3
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 15 09:27:07 2012 +0000

    sna/dri: Honour TripleBuffer Option
    
    In case anyone ever wants to disable the default.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/intel_options.c b/src/intel_options.c
index 443e84d..f7ff595 100644
--- a/src/intel_options.c
+++ b/src/intel_options.c
@@ -14,6 +14,7 @@ const OptionInfoRec intel_options[] = {
 	{OPTION_TILING_2D,	"Tiling",	OPTV_BOOLEAN,	{0},	1},
 	{OPTION_TILING_FB,	"LinearFramebuffer",	OPTV_BOOLEAN,	{0},	0},
 	{OPTION_SWAPBUFFERS_WAIT, "SwapbuffersWait", OPTV_BOOLEAN,	{0},	1},
+	{OPTION_TRIPLE_BUFFER,	"TripleBuffer", OPTV_BOOLEAN,	{0},	1},
 	{OPTION_PREFER_OVERLAY, "XvPreferOverlay", OPTV_BOOLEAN, {0}, 0},
 	{OPTION_HOTPLUG,	"HotPlug",	OPTV_BOOLEAN,	{0},	1},
 	{OPTION_RELAXED_FENCING,"RelaxedFencing",	OPTV_BOOLEAN,	{0},	1},
@@ -33,7 +34,6 @@ const OptionInfoRec intel_options[] = {
 	{OPTION_DEBUG_FLUSH_CACHES, "DebugFlushCaches", OPTV_BOOLEAN, {0}, 0},
 	{OPTION_DEBUG_WAIT, "DebugWait", OPTV_BOOLEAN, {0}, 0},
 	{OPTION_BUFFER_CACHE,	"BufferCache",	OPTV_BOOLEAN,   {0},    1},
-	{OPTION_TRIPLE_BUFFER,	"TripleBuffer", OPTV_BOOLEAN,	{0},	1},
 #endif
 	{-1,			NULL,		OPTV_NONE,	{0},	0}
 };
diff --git a/src/intel_options.h b/src/intel_options.h
index 3b5262a..953fc9c 100644
--- a/src/intel_options.h
+++ b/src/intel_options.h
@@ -20,6 +20,7 @@ enum intel_options {
 	OPTION_TILING_2D,
 	OPTION_TILING_FB,
 	OPTION_SWAPBUFFERS_WAIT,
+	OPTION_TRIPLE_BUFFER,
 	OPTION_PREFER_OVERLAY,
 	OPTION_HOTPLUG,
 	OPTION_RELAXED_FENCING,
@@ -40,7 +41,6 @@ enum intel_options {
 	OPTION_DEBUG_FLUSH_CACHES,
 	OPTION_DEBUG_WAIT,
 	OPTION_BUFFER_CACHE,
-	OPTION_TRIPLE_BUFFER,
 #endif
 	NUM_OPTIONS,
 };
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 9b93ed9..8861fd9 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -200,6 +200,7 @@ struct sna {
 #define SNA_NO_FLIP		0x8
 #define SNA_TEAR_FREE		0x10
 #define SNA_FORCE_SHADOW	0x20
+#define SNA_TRIPLE_BUFFER	0x40
 
 	unsigned watch_flush;
 
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index c05e8b4..522549a 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1769,7 +1769,7 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 		if (info == NULL)
 			return false;
 
-		info->type = DRI2_FLIP_THROTTLE;
+		info->type = sna->flags & SNA_TRIPLE_BUFFER ? DRI2_FLIP_THROTTLE: DRI2_FLIP;
 
 		info->draw = draw;
 		info->client = client;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index fc80cf3..22770c7 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -504,6 +504,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 		sna->flags |= SNA_NO_DELAYED_FLUSH;
 	if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE))
 		sna->flags |= SNA_NO_WAIT;
+	if (xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE))
+		sna->flags |= SNA_TRIPLE_BUFFER;
 	if (has_pageflipping(sna)) {
 		if (xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, FALSE))
 			sna->flags |= SNA_TEAR_FREE;

commit 6593ad3fecb3d044ee5ca161176d8ecaa0b4126a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 14 23:48:00 2012 +0000

    sna/dri: Store and check size of front/back bo attached to a DRI2 drawable
    
    So that we can prevent feeding back a stale bo when the DRI2 client
    tries to swap an old buffer.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57212
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index e7e5e35..c05e8b4 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -100,7 +100,8 @@ struct sna_dri_frame_event {
 struct sna_dri_private {
 	PixmapPtr pixmap;
 	struct kgem_bo *bo;
-	unsigned long serial;
+	bool scanout;
+	uint32_t size;
 	int refcnt;
 };
 
@@ -241,12 +242,15 @@ sna_dri_create_buffer(DrawablePtr draw,
 	struct sna_dri_private *private;
 	PixmapPtr pixmap;
 	struct kgem_bo *bo;
+	unsigned flags = CREATE_EXACT;
+	uint32_t size;
 	int bpp;
 
 	DBG(("%s(attachment=%d, format=%d, drawable=%dx%d)\n",
 	     __FUNCTION__, attachment, format, draw->width, draw->height));
 
 	pixmap = NULL;
+	size = (uint32_t)draw->height << 16 | draw->width;
 	switch (attachment) {
 	case DRI2BufferFrontLeft:
 		pixmap = get_drawable_pixmap(draw);
@@ -279,6 +283,9 @@ sna_dri_create_buffer(DrawablePtr draw,
 		     __FUNCTION__,
 		     pixmap->drawable.width, pixmap->drawable.height,
 		     pixmap, pixmap->refcnt));
+		if (pixmap == sna->front)
+			flags |= CREATE_SCANOUT;
+		size = (uint32_t)pixmap->drawable.height << 16 | pixmap->drawable.width;
 		break;
 
 	case DRI2BufferBackLeft:
@@ -287,12 +294,15 @@ sna_dri_create_buffer(DrawablePtr draw,
 	case DRI2BufferFakeFrontLeft:
 	case DRI2BufferFakeFrontRight:
 		bpp = draw->bitsPerPixel;
+		if (draw->width  == sna->front->drawable.width &&
+		    draw->height == sna->front->drawable.height)
+			flags |= CREATE_SCANOUT;
 		bo = kgem_create_2d(&sna->kgem,
 				    draw->width,
 				    draw->height,
 				    draw->bitsPerPixel,
 				    color_tiling(sna, draw),
-				    CREATE_SCANOUT | CREATE_EXACT);
+				    flags);
 		break;
 
 	case DRI2BufferStencil:
@@ -323,7 +333,7 @@ sna_dri_create_buffer(DrawablePtr draw,
 		bo = kgem_create_2d(&sna->kgem,
 				    ALIGN(draw->width, 64),
 				    ALIGN((draw->height + 1) / 2, 64),
-				    bpp, I915_TILING_NONE, CREATE_EXACT);
+				    bpp, I915_TILING_NONE, flags);
 		break;
 
 	case DRI2BufferDepth:
@@ -334,7 +344,7 @@ sna_dri_create_buffer(DrawablePtr draw,
 		bo = kgem_create_2d(&sna->kgem,
 				    draw->width, draw->height, bpp,
 				    other_tiling(sna, draw),
-				    CREATE_EXACT);
+				    flags);
 		break;
 
 	default:
@@ -358,7 +368,8 @@ sna_dri_create_buffer(DrawablePtr draw,
 	private->refcnt = 1;
 	private->bo = bo;
 	private->pixmap = pixmap;
-	private->serial = get_drawable_pixmap(draw)->drawable.serialNumber;
+	private->scanout = !!(flags & CREATE_SCANOUT);
+	private->size = size;
 
 	if (buffer->name == 0)
 		goto err;
@@ -825,14 +836,14 @@ can_blit(struct sna * sna,
 	 DRI2BufferPtr front,
 	 DRI2BufferPtr back)
 {
-	PixmapPtr pixmap;
+	uint32_t f, b;
 
 	if (draw->type == DRAWABLE_PIXMAP)
 		return true;
 
-	pixmap = get_drawable_pixmap(draw);
-	return (get_private(front)->serial == pixmap->drawable.serialNumber &&
-		get_private(back)->serial  == pixmap->drawable.serialNumber);
+	f = get_private(front)->size;
+	b = get_private(back)->size;
+	return (f >> 16) >= (b >> 16) && (f & 0xffff) >= (b & 0xffff);
 }
 
 static void
@@ -1097,16 +1108,19 @@ can_flip(struct sna * sna,
 		return false;
 	}
 
+	if (!get_private(front)->scanout) {
+		DBG(("%s: no, DRI2 drawable not attached at time of creation)\n",
+		     __FUNCTION__));
+		return false;
+	}
 	assert(get_private(front)->pixmap == sna->front);
-	assert(get_private(front)->serial == pixmap->drawable.serialNumber);
 
-	if (get_private(back)->serial != pixmap->drawable.serialNumber) {
-		DBG(("%s: no, DRI2 drawable has a stale reference to the pixmap (DRI2 pixmap=%ld, X pixmap=%ld)\n",
-		     __FUNCTION__,
-		     get_private(back)->serial,
-		     pixmap->drawable.serialNumber));
+	if (!get_private(back)->scanout) {
+		DBG(("%s: no, DRI2 drawable was too small at time of creation)\n",
+		     __FUNCTION__));
 		return false;
 	}
+	assert(get_private(back)->size == get_private(front)->size);
 
 	DBG(("%s: window size: %dx%d, clip=(%d, %d), (%d, %d) x %d\n",
 	     __FUNCTION__,
@@ -1203,14 +1217,19 @@ can_exchange(struct sna * sna,
 		return false;
 	}
 
-	assert(get_private(front)->serial == pixmap->drawable.serialNumber);
-	if (get_private(back)->serial != pixmap->drawable.serialNumber) {
-		DBG(("%s: no, DRI2 drawable has a stale reference to the pixmap (DRI2 pixmap=%ld, X pixmap=%ld)\n",
-		     __FUNCTION__,
-		     get_private(back)->serial,
-		     pixmap->drawable.serialNumber));
+	if (!get_private(front)->scanout) {
+		DBG(("%s: no, DRI2 drawable not attached at time of creation)\n",
+		     __FUNCTION__));
+		return false;
+	}
+	assert(get_private(front)->pixmap == sna->front);
+
+	if (!get_private(back)->scanout) {
+		DBG(("%s: no, DRI2 drawable was too small at time of creation)\n",
+		     __FUNCTION__));
 		return false;
 	}
+	assert(get_private(back)->size == get_private(front)->size);
 
 	return true;
 }

commit 9df9585cb00958b42461b3139bb7aec32090a869
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 14 15:37:56 2012 +0000

    sna: Reduce fence watermarks
    
    Further restrict the amount of fenced bo we try to fit into the batch to
    make it easier for the kernel to accommodate the request.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f8b3cff..66bf473 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3906,9 +3906,12 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 			if (kgem->nfence >= kgem->fence_max)
 				return false;
 
+			if (3*kgem->aperture_fenced > kgem->aperture_mappable)
+				return false;
+
 			size = kgem->aperture_fenced;
 			size += kgem_bo_fenced_size(kgem, bo);
-			if (4*size > 3*kgem->aperture_mappable)
+			if (3*size > 2*kgem->aperture_mappable)
 				return false;
 		}
 
@@ -3932,12 +3935,12 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 		if (kgem->nfence >= kgem->fence_max)
 			return false;
 
-		if (2*kgem->aperture_fenced > kgem->aperture_mappable)
+		if (3*kgem->aperture_fenced > kgem->aperture_mappable)
 			return false;
 
 		size = kgem->aperture_fenced;
 		size += kgem_bo_fenced_size(kgem, bo);
-		if (4*size > 3*kgem->aperture_mappable)
+		if (3*size > 2*kgem->aperture_mappable)
 			return false;
 	}
 
@@ -3982,10 +3985,10 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 		if (kgem->nfence + num_fence > kgem->fence_max)
 			return false;
 
-		if (2*kgem->aperture_fenced > kgem->aperture_mappable)
+		if (3*kgem->aperture_fenced > kgem->aperture_mappable)
 			return false;
 
-		if (4*(fenced_size + kgem->aperture_fenced) > 3*kgem->aperture_mappable)
+		if (3*(fenced_size + kgem->aperture_fenced) > 2*kgem->aperture_mappable)
 			return false;
 	}
 

commit 0d3ba44e448c152a570cc469d289ab057fa7be5c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 14 12:47:46 2012 +0000

    sna/gen2+: Experiment with not forcing migration to GPU after CPU rasterisation
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index c4242f4..8f92338 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1716,7 +1716,7 @@ gen2_composite_fallback(struct sna *sna,
 
 	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
 	     __FUNCTION__));
-	return false;
+	return dst_use_cpu(dst_pixmap);
 }
 
 static int
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 5c17a8f..b9a1e01 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2676,9 +2676,9 @@ gen3_composite_fallback(struct sna *sna,
 
 	if (mask &&
 	    mask->componentAlpha && PICT_FORMAT_RGB(mask->format) &&
-	    op != PictOpOver &&
-	    gen3_blend_op[op].src_blend != BLENDFACT_ZERO)
-	{
+	    gen3_blend_op[op].src_alpha &&
+	    gen3_blend_op[op].src_blend != BLENDFACT_ZERO &&
+	    op != PictOpOver) {
 		DBG(("%s: component-alpha mask with op=%d, should fallback\n",
 		     __FUNCTION__, op));
 		return true;
@@ -2725,9 +2725,9 @@ gen3_composite_fallback(struct sna *sna,
 		return true;
 	}
 
-	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
-	     __FUNCTION__));
-	return false;
+	DBG(("%s: dst is not on the GPU and the operation should not fallback: use-cpu? %d\n",
+	     __FUNCTION__, dst_use_cpu(dst_pixmap)));
+	return dst_use_cpu(dst_pixmap);
 }
 
 static int
@@ -2916,7 +2916,7 @@ gen3_render_composite(struct sna *sna,
 					tmp->mask.u.gen3.type = SHADER_NONE;
 					tmp->has_component_alpha = false;
 				} else if (gen3_blend_op[op].src_alpha &&
-					   (gen3_blend_op[op].src_blend != BLENDFACT_ZERO)) {
+					   gen3_blend_op[op].src_blend != BLENDFACT_ZERO) {
 					if (op != PictOpOver)
 						goto cleanup_mask;
 
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index f80fa83..27cf975 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2247,7 +2247,7 @@ gen4_composite_fallback(struct sna *sna,
 
 	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
 	     __FUNCTION__));
-	return false;
+	return dst_use_cpu(dst_pixmap);
 }
 
 static int
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 6e6389a..9b779b6 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2256,7 +2256,7 @@ gen5_composite_fallback(struct sna *sna,
 
 	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
 	     __FUNCTION__));
-	return false;
+	return dst_use_cpu(dst_pixmap);
 }
 
 static int
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 801236f..ec29124 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2604,7 +2604,7 @@ gen6_composite_fallback(struct sna *sna,
 
 	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
 	     __FUNCTION__));
-	return false;
+	return dst_use_cpu(dst_pixmap);
 }
 
 static int
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 270488c..29b1cdc 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2721,7 +2721,7 @@ gen7_composite_fallback(struct sna *sna,
 
 	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
 	     __FUNCTION__));
-	return false;
+	return dst_use_cpu(dst_pixmap);
 }
 
 static int
diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 2468b89..e31db15 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -233,6 +233,15 @@ inline static bool dst_use_gpu(PixmapPtr pixmap)
 	return priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo);
 }
 
+inline static bool dst_use_cpu(PixmapPtr pixmap)
+{
+	struct sna_pixmap *priv = sna_pixmap(pixmap);
+	if (priv == NULL)
+		return true;
+
+	return priv->cpu_damage && priv->cpu;
+}
+
 inline static bool dst_is_cpu(PixmapPtr pixmap)
 {
 	struct sna_pixmap *priv = sna_pixmap(pixmap);

commit d867fd01cb0060342102a79600daf43e3dc44a07
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 14 13:10:54 2012 +0000

    sna/gen3: Don't combine primitives if beginning a ca 2-pass
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 8f8cef2..5c17a8f 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1768,7 +1768,8 @@ static bool gen3_rectangle_begin(struct sna *sna,
 		}
 	}
 
-	if (sna->kgem.nbatch == 2 + state->last_vertex_offset) {
+	if (sna->kgem.nbatch == 2 + state->last_vertex_offset &&
+	    !op->need_magic_ca_pass) {
 		state->vertex_offset = state->last_vertex_offset;
 	} else {
 		state->vertex_offset = sna->kgem.nbatch;

commit 3ca503dac2ea6c036e7ebe878b41923541daf225
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 14 12:49:14 2012 +0000

    sna/gen3: Remove stray setting of vertex_start
    
    It is always done at the beginning of vertex emission.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 51ace78..8f8cef2 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2921,7 +2921,6 @@ gen3_render_composite(struct sna *sna,
 
 					tmp->need_magic_ca_pass = true;
 					tmp->op = PictOpOutReverse;
-					sna->render.vertex_start = sna->render.vertex_index;
 				}
 			} else {
 				if (tmp->mask.is_opaque) {

commit 7f76f100e8033497620ee46548df45afff41064a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 23:12:42 2012 +0000

    sna/gen2: Reorder reuse_source() to avoid NULL dereference for solids
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index a059967..c4242f4 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1729,6 +1729,12 @@ reuse_source(struct sna *sna,
 	if (src_x != msk_x || src_y != msk_y)
 		return false;
 
+	if (sna_picture_is_solid(mask, &color))
+		return gen2_composite_solid_init(sna, mc, color);
+
+	if (sc->is_solid)
+		return false;
+
 	if (src == mask) {
 		DBG(("%s: mask is source\n", __FUNCTION__));
 		*mc = *sc;
@@ -1736,12 +1742,6 @@ reuse_source(struct sna *sna,
 		return true;
 	}
 
-	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;
 

commit 044a54c23384756a5dc1895473abf34f7abb3d83
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 23:05:30 2012 +0000

    sna/gen2: Initialise channel->is_affine for solid
    
    In case we hit a path were we avoid reusing the source for the mask and
    leave is_affine unset for a solid mask.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index afc71af..a059967 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1161,6 +1161,7 @@ gen2_composite_solid_init(struct sna *sna,
 	channel->filter = PictFilterNearest;
 	channel->repeat = RepeatNormal;
 	channel->is_solid  = true;
+	channel->is_affine = true;
 	channel->width  = 1;
 	channel->height = 1;
 	channel->pict_format = PICT_a8r8g8b8;

commit 29afd0dc8e893cc4110ee0d70546775dae86ddb3
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 22:53:18 2012 +0000

    sna/gen2: Assertions
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index d0272bf..afc71af 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1050,6 +1050,7 @@ inline static int gen2_get_rectangles(struct sna *sna,
 		if ((sna->kgem.batch[sna->kgem.nbatch-1] & ~0xffff) ==
 		    (PRIM3D_INLINE | PRIM3D_RECTLIST)) {
 			uint32_t *b = &sna->kgem.batch[sna->kgem.nbatch-1];
+			assert(*b & 0xffff);
 			sna->render.vertex_index = 1 + (*b & 0xffff);
 			*b = PRIM3D_INLINE | PRIM3D_RECTLIST;
 			state->vertex_offset = sna->kgem.nbatch - 1;
@@ -1885,7 +1886,7 @@ gen2_render_composite(struct sna *sna,
 					DBG(("%s: fallback -- unsupported CA blend (src_blend=%d)\n",
 					     __FUNCTION__,
 					     gen2_blend_op[op].src_blend));
-					goto cleanup_dst;
+					goto cleanup_src;
 				}
 
 				tmp->need_magic_ca_pass = true;
@@ -1894,8 +1895,12 @@ gen2_render_composite(struct sna *sna,
 		}
 
 		/* convert solid to a texture (pure convenience) */
-		if (tmp->mask.is_solid && tmp->src.is_solid)
+		if (tmp->mask.is_solid && tmp->src.is_solid) {
+			assert(tmp->mask.is_affine);
 			tmp->mask.bo = sna_render_get_solid(sna, tmp->mask.u.gen2.pixel);
+			if (!tmp->mask.bo)
+				goto cleanup_src;
+		}
 	}
 
 	tmp->floats_per_vertex = 2;
@@ -1908,18 +1913,25 @@ gen2_render_composite(struct sna *sna,
 	tmp->prim_emit = gen2_emit_composite_primitive;
 	if (tmp->mask.bo) {
 		if (tmp->mask.transform == NULL) {
-			if (tmp->src.is_solid)
+			if (tmp->src.is_solid) {
+				assert(tmp->floats_per_rect == 12);
 				tmp->prim_emit = gen2_emit_composite_primitive_constant_identity_mask;
+			}
 		}
 	} else {
-		if (tmp->src.is_solid)
+		if (tmp->src.is_solid) {
+			assert(tmp->floats_per_rect == 6);
 			tmp->prim_emit = gen2_emit_composite_primitive_constant;
-		else if (tmp->src.is_linear)
+		} else if (tmp->src.is_linear) {
+			assert(tmp->floats_per_rect == 12);
 			tmp->prim_emit = gen2_emit_composite_primitive_linear;
-		else if (tmp->src.transform == NULL)
+		} else if (tmp->src.transform == NULL) {
+			assert(tmp->floats_per_rect == 12);
 			tmp->prim_emit = gen2_emit_composite_primitive_identity;
-		else if (tmp->src.is_affine)
+		} else if (tmp->src.is_affine) {
+			assert(tmp->floats_per_rect == 12);
 			tmp->prim_emit = gen2_emit_composite_primitive_affine;
+		}
 	}
 
 	tmp->blt   = gen2_render_composite_blt;

commit 4d2abe1e3daac74747535d88dff34b024b87bbe9
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 22:09:37 2012 +0000

    sna/gen3: Remove incorrect optimisation of an opaque source for CA
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index f203e7e..51ace78 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -929,13 +929,6 @@ gen3_composite_emit_shader(struct sna *sna,
 	if (mask->u.gen3.type == SHADER_NONE)
 		mask = NULL;
 
-	if (mask && src->is_opaque &&
-	    gen3_blend_op[blend].src_alpha &&
-	    op->has_component_alpha) {
-		src = mask;
-		mask = NULL;
-	}
-
 	id = (src->u.gen3.type |
 	      src->is_affine << 4 |
 	      src->alpha_fixup << 5 |

commit d428dbf7ad7c246acb1c301b73b9df4a1309de03
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 14:53:50 2012 +0000

    sna/gen2: Program solid mask using the DIFFUSE component
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 825f78c..d0272bf 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -396,6 +396,15 @@ gen2_get_blend_factors(const struct sna_composite_op *op,
 
 		cblend |= TB0C_OP_MODULATE;
 		ablend |= TB0A_OP_MODULATE;
+	} else if (op->mask.is_solid) {
+		cblend |= TB0C_ARG2_SEL_DIFFUSE;
+		ablend |= TB0A_ARG2_SEL_DIFFUSE;
+
+		if (op->dst.format == PICT_a8 || !op->has_component_alpha)
+			cblend |= TB0C_ARG2_REPLICATE_ALPHA;
+
+		cblend |= TB0C_OP_MODULATE;
+		ablend |= TB0A_OP_MODULATE;
 	} else {
 		cblend |= TB0C_OP_ARG1;
 		ablend |= TB0A_OP_ARG1;
@@ -727,6 +736,12 @@ static void gen2_emit_composite_state(struct sna *sna,
 		else
 			texcoordfmt |= TEXCOORDFMT_3D << (2*tex);
 		gen2_emit_texture(sna, &op->mask, tex++);
+	} else if (op->mask.is_solid) {
+		if (op->mask.u.gen2.pixel != sna->render_state.gen2.diffuse) {
+			BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
+			BATCH(op->mask.u.gen2.pixel);
+			sna->render_state.gen2.diffuse = op->mask.u.gen2.pixel;
+		}
 	}
 
 	v = _3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt;
@@ -1879,7 +1894,7 @@ gen2_render_composite(struct sna *sna,
 		}
 
 		/* convert solid to a texture (pure convenience) */
-		if (tmp->mask.is_solid)
+		if (tmp->mask.is_solid && tmp->src.is_solid)
 			tmp->mask.bo = sna_render_get_solid(sna, tmp->mask.u.gen2.pixel);
 	}
 

commit 9e7311516da81ab45484b291ec668503c5ded0bb
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 14:40:25 2012 +0000

    sna/gen2: Align surface sizes to an even tile
    
    Makes this 855gm much happier.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index d501115..f8b3cff 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1223,10 +1223,10 @@ static uint32_t kgem_surface_size(struct kgem *kgem,
 		if (tiling) {
 			if (kgem->gen < 030) {
 				tile_width = 128;
-				tile_height = 16;
+				tile_height = 32;
 			} else {
 				tile_width = 512;
-				tile_height =  8;
+				tile_height = 16;
 			}
 		} else {
 			tile_width = 2 * bpp >> 3;
@@ -1292,12 +1292,12 @@ static uint32_t kgem_aligned_height(struct kgem *kgem,
 	uint32_t tile_height;
 
 	if (kgem->gen <= 030) {
-		tile_height = tiling ? kgem->gen < 030 ? 16 : 8 : 1;
+		tile_height = tiling ? kgem->gen < 030 ? 32 : 16 : 1;
 	} else switch (tiling) {
 		/* XXX align to an even tile row */
 	default:
 	case I915_TILING_NONE:
-		tile_height = 2;
+		tile_height = 1;
 		break;
 	case I915_TILING_X:
 		tile_height = 16;

commit e646047a563598948206167765eaaf4192cfd77f
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 14:23:54 2012 +0000

    sna: Fix up BLT overwrite detection to use target_handle
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index e9ca0dd..fb560d5 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -433,7 +433,7 @@ static void sna_blt_copy_one(struct sna *sna,
 	    kgem->batch[kgem->nbatch-6] == (XY_COLOR_BLT | (blt->cmd & (BLT_WRITE_ALPHA | BLT_WRITE_RGB))) &&
 	    kgem->batch[kgem->nbatch-4] == ((uint32_t)dst_y << 16 | (uint16_t)dst_x) &&
 	    kgem->batch[kgem->nbatch-3] == ((uint32_t)(dst_y+height) << 16 | (uint16_t)(dst_x+width)) &&
-	    kgem->reloc[kgem->nreloc-1].target_handle == blt->bo[1]->handle) {
+	    kgem->reloc[kgem->nreloc-1].target_handle == blt->bo[1]->target_handle) {
 		DBG(("%s: replacing last fill\n", __FUNCTION__));
 		if (kgem_check_batch(kgem, 8-6)) {
 			b = kgem->batch + kgem->nbatch - 6;
@@ -2231,7 +2231,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	if (overwrites && kgem->nbatch >= 6 &&
 	    kgem->batch[kgem->nbatch-6] == cmd &&
 	    *(uint64_t *)&kgem->batch[kgem->nbatch-4] == *(const uint64_t *)box &&
-	    kgem->reloc[kgem->nreloc-1].target_handle == bo->handle) {
+	    kgem->reloc[kgem->nreloc-1].target_handle == bo->target_handle) {
 		DBG(("%s: replacing last fill\n", __FUNCTION__));
 		kgem->batch[kgem->nbatch-5] = br13;
 		kgem->batch[kgem->nbatch-1] = color;
@@ -2240,7 +2240,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	if (overwrites && kgem->nbatch >= 8 &&
 	    (kgem->batch[kgem->nbatch-8] & 0xffc0000f) == XY_SRC_COPY_BLT_CMD &&
 	    *(uint64_t *)&kgem->batch[kgem->nbatch-6] == *(const uint64_t *)box &&
-	    kgem->reloc[kgem->nreloc-2].target_handle == bo->handle) {
+	    kgem->reloc[kgem->nreloc-2].target_handle == bo->target_handle) {
 		DBG(("%s: replacing last copy\n", __FUNCTION__));
 		kgem->batch[kgem->nbatch-8] = cmd;
 		kgem->batch[kgem->nbatch-7] = br13;
@@ -2503,7 +2503,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 	/* Compare first box against a previous fill */
 	if (kgem->nbatch >= 6 &&
 	    (alu == GXcopy || alu == GXclear || alu == GXset) &&
-	    kgem->reloc[kgem->nreloc-1].target_handle == dst_bo->handle &&
+	    kgem->reloc[kgem->nreloc-1].target_handle == dst_bo->target_handle &&
 	    kgem->batch[kgem->nbatch-6] == ((cmd & ~XY_SRC_COPY_BLT_CMD) | XY_COLOR_BLT) &&
 	    kgem->batch[kgem->nbatch-4] == ((uint32_t)(box->y1 + dst_dy) << 16 | (uint16_t)(box->x1 + dst_dx)) &&
 	    kgem->batch[kgem->nbatch-3] == ((uint32_t)(box->y2 + dst_dy) << 16 | (uint16_t)(box->x2 + dst_dx))) {

commit 4f96439e39a4bf4b127af9ccfdc09d061caff9bd
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 13:15:52 2012 +0000

    sna: Fix typo for 830/845 gen
    
    Must remember, its octal not decimal.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 90594cf..d501115 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2368,7 +2368,7 @@ kgem_create_batch(struct kgem *kgem, int size)
 		}
 	}
 
-	if (kgem->gen == 20) {
+	if (kgem->gen == 020) {
 		assert(size <= 16384);
 
 		bo = list_first_entry(&kgem->pinned_batches[size > 4096],

commit f631a56bcb3ff1ce1942b828325a157cef1e0880
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 13 00:55:45 2012 +0000

    sna: Only flush the batch after an actual relocation
    
    As we may write preparatory instructions into the batch before checking
    for a flush.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 5c9cd14..2d90cf3 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -347,7 +347,7 @@ static inline void kgem_set_mode(struct kgem *kgem,
 	kgem_submit(kgem);
 #endif
 
-	if (kgem->mode && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring))
+	if (kgem->nexec && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring))
 		kgem_submit(kgem);
 
 	if (kgem->mode == mode)

commit 74bbf20e6e652cba55d6d0bc17066f4112f8548c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Dec 12 21:56:22 2012 +0000

    sna: Improve the initialisation failure path for pinned batches
    
    Simplify the later checks by always populating the lists with a single,
    albeit unpinned, bo in the case we fail to create pinned batches.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f1682da..90594cf 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -869,7 +869,6 @@ static bool kgem_init_pinned_batches(struct kgem *kgem)
 			bo->presumed_offset = pin.offset;


Reply to: