xf86-video-intel: 8 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_dri.c src/sna/sna_glyphs.c src/sna/sna_gradient.c src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 20 05:35:16 PDT 2011


 src/sna/kgem.c         |   40 +++++----
 src/sna/kgem.h         |   13 ---
 src/sna/sna_accel.c    |   32 ++++++-
 src/sna/sna_blt.c      |  208 ++++++++++++++++++++++++++++++++++++++-----------
 src/sna/sna_dri.c      |   19 +++-
 src/sna/sna_glyphs.c   |    5 -
 src/sna/sna_gradient.c |    6 -
 src/sna/sna_io.c       |    2 
 8 files changed, 238 insertions(+), 87 deletions(-)

New commits:
commit 3526d83e460ce6410f23f59d1315793ff9607253
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 20 00:29:52 2011 +0100

    sna/dri: Perform a little dance to restore the gpu status on release of the bo
    
    As the bo is outside of our control whilst it is under the influence of
    an external renderer, we try to maintain it on the gpu so as to avoid
    unnecessary ping-pong. But once it is wholly back under our control, we
    want to stop paying the penalty for sharing 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 ed0e12f..d5084f8 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -105,7 +105,6 @@ static void kgem_sna_flush(struct kgem *kgem)
 		sna_render_flush_solid(sna);
 }
 
-
 static int gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
 {
 	struct drm_i915_gem_set_tiling set_tiling;
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index ae4f1fa..65fec47 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -153,8 +153,9 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 		list_add(&priv->list, &sna->dirty_pixmaps);
 
 	/* The bo is outside of our control, so presume it is written to */
-	priv->gpu_bo->needs_flush = 1;
+	priv->gpu_bo->needs_flush = true;
 	priv->gpu_bo->reusable = false;
+	priv->gpu_bo->gpu = true;
 
 	/* We need to submit any modifications to and reads from this
 	 * buffer before we send any reply to the Client.
@@ -317,8 +318,18 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 	struct sna_dri_private *private = buffer->driverPrivate;
 
 	if (--private->refcnt == 0) {
+		private->bo->gpu = private->bo->needs_flush || private->bo->rq != NULL;
+		private->bo->flush = 0;
+
 		if (private->pixmap) {
 			ScreenPtr screen = private->pixmap->drawable.pScreen;
+			struct sna_pixmap *priv = sna_pixmap(private->pixmap);
+
+			/* Undo the DRI markings on this pixmap */
+			list_del(&priv->list);
+			priv->pinned = private->pixmap == sna->front;
+			priv->flush = 0;
+
 			screen->DestroyPixmap(private->pixmap);
 		} else
 			kgem_bo_destroy(&sna->kgem, private->bo);
commit 50b980f12e02401cdd4bc21b970d92e7bd1e6459
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 21:09:01 2011 +0100

    sna: Reuse any partial write buffer for readback
    
    Take advantage of any available temporary buffer that we reuse for
    readback knowing that it is the last operation in the batch.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 073fed7..ed0e12f 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1944,6 +1944,16 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 	     __FUNCTION__, size, flags, write, flags & KGEM_BUFFER_LAST));
 
 	list_for_each_entry(bo, &kgem->partial, base.list) {
+		if (flags == KGEM_BUFFER_LAST && bo->write) {
+			/* We can reuse any write buffer which we can fit */
+			if (size < bo->alloc) {
+				DBG(("%s: reusing write buffer for read of %d bytes? used=%d, total=%d\n",
+				     __FUNCTION__, size, bo->used, bo->alloc));
+				offset = 0;
+				goto done;
+			}
+		}
+
 		if (bo->write != write) {
 			DBG(("%s: skip write %d buffer, need %d\n",
 			     __FUNCTION__, bo->write, write));
@@ -2133,31 +2143,25 @@ cleanup_bo:
 	return NULL;
 }
 
-void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *_bo)
+void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
 {
 	struct kgem_partial_bo *bo;
+	uint32_t offset = _bo->delta, length = _bo->size;
 
 	if (_bo->proxy)
 		_bo = _bo->proxy;
 
 	bo = (struct kgem_partial_bo *)_bo;
 
-	DBG(("%s(need_io=%s, sync=%d)\n", __FUNCTION__,
-	     bo->need_io ? bo->write ? "write" : "read" : "none",
-	     bo->base.sync));
+	DBG(("%s(offset=%d, length=%d, sync=%d)\n", __FUNCTION__,
+	     offset, length, bo->base.sync));
 
-	if (bo->need_io) {
-		if (bo->write)
-			gem_write(kgem->fd, bo->base.handle,
-				  0, bo->used, bo+1);
-		else
-			gem_read(kgem->fd, bo->base.handle, bo+1, bo->used);
+	if (!bo->base.sync) {
+		gem_read(kgem->fd, bo->base.handle,
+			 (char *)(bo+1)+offset, length);
 		bo->base.needs_flush = false;
 		if (bo->base.gpu)
 			kgem_retire(kgem);
-		bo->need_io = 0;
-	}
-
-	if (bo->base.sync)
-		kgem_bo_sync(kgem, &bo->base, bo->write);
+	} else
+		kgem_bo_sync(kgem, &bo->base, false);
 }
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 60a23de..eb89c63 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -330,7 +330,7 @@ void kgem_bo_sync(struct kgem *kgem, struct kgem_bo *bo, bool for_write);
 struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 				   uint32_t size, uint32_t flags,
 				   void **ret);
-void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *bo);
+void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
 
 void kgem_throttle(struct kgem *kgem);
 bool kgem_expire_cache(struct kgem *kgem);
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 321247a..5a6fdd9 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -202,7 +202,7 @@ void sna_read_boxes(struct sna *sna,
 	} while (tmp_nbox);
 	assert(offset == dst_bo->size);
 
-	kgem_buffer_sync(kgem, dst_bo);
+	kgem_buffer_read_sync(kgem, dst_bo);
 
 	src = ptr;
 	do {
commit 972989276dd3f84c1cedca0494d04f907875f8f3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 20:41:14 2011 +0100

    sna: Add some debug to discern the nature of the Cr fallback
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 07132bf..22f5468 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2233,13 +2233,20 @@ sna_poly_line_can_blt(int mode, int n, DDXPointPtr pt)
 
 	if (mode == CoordModePrevious) {
 		for (i = 1; i < n; i++) {
-			if (pt[i].x != 0 && pt[i].y != 0)
+			if (pt[i].x != 0 && pt[i].y != 0) {
+				DBG(("%s: diagonal segment[%d]=(%d,%d)\n",
+				     __FUNCTION__, i, pt[i].x, pt[i].y));
 				return FALSE;
+			}
 		}
 	} else {
 		for (i = 1; i < n; i++) {
-			if (pt[i].x != pt[i-1].x && pt[i].y != pt[i-1].y)
+			if (pt[i].x != pt[i-1].x && pt[i].y != pt[i-1].y) {
+				DBG(("%s: diagonal segment[%d]=(%d,%d)->(%d,%d)\n",
+				     __FUNCTION__, i,
+				     pt[i-1].x, pt[i-1].y, pt[i].x, pt[i].y));
 				return FALSE;
+			}
 		}
 	}
 
@@ -2412,6 +2419,13 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 		goto fallback;
 	}
 
+	DBG(("%s: fill=%d [%d], line=%d [%d], width=%d, mask=%lu [%d], rectlinear=%d\n",
+	     __FUNCTION__,
+	     gc->fillStyle, gc->fillStyle == FillSolid,
+	     gc->lineStyle, gc->lineStyle == LineSolid,
+	     gc->lineWidth,
+	     gc->planemask, PM_IS_SOLID(drawable, gc->planemask),
+	     sna_poly_line_can_blt(mode, n, pt)));
 	if (gc->fillStyle == FillSolid &&
 	    gc->lineStyle == LineSolid &&
 	    (gc->lineWidth == 0 || gc->lineWidth == 1) &&
@@ -2482,8 +2496,11 @@ static Bool
 sna_poly_segment_can_blt(int n, xSegment *seg)
 {
 	while (n--) {
-		if (seg->x1 != seg->x2 && seg->y1 != seg->y2)
+		if (seg->x1 != seg->x2 && seg->y1 != seg->y2) {
+			DBG(("%s: (%d, %d) -> (%d, %d)\n",
+			     __FUNCTION__, seg->x1, seg->y1, seg->x2, seg->y2));
 			return FALSE;
+		}
 
 		seg++;
 	}
@@ -2718,9 +2735,16 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 		goto fallback;
 	}
 
+	DBG(("%s: fill=%d [%d], line=%d [%d], width=%d, mask=%lu [%d], rectlinear=%d\n",
+	     __FUNCTION__,
+	     gc->fillStyle, gc->fillStyle == FillSolid,
+	     gc->lineStyle, gc->lineStyle == LineSolid,
+	     gc->lineWidth,
+	     gc->planemask, PM_IS_SOLID(drawable, gc->planemask),
+	     sna_poly_segment_can_blt(n, seg)));
 	if (gc->fillStyle == FillSolid &&
 	    gc->lineStyle == LineSolid &&
-	    gc->lineWidth == 0 &&
+	    (gc->lineWidth == 0 || gc->lineWidth == 1) &&
 	    PM_IS_SOLID(drawable, gc->planemask) &&
 	    sna_poly_segment_can_blt(n, seg)) {
 		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
commit fc224e2f8c0200c114f8dbddfc4f5395a3ef0fad
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 20:20:55 2011 +0100

    sna: Clean up some debug messages for 64bit
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 82cec08..ae4f1fa 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -630,7 +630,7 @@ sna_dri_frame_event_drawable_gone(void *data, XID id)
 					 drawable_resource);
 
 		DBG(("%s: marking drawable gone [%p]: %ld\n",
-		     __FUNCTION__, info, info->drawable_id));
+		     __FUNCTION__, info, (long)info->drawable_id));
 
 		list_del(&info->drawable_resource);
 		info->drawable_id = None;
@@ -696,7 +696,7 @@ sna_dri_add_frame_event(struct sna_dri_frame_event *info)
 	list_add(&info->drawable_resource, resource);
 
 	DBG(("%s: add[%p] (%p, %ld)\n", __FUNCTION__,
-	     info, info->client, info->drawable_id));
+	     info, info->client, (long)info->drawable_id));
 
 	return TRUE;
 }
@@ -705,7 +705,7 @@ static void
 sna_dri_frame_event_info_free(struct sna_dri_frame_event *info)
 {
 	DBG(("%s: del[%p] (%p, %ld)\n", __FUNCTION__,
-	     info, info->client, info->drawable_id));
+	     info, info->client, (long)info->drawable_id));
 
 	list_del(&info->client_resource);
 	list_del(&info->drawable_resource);
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 13b0cca..928c9fb 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -973,8 +973,9 @@ glyphs_fallback(CARD8 op,
 		     region.extents.y2 - region.extents.y1,
 		     dst->pDrawable->x, dst->pDrawable->y,
 		     x, y,
-		     mask_format->depth, mask_format->format,
-		     mask_format->depth << 24 | mask_format->format,
+		     mask_format->depth,
+		     (long)mask_format->format,
+		     (long)(mask_format->depth << 24 | mask_format->format),
 		     NeedsComponent(mask_format->format)));
 		mask_image =
 			pixman_image_create_bits(mask_format->depth << 24 | mask_format->format,
commit f4346e5d255f419ee6148f7d69f02560732dd4de
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 19:26:19 2011 +0100

    sna/blt: Use SCANLINE_BLT for multiple fill boxes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 43e126b..60a23de 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -237,16 +237,7 @@ static inline void kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
 
 static inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
 {
-#if DEBUG_FLUSH_CACHE
-	kgem_emit_flush(kgem);
-#endif
-
-#if DEBUG_FLUSH_BATCH
-	kgem_submit(kgem);
-#endif
-
-	if (kgem->nbatch)
-		kgem->mode = mode;
+	kgem->mode = mode;
 }
 
 static inline bool kgem_check_batch(struct kgem *kgem, int num_dwords)
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 3b2c0b9..2343838 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -290,8 +290,10 @@ static Bool sna_blt_copy_init(struct sna *sna,
 	}
 
 	kgem_set_mode(kgem, KGEM_BLT);
-	if (!kgem_check_bo_fenced(kgem, src, dst, NULL))
+	if (!kgem_check_bo_fenced(kgem, src, dst, NULL)) {
 		_kgem_submit(kgem);
+		_kgem_set_mode(kgem, KGEM_BLT);
+	}
 
 	sna->blt_state.fill_bo = 0;
 	return TRUE;
@@ -340,8 +342,10 @@ static void sna_blt_copy_one(struct sna *sna,
 		return;
 	}
 
-	if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2))
+	if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2)) {
 		_kgem_submit(kgem);
+		_kgem_set_mode(kgem, KGEM_BLT);
+	}
 
 	b = kgem->batch + kgem->nbatch;
 	b[0] = blt->cmd;
@@ -821,8 +825,10 @@ prepare_blt_copy(struct sna *sna,
 	if (priv->gpu_bo->tiling == I915_TILING_Y)
 		return FALSE;
 
-	if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL))
+	if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL)) {
 		_kgem_submit(&sna->kgem);
+		_kgem_set_mode(&sna->kgem, KGEM_BLT);
+	}
 
 	DBG(("%s\n", __FUNCTION__));
 
@@ -1148,8 +1154,10 @@ sna_blt_composite(struct sna *sna,
 	if (width && height)
 		reduce_damage(tmp, dst_x, dst_y, width, height);
 
-	if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL))
+	if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL)) {
 		_kgem_submit(&sna->kgem);
+		_kgem_set_mode(&sna->kgem, KGEM_BLT);
+	}
 
 	if (op == PictOpClear)
 		return prepare_blt_clear(sna, tmp);
@@ -1349,26 +1357,20 @@ bool sna_blt_copy(struct sna *sna, uint8_t alu,
 	return TRUE;
 }
 
-Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
-			struct kgem_bo *bo, int bpp,
-			uint32_t color,
-			const BoxRec *box, int nbox)
+static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
+			     struct kgem_bo *bo, int bpp,
+			     uint32_t color,
+			     const BoxRec *box)
 {
 	struct kgem *kgem = &sna->kgem;
 	uint32_t br13, cmd;
+	uint32_t *b;
 
-#if DEBUG_NO_BLT || NO_BLT_FILL_BOXES
-	return FALSE;
-#endif
-
-	DBG(("%s (%d, %08x, %d) x %d\n",
-	     __FUNCTION__, bpp, color, alu, nbox));
+	DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__,
+	     box->x1, box->y1, box->x2, box->y2));
 
-	if (bo->tiling == I915_TILING_Y) {
-		DBG(("%s: fallback -- dst uses Y-tiling\n",
-		     __FUNCTION__));
-		return FALSE;
-	}
+	assert(box->x1 >= 0);
+	assert(box->y1 >= 0);
 
 	cmd = XY_COLOR_BLT_CMD;
 	if (bpp == 32)
@@ -1403,58 +1405,171 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 		DBG(("%s: replacing last fill\n", __FUNCTION__));
 		kgem->batch[kgem->nbatch-5] = br13;
 		kgem->batch[kgem->nbatch-1] = color;
-		if (--nbox == 0)
-			return TRUE;
-		box++;
+		return TRUE;
 	}
 
 	kgem_set_mode(kgem, KGEM_BLT);
 	if (!kgem_check_batch(kgem, 6) ||
 	    !kgem_check_reloc(kgem, 1) ||
-	    !kgem_check_bo_fenced(kgem, bo, NULL))
+	    !kgem_check_bo_fenced(kgem, bo, NULL)) {
+		_kgem_submit(kgem);
+		_kgem_set_mode(kgem, KGEM_BLT);
+	}
+
+	b = kgem->batch + kgem->nbatch;
+
+	b[0] = cmd;
+	b[1] = br13;
+	b[2] = box->y1 << 16 | box->x1;
+	b[3] = box->y2 << 16 | box->x2;
+	b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4,
+			      bo,
+			      I915_GEM_DOMAIN_RENDER << 16 |
+			      I915_GEM_DOMAIN_RENDER |
+			      KGEM_RELOC_FENCED,
+			      0);
+	b[5] = color;
+	kgem->nbatch += 6;
+
+	sna->blt_state.fill_bo = 0;
+	return TRUE;
+}
+
+Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
+			struct kgem_bo *bo, int bpp,
+			uint32_t pixel,
+			const BoxRec *box, int nbox)
+{
+	struct kgem *kgem = &sna->kgem;
+	uint32_t br13, cmd;
+
+#if DEBUG_NO_BLT || NO_BLT_FILL_BOXES
+	return FALSE;
+#endif
+
+	DBG(("%s (%d, %08x, %d) x %d\n",
+	     __FUNCTION__, bpp, pixel, alu, nbox));
+
+	if (bo->tiling == I915_TILING_Y) {
+		DBG(("%s: fallback -- dst uses Y-tiling\n", __FUNCTION__));
+		return FALSE;
+	}
+
+	if (nbox == 1)
+		return sna_blt_fill_box(sna, alu, bo, bpp, pixel, box);
+
+	br13 = bo->pitch;
+	cmd = XY_SCANLINE_BLT;
+	if (kgem->gen >= 40 && bo->tiling) {
+		cmd |= 1 << 11;
+		br13 >>= 2;
+	}
+	if (br13 > MAXSHORT)
+		return FALSE;
+
+	br13 |= 1<<31 | fill_ROP[alu] << 16;
+	switch (bpp) {
+	default: assert(0);
+	case 32: br13 |= 1 << 25; /* RGB8888 */
+	case 16: br13 |= 1 << 24; /* RGB565 */
+	case 8: break;
+	}
+
+	kgem_set_mode(kgem, KGEM_BLT);
+	if (!kgem_check_bo_fenced(kgem, bo, NULL) ||
+	    !kgem_check_batch(kgem, 12)) {
 		_kgem_submit(kgem);
+		_kgem_set_mode(kgem, KGEM_BLT);
+	}
+
+	if (sna->blt_state.fill_bo != bo->handle ||
+	    sna->blt_state.fill_pixel != pixel)
+	{
+		uint32_t *b;
+
+		if (!kgem_check_reloc(kgem, 1)) {
+			_kgem_submit(kgem);
+			_kgem_set_mode(kgem, KGEM_BLT);
+		}
+
+		b = kgem->batch + kgem->nbatch;
+		b[0] = XY_SETUP_MONO_PATTERN_SL_BLT;
+		if (bpp == 32)
+			b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+		b[1] = br13;
+		b[2] = 0;
+		b[3] = 0;
+		b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
+				      I915_GEM_DOMAIN_RENDER << 16 |
+				      I915_GEM_DOMAIN_RENDER |
+				      KGEM_RELOC_FENCED,
+				      0);
+		b[5] = pixel;
+		b[6] = pixel;
+		b[7] = 0;
+		b[8] = 0;
+		kgem->nbatch += 9;
+
+		sna->blt_state.fill_bo = bo->handle;
+		sna->blt_state.fill_pixel = pixel;
+	}
 
 	do {
 		int nbox_this_time;
 
 		nbox_this_time = nbox;
-		if (6*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-			nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 6;
-		if (nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
-			nbox_this_time = KGEM_RELOC_SIZE(kgem) - kgem->nreloc;
+		if (3*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+			nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 3;
 		assert(nbox_this_time);
 		nbox -= nbox_this_time;
 
 		do {
 			uint32_t *b = kgem->batch + kgem->nbatch;
 
-			DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__,
-			     box->x1, box->y1, box->x2, box->y2));
+			DBG(("%s: (%d, %d), (%d, %d): %08x\n",
+			     __FUNCTION__,
+			     box->x1, box->y1,
+			     box->x2, box->y2,
+			     pixel));
 
 			assert(box->x1 >= 0);
 			assert(box->y1 >= 0);
+			assert(box->y2 * bo->pitch <= bo->size);
 
+			b = kgem->batch + kgem->nbatch;
+			kgem->nbatch += 3;
 			b[0] = cmd;
+			b[1] = box->y1 << 16 | box->x1;
+			b[2] = box->y2 << 16 | box->x2;
+			box++;
+		} while (--nbox_this_time);
+
+		if (nbox) {
+			uint32_t *b;
+
+			_kgem_submit(kgem);
+			_kgem_set_mode(kgem, KGEM_BLT);
+
+			b = kgem->batch + kgem->nbatch;
+			b[0] = XY_SETUP_MONO_PATTERN_SL_BLT;
+			if (bpp == 32)
+				b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
 			b[1] = br13;
-			b[2] = box->y1 << 16 | box->x1;
-			b[3] = box->y2 << 16 | box->x2;
-			b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4,
-					      bo,
+			b[2] = 0;
+			b[3] = 0;
+			b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
 					      I915_GEM_DOMAIN_RENDER << 16 |
 					      I915_GEM_DOMAIN_RENDER |
 					      KGEM_RELOC_FENCED,
 					      0);
-			b[5] = color;
-			kgem->nbatch += 6;
-			box++;
-		} while (--nbox_this_time);
-
-		if (nbox)
-			_kgem_submit(kgem);
+			b[5] = pixel;
+			b[6] = pixel;
+			b[7] = 0;
+			b[8] = 0;
+			kgem->nbatch += 9;
+		}
 	} while (nbox);
 
-	_kgem_set_mode(kgem, KGEM_BLT);
-	sna->blt_state.fill_bo = 0;
 	return TRUE;
 }
 
@@ -1512,8 +1627,10 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 	kgem_set_mode(kgem, KGEM_BLT);
 	if (!kgem_check_batch(kgem, 8) ||
 	    !kgem_check_reloc(kgem, 2) ||
-	    !kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL))
+	    !kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL)) {
 		_kgem_submit(kgem);
+		_kgem_set_mode(kgem, KGEM_BLT);
+	}
 
 	do {
 		int nbox_this_time;
@@ -1561,8 +1678,10 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 			box++;
 		} while (--nbox_this_time);
 
-		if (nbox)
+		if (nbox) {
 			_kgem_submit(kgem);
+			_kgem_set_mode(kgem, KGEM_BLT);
+		}
 	} while (nbox);
 
 	if (kgem->gen >= 60 && kgem_check_batch(kgem, 3)) {
@@ -1572,6 +1691,5 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		kgem->nbatch += 3;
 	}
 
-	_kgem_set_mode(kgem, KGEM_BLT);
 	return TRUE;
 }
commit d7fb98efdcc1bcc2cca6deb54b16d425b0350196
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 17:52:56 2011 +0100

    sna: The initial aperture check for a set of bo is unlikely to fail
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 38303e3..073fed7 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1621,7 +1621,7 @@ bool kgem_check_bo_fenced(struct kgem *kgem, ...)
 	int size = 0;
 	int fenced_size = 0;
 
-	if (kgem->aperture > kgem->aperture_low)
+	if (unlikely (kgem->aperture > kgem->aperture_low))
 		return false;
 
 	va_start(ap, kgem);
commit 3c8e1c5c4cbe703781f2845926f76a9537a971ea
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 16:35:08 2011 +0100

    sna: Reset the ring flag upon idling
    
    We track the last ring used when active so as to avoid stalling between
    batches. Once the GPU has retired all the pending requests, we can use
    whichever ring is preferrable for the next operation without any danger
    of stalling upon submission.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 4d876db..38303e3 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -670,6 +670,9 @@ void kgem_retire(struct kgem *kgem)
 		list_del(&rq->list);
 		free(rq);
 	}
+
+	if (kgem->ring && list_is_empty(&kgem->requests))
+		kgem->ring = kgem->mode;
 }
 
 static void kgem_commit(struct kgem *kgem)
commit 594c5f86bb2e1cd0390b360c926ead58ba49979f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 16:25:42 2011 +0100

    sna: Don't rewrite the solid colour cache if it hasn't changed
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_gradient.c b/src/sna/sna_gradient.c
index 4a93143..84d57f4 100644
--- a/src/sna/sna_gradient.c
+++ b/src/sna/sna_gradient.c
@@ -227,9 +227,9 @@ sna_render_finish_solid(struct sna *sna, bool force)
 	int i;
 
 	DBG(("sna_render_finish_solid(force=%d, busy=%d, dirty=%d)\n",
-	     force, cache->cache_bo->rq != NULL, cache->dirty));
+	     force, cache->cache_bo->gpu, cache->dirty));
 
-	if (!force && !cache->cache_bo->rq)
+	if (!force && !cache->cache_bo->gpu)
 		return;
 
 	if (cache->dirty)
@@ -291,13 +291,13 @@ sna_render_get_solid(struct sna *sna, uint32_t color)
 
 	i = cache->size++;
 	cache->color[i] = color;
+	cache->dirty = 1;
 	DBG(("sna_render_get_solid(%d) = %x (new)\n", i, color));
 
 create:
 	cache->bo[i] = kgem_create_proxy(cache->cache_bo,
 					 i*sizeof(uint32_t), sizeof(uint32_t));
 	cache->bo[i]->pitch = 4;
-	cache->dirty = 1;
 
 done:
 	cache->last = i;


More information about the xorg-commit mailing list