xf86-video-intel: 6 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Wed Nov 2 14:08:31 PDT 2011


 src/sna/kgem.c       |    1 
 src/sna/sna.h        |   41 ++--
 src/sna/sna_accel.c  |  510 ++++++++++++++++++++++++++++++++++++++-------------
 src/sna/sna_driver.c |    4 
 4 files changed, 415 insertions(+), 141 deletions(-)

New commits:
commit 6fd0754e9c81164ca0fdcf96ba2bfb419568187f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 2 18:03:07 2011 +0000

    sna: defer calling fbValidateGC until we fallback
    
    A secondary effect is that this prevents needless migration of the
    tiling pixmap which we want to optimistically keep on the GPU.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 3d2ecaf..1097d74 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -43,25 +43,26 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include <stdint.h>
 
-#include "xf86_OSproc.h"
 #include "compiler.h"
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-#include "xf86Cursor.h"
-#include "xf86xv.h"
-#include "vgaHW.h"
-#include "xf86Crtc.h"
-#include "xf86RandR12.h"
-
-#include "xorg-server.h"
+#include <xf86_OSproc.h>
+#include <xf86PciInfo.h>
+#include <xf86Pci.h>
+#include <xf86Cursor.h>
+#include <xf86xv.h>
+#include <vgaHW.h>
+#include <xf86Crtc.h>
+#include <xf86RandR12.h>
+#include <gcstruct.h>
+
+#include <xorg-server.h>
 #include <pciaccess.h>
 
-#include "xf86drm.h"
-#include "xf86drmMode.h"
+#include <xf86drm.h>
+#include <xf86drmMode.h>
 
 #define _XF86DRI_SERVER_
-#include "dri2.h"
-#include "i915_drm.h"
+#include <dri2.h>
+#include <i915_drm.h>
 
 #if HAVE_UDEV
 #include <libudev.h>
@@ -181,6 +182,18 @@ static inline void sna_set_pixmap(PixmapPtr pixmap, struct sna_pixmap *sna)
 	dixSetPrivate(&pixmap->devPrivates, &sna_pixmap_index, sna);
 }
 
+struct sna_gc {
+	long changes;
+	long serial;
+};
+
+extern DevPrivateKeyRec sna_gc_index;
+
+static inline struct sna_gc *sna_gc(GCPtr gc)
+{
+	return dixGetPrivateAddr(&gc->devPrivates, &sna_gc_index);
+}
+
 enum {
 	OPTION_TILING_FB,
 	OPTION_TILING_2D,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index a689437..9b9c7cc 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -63,6 +63,7 @@
 #define USE_BO_FOR_SCRATCH_PIXMAP 1
 
 DevPrivateKeyRec sna_pixmap_index;
+DevPrivateKeyRec sna_gc_index;
 DevPrivateKey sna_window_key;
 
 static const uint8_t copy_ROP[] = {
@@ -1003,9 +1004,51 @@ done:
 	return priv;
 }
 
-static void sna_gc_move_to_cpu(GCPtr gc)
+static void sna_validate_pixmap(DrawablePtr draw, PixmapPtr pixmap)
 {
-	DBG(("%s\n", __FUNCTION__));
+	if (draw->bitsPerPixel == pixmap->drawable.bitsPerPixel &&
+	    FbEvenTile(pixmap->drawable.width *
+		       pixmap->drawable.bitsPerPixel)) {
+		DBG(("%s: flushing pixmap\n", __FUNCTION__));
+		sna_pixmap_move_to_cpu(pixmap, true);
+	}
+}
+
+static void sna_gc_move_to_cpu(GCPtr gc, DrawablePtr drawable)
+{
+	struct sna_gc *sgc = sna_gc(gc);
+	long changes = sgc->changes;
+
+	DBG(("%s, changes=%d\n", __FUNCTION_, changes_));
+
+	if (gc->clientClipType == CT_PIXMAP) {
+		PixmapPtr clip = gc->clientClip;
+		gc->clientClip = BitmapToRegion(gc->pScreen, clip);
+		gc->pScreen->DestroyPixmap(clip);
+		gc->clientClipType = gc->clientClip ? CT_REGION : CT_NONE;
+		changes |= GCClipMask;
+	} else
+		changes &= ~GCClipMask;
+
+	if (changes || drawable->serialNumber != sgc->serial) {
+		gc->serialNumber = sgc->serial;
+
+		if (changes & GCTile && !gc->tileIsPixel) {
+			DBG(("%s: flushing tile pixmap\n", __FUNCTION__));
+			sna_validate_pixmap(drawable, gc->tile.pixmap);
+		}
+
+		if (changes & GCStipple && gc->stipple) {
+			DBG(("%s: flushing stipple pixmap\n", __FUNCTION__));
+			sna_pixmap_move_to_cpu(gc->stipple, false);
+		}
+
+		fbValidateGC(gc, changes, drawable);
+
+		gc->serialNumber = drawable->serialNumber;
+		sgc->serial = drawable->serialNumber;
+	}
+	sgc->changes = 0;
 
 	if (gc->stipple)
 		sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
@@ -1621,6 +1664,7 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 	if (priv == NULL) {
 		DBG(("%s: fbPutImage, unattached(%d, %d, %d, %d)\n",
 		     __FUNCTION__, x, y, w, h));
+		sna_gc_move_to_cpu(gc, drawable);
 		fbPutImage(drawable, gc, depth, x, y, w, h, left, format, bits);
 		return;
 	}
@@ -1683,6 +1727,7 @@ fallback:
 	DBG(("%s: fallback\n", __FUNCTION__));
 	RegionTranslate(&region, -dx, -dy);
 
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -1869,12 +1914,11 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 	/* Try to maintain the data on the GPU */
 	if (dst_priv && dst_priv->gpu_bo == NULL &&
-	    src_priv && src_priv->gpu_bo != NULL &&
-	    alu == GXcopy) {
+	    src_priv && src_priv->gpu_bo != NULL) {
 		uint32_t tiling =
 			sna_pixmap_choose_tiling(dst_pixmap);
 
-		DBG(("%s: create dst GPU bo for copy\n", __FUNCTION__));
+		DBG(("%s: create dst GPU bo for upload\n", __FUNCTION__));
 
 		if (kgem_can_create_2d(&sna->kgem,
 				       dst_pixmap->drawable.width,
@@ -2163,6 +2207,7 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		if (!RegionNotEmpty(&region))
 			return NULL;
 
+		sna_gc_move_to_cpu(gc, dst);
 		sna_drawable_move_region_to_cpu(dst, &region, true);
 		RegionTranslate(&region,
 				src_x - dst_x - dst->x + src->x,
@@ -2738,7 +2783,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -2763,6 +2808,7 @@ sna_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	if (!RegionNotEmpty(&region))
 		return;
 
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -3127,6 +3173,7 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	}
 
 	DBG(("%s: fallback\n", __FUNCTION__));
+	sna_gc_move_to_cpu(gc, dst);
 	sna_drawable_move_region_to_cpu(dst, &region, true);
 	RegionTranslate(&region,
 			src_x - dst_x - dst->x + src->x,
@@ -3313,9 +3360,11 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
+	DBG(("%s: fbPolyPoint\n", __FUNCTION__));
 	fbPolyPoint(drawable, gc, mode, n, pt);
 }
 
@@ -4080,7 +4129,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -4853,7 +4902,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -5391,7 +5440,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -5508,7 +5557,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -6447,6 +6496,8 @@ sna_poly_fill_rect_stippled_blt(DrawablePtr drawable,
 	if (bo->tiling == I915_TILING_Y)
 		return false;
 
+	sna_drawable_move_to_cpu(&stipple->drawable, false);
+
 	DBG(("%s: origin (%d, %d), extents (stipple): (%d, %d), stipple size %dx%d\n",
 	     __FUNCTION__, gc->patOrg.x, gc->patOrg.y,
 	     extents->x2 - gc->patOrg.x - drawable->x,
@@ -6613,7 +6664,7 @@ fallback:
 		return;
 	}
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, draw);
 	sna_drawable_move_region_to_cpu(draw, &region, true);
 	RegionUninit(&region);
 
@@ -6845,7 +6896,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -6899,7 +6950,7 @@ fallback:
 	if (!RegionNotEmpty(&region))
 		return;
 
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
 
@@ -7069,7 +7120,7 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 	}
 
 	DBG(("%s: fallback\n", __FUNCTION__));
-	sna_gc_move_to_cpu(gc);
+	sna_gc_move_to_cpu(gc, drawable);
 	sna_pixmap_move_to_cpu(bitmap, false);
 	sna_drawable_move_region_to_cpu(drawable, &region, true);
 	RegionUninit(&region);
@@ -7102,32 +7153,17 @@ static const GCOps sna_gc_ops = {
 	sna_push_pixels,
 };
 
-static void sna_validate_pixmap(DrawablePtr draw, PixmapPtr pixmap)
-{
-	if (draw->bitsPerPixel == pixmap->drawable.bitsPerPixel &&
-	    FbEvenTile(pixmap->drawable.width *
-		       pixmap->drawable.bitsPerPixel)) {
-		DBG(("%s: flushing pixmap\n", __FUNCTION__));
-		sna_pixmap_move_to_cpu(pixmap, true);
-	}
-}
-
 static void
 sna_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 {
 	DBG(("%s\n", __FUNCTION__));
 
-	if (changes & GCTile && !gc->tileIsPixel) {
-		DBG(("%s: flushing tile pixmap\n", __FUNCTION__));
-		sna_validate_pixmap(drawable, gc->tile.pixmap);
-	}
-
-	if (changes & GCStipple && gc->stipple) {
-		DBG(("%s: flushing stipple pixmap\n", __FUNCTION__));
-		sna_pixmap_move_to_cpu(gc->stipple, true);
-	}
+	if (changes & (GCClipMask|GCSubwindowMode) ||
+	    drawable->serialNumber != (gc->serialNumber & DRAWABLE_SERIAL_BITS) ||
+	    (gc->clientClipType != CT_NONE && (changes & (GCClipXOrigin | GCClipYOrigin))))
+		miComputeCompositeClip(gc, drawable);
 
-	fbValidateGC(gc, changes, drawable);
+	sna_gc(gc)->changes |= changes;
 }
 
 static const GCFuncs sna_gc_funcs = {
@@ -7444,6 +7480,8 @@ Bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 
 	if (!dixRegisterPrivateKey(&sna_pixmap_index, PRIVATE_PIXMAP, 0))
 		return FALSE;
+	if (!dixRegisterPrivateKey(&sna_gc_index, PRIVATE_GC, sizeof(struct sna_gc)))
+		return FALSE;
 
 	if (!AddCallback(&FlushCallback, sna_accel_flush_callback, sna))
 		return FALSE;
commit 6f8875e216194474e818ba6e743e7c22b817f96e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 2 15:41:40 2011 +0000

    sna: Wait an extra interval before switching off periodic updates
    
    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 4162f87..a689437 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -7410,7 +7410,7 @@ static bool sna_accel_flush(struct sna *sna)
 		_sna_accel_disarm_timer(sna, FLUSH_TIMER);
 	else
 		sna_pixmap_move_to_gpu(priv->pixmap);
-	sna->kgem.busy = 0;
+	sna->kgem.busy = !nothing_to_do;
 	kgem_bo_flush(&sna->kgem, priv->gpu_bo);
 	return !nothing_to_do;
 }
commit def6b5e733e623333abf596bbdbabf8dd0ac8b00
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 2 14:35:45 2011 +0000

    sna: Only execute the accel block handler if we are about to block
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 0df7ca0..cacee4b 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -567,12 +567,14 @@ static void
 sna_block_handler(int i, pointer data, pointer timeout, pointer read_mask)
 {
 	struct sna *sna = data;
+	struct timeval *tv = timeout;
 
 	DBG(("%s\n", __FUNCTION__));
 
 	sna->BlockHandler(i, sna->BlockData, timeout, read_mask);
 
-	sna_accel_block_handler(sna);
+	if (tv == NULL || (tv->tv_usec | tv->tv_sec))
+		sna_accel_block_handler(sna);
 }
 
 static void
commit 088b875affb8655010bc678ca4a3e87703c92daf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 2 13:11:04 2011 +0000

    sna: Use the packed 8x8 stipple for non-repeating small rectangles
    
    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 bd895d4..4162f87 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5918,7 +5918,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
-	uint32_t pat[2], br00, br13;
+	uint32_t pat[2] = {0, 0}, br00, br13;
 	int16_t dx, dy;
 
 	DBG(("%s: alu=%d, upload (%d, %d), (%d, %d), origin (%d, %d)\n",
@@ -5951,7 +5951,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 		uint8_t *dst = (uint8_t *)pat;
 		const uint8_t *src = gc->stipple->devPrivate.ptr;
 		int stride = gc->stipple->devKind;
-		int n = 8;
+		int n = gc->stipple->drawable.height;
 		do {
 			*dst++ = byte_reverse(*src);
 			src += stride;
@@ -6459,10 +6459,16 @@ sna_poly_fill_rect_stippled_blt(DrawablePtr drawable,
 							   extents, clipped);
 
 	if (extents->x2 - gc->patOrg.x - drawable->x <= stipple->drawable.width &&
-	    extents->y2 - gc->patOrg.y - drawable->y <= stipple->drawable.height)
-		return sna_poly_fill_rect_stippled_1_blt(drawable, bo, damage,
-							 gc, n, rect,
-							 extents, clipped);
+	    extents->y2 - gc->patOrg.y - drawable->y <= stipple->drawable.height) {
+		if (stipple->drawable.width <= 8 && stipple->drawable.height <= 8)
+			return sna_poly_fill_rect_stippled_8x8_blt(drawable, bo, damage,
+								   gc, n, rect,
+								   extents, clipped);
+		else
+			return sna_poly_fill_rect_stippled_1_blt(drawable, bo, damage,
+								 gc, n, rect,
+								 extents, clipped);
+	}
 
 	return false;
 }
commit 0c373db73d1d2b7cf844653307c60a3891a3cc10
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 2 12:43:55 2011 +0000

    sna: Fix the 8x8 stippled pattern origin
    
    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 235b783..bd895d4 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5929,8 +5929,8 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 	{
-		unsigned px = (gc->patOrg.x - dx) & 7;
-		unsigned py = (gc->patOrg.y - dy) & 7;
+		unsigned px = (0 - gc->patOrg.x - dx) & 7;
+		unsigned py = (0 - gc->patOrg.y - dy) & 7;
 		DBG(("%s: pat offset (%d, %d)\n", __FUNCTION__ ,px, py));
 		br00 = XY_MONO_PAT | px << 12 | py << 8;
 		if (drawable->bitsPerPixel == 32)
commit 9cdf8be55029f30b47cfc39ddd2754d40602cf2c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 2 12:17:31 2011 +0000

    sna: Add clipped stippled upload support
    
    For xsnow!
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 7770175..e470e4d 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1959,6 +1959,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 
 	DBG(("%s: size=%d, flags=%x [write=%d, last=%d]\n",
 	     __FUNCTION__, size, flags, write, flags & KGEM_BUFFER_LAST));
+	assert(size);
 
 	list_for_each_entry(bo, &kgem->partial, base.list) {
 		if (flags == KGEM_BUFFER_LAST && bo->write) {
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f70a312..235b783 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -6121,100 +6121,314 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 	     extents->x2, extents->y2,
 	     origin->x, origin->y));
 
-	if (clipped) {
-		DBG(("%s: fallback -- clipped\n", __FUNCTION__));
-		return false;
-	}
-
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
-	dx += drawable->x;
-	dy += drawable->y;
-
 	kgem_set_mode(&sna->kgem, KGEM_BLT);
 
-	sna_damage_add_rectangles(damage, r, n, dx, dy);
-	do {
-		int bx1 = (r->x - origin->x) & ~7;
-		int bx2 = (r->x + r->width - origin->x + 7) & ~7;
-		int bw = (bx2 - bx1)/8;
-		int bh = r->height;
-		int bstride = ALIGN(bw, 2);
-		int src_stride;
-		uint8_t *dst, *src;
-		uint32_t *b;
-		struct kgem_bo *upload;
-		void *ptr;
+	if (!clipped) {
+		dx += drawable->x;
+		dy += drawable->y;
 
-		DBG(("%s: rect (%d, %d)x(%d, %d) stipple [%d,%d]\n",
-		     __FUNCTION__,
-		     r->x, r->y, r->width, r->height,
-		     bx1, bx2));
+		sna_damage_add_rectangles(damage, r, n, dx, dy);
+		do {
+			int bx1 = (r->x - origin->x) & ~7;
+			int bx2 = (r->x + r->width - origin->x + 7) & ~7;
+			int bw = (bx2 - bx1)/8;
+			int bh = r->height;
+			int bstride = ALIGN(bw, 2);
+			int src_stride;
+			uint8_t *dst, *src;
+			uint32_t *b;
+			struct kgem_bo *upload;
+			void *ptr;
 
-		if (!kgem_check_batch(&sna->kgem, 8) ||
-		    !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) ||
-		    !kgem_check_reloc(&sna->kgem, 2)) {
-			_kgem_submit(&sna->kgem);
-			_kgem_set_mode(&sna->kgem, KGEM_BLT);
-		}
+			DBG(("%s: rect (%d, %d)x(%d, %d) stipple [%d,%d]\n",
+			     __FUNCTION__,
+			     r->x, r->y, r->width, r->height,
+			     bx1, bx2));
 
-		upload = kgem_create_buffer(&sna->kgem,
-					    bstride*bh,
-					    KGEM_BUFFER_WRITE,
-					    &ptr);
-		if (!upload)
-			break;
+			if (!kgem_check_batch(&sna->kgem, 8) ||
+			    !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) ||
+			    !kgem_check_reloc(&sna->kgem, 2)) {
+				_kgem_submit(&sna->kgem);
+				_kgem_set_mode(&sna->kgem, KGEM_BLT);
+			}
 
-		dst = ptr;
-		bstride -= bw;
+			upload = kgem_create_buffer(&sna->kgem,
+						    bstride*bh,
+						    KGEM_BUFFER_WRITE,
+						    &ptr);
+			if (!upload)
+				break;
 
-		src_stride = stipple->devKind;
-		src = (uint8_t*)stipple->devPrivate.ptr;
-		src += (r->y - origin->y) * src_stride + bx1/8;
-		src_stride -= bw;
-		do {
-			int i = bw;
+			dst = ptr;
+			bstride -= bw;
+
+			src_stride = stipple->devKind;
+			src = (uint8_t*)stipple->devPrivate.ptr;
+			src += (r->y - origin->y) * src_stride + bx1/8;
+			src_stride -= bw;
 			do {
-				*dst++ = byte_reverse(*src++);
-			} while (--i);
-			dst += bstride;
-			src += src_stride;
-		} while (--bh);
+				int i = bw;
+				do {
+					*dst++ = byte_reverse(*src++);
+				} while (--i);
+				dst += bstride;
+				src += src_stride;
+			} while (--bh);
 
-		b = sna->kgem.batch + sna->kgem.nbatch;
-		b[0] = XY_MONO_SRC_COPY;
-		if (drawable->bitsPerPixel == 32)
-			b[0] |= 3 << 20;
-		b[0] |= ((r->x - origin->x) & 7) << 17;
-		b[1] = priv->gpu_bo->pitch;
-		if (sna->kgem.gen >= 40) {
-			if (priv->gpu_bo->tiling)
-				b[0] |= BLT_DST_TILED;
-			b[1] >>= 2;
-		}
-		b[1] |= (gc->fillStyle == FillStippled) << 29;
-		b[1] |= blt_depth(drawable->depth) << 24;
-		b[1] |= rop << 16;
-		b[2] = (r->y + dy) << 16 | (r->x + dx);
-		b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
-		b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
-				      priv->gpu_bo,
-				      I915_GEM_DOMAIN_RENDER << 16 |
-				      I915_GEM_DOMAIN_RENDER |
-				      KGEM_RELOC_FENCED,
-				      0);
-		b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5,
-				      upload,
-				      I915_GEM_DOMAIN_RENDER << 16 |
-				      KGEM_RELOC_FENCED,
-				      0);
-		b[6] = gc->bgPixel;
-		b[7] = gc->fgPixel;
+			b = sna->kgem.batch + sna->kgem.nbatch;
+			b[0] = XY_MONO_SRC_COPY;
+			if (drawable->bitsPerPixel == 32)
+				b[0] |= 3 << 20;
+			b[0] |= ((r->x - origin->x) & 7) << 17;
+			b[1] = priv->gpu_bo->pitch;
+			if (sna->kgem.gen >= 40) {
+				if (priv->gpu_bo->tiling)
+					b[0] |= BLT_DST_TILED;
+				b[1] >>= 2;
+			}
+			b[1] |= (gc->fillStyle == FillStippled) << 29;
+			b[1] |= blt_depth(drawable->depth) << 24;
+			b[1] |= rop << 16;
+			b[2] = (r->y + dy) << 16 | (r->x + dx);
+			b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
+			b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
+					      priv->gpu_bo,
+					      I915_GEM_DOMAIN_RENDER << 16 |
+					      I915_GEM_DOMAIN_RENDER |
+					      KGEM_RELOC_FENCED,
+					      0);
+			b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5,
+					      upload,
+					      I915_GEM_DOMAIN_RENDER << 16 |
+					      KGEM_RELOC_FENCED,
+					      0);
+			b[6] = gc->bgPixel;
+			b[7] = gc->fgPixel;
 
-		sna->kgem.nbatch += 8;
-		kgem_bo_destroy(&sna->kgem, upload);
+			sna->kgem.nbatch += 8;
+			kgem_bo_destroy(&sna->kgem, upload);
 
-		r++;
-	} while (--n);
+			r++;
+		} while (--n);
+	} else {
+		RegionRec clip;
+		DDXPointRec pat;
+
+		region_set(&clip, extents);
+		region_maybe_clip(&clip, gc->pCompositeClip);
+		if (!RegionNotEmpty(&clip))
+			return true;
+
+		pat.x = origin->x + drawable->x;
+		pat.y = origin->y + drawable->y;
+
+		if (clip.data == NULL) {
+			do {
+				BoxRec box;
+				int bx1, bx2, bw, bh, bstride;
+				int src_stride;
+				uint8_t *dst, *src;
+				uint32_t *b;
+				struct kgem_bo *upload;
+				void *ptr;
+
+				box.x1 = r->x + drawable->x;
+				box.x2 = bound(r->x, r->width);
+				box.y1 = r->y + drawable->y;
+				box.y2 = bound(r->y, r->height);
+				r++;
+
+				if (!box_intersect(&box, &clip.extents))
+					continue;
+
+				bx1 = (box.x1 - pat.x) & ~7;
+				bx2 = (box.x2 - pat.x + 7) & ~7;
+				bw = (bx2 - bx1)/8;
+				bh = box.y2 - box.y1;
+				bstride = ALIGN(bw, 8);
+
+				DBG(("%s: rect (%d, %d)x(%d, %d), box (%d,%d),(%d,%d) stipple [%d,%d], pitch=%d, stride=%d\n",
+				     __FUNCTION__,
+				     r->x, r->y, r->width, r->height,
+				     box.x1, box.y1, box.x2, box.y2,
+				     bx1, bx2, bw, bstride));
+
+				if (!kgem_check_batch(&sna->kgem, 8) ||
+				    !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) ||
+				    !kgem_check_reloc(&sna->kgem, 2)) {
+					_kgem_submit(&sna->kgem);
+					_kgem_set_mode(&sna->kgem, KGEM_BLT);
+				}
+
+				upload = kgem_create_buffer(&sna->kgem,
+							    bstride*bh,
+							    KGEM_BUFFER_WRITE,
+							    &ptr);
+				if (!upload)
+					break;
+
+				dst = ptr;
+				bstride -= bw;
+
+				src_stride = stipple->devKind;
+				src = (uint8_t*)stipple->devPrivate.ptr;
+				src += (box.y1 - pat.y) * src_stride + bx1/8;
+				src_stride -= bw;
+				do {
+					int i = bw;
+					do {
+						*dst++ = byte_reverse(*src++);
+					} while (--i);
+					dst += bstride;
+					src += src_stride;
+				} while (--bh);
+
+				b = sna->kgem.batch + sna->kgem.nbatch;
+				b[0] = XY_MONO_SRC_COPY;
+				if (drawable->bitsPerPixel == 32)
+					b[0] |= 3 << 20;
+				b[0] |= ((box.x1 - pat.x) & 7) << 17;
+				b[1] = priv->gpu_bo->pitch;
+				if (sna->kgem.gen >= 40) {
+					if (priv->gpu_bo->tiling)
+						b[0] |= BLT_DST_TILED;
+					b[1] >>= 2;
+				}
+				b[1] |= (gc->fillStyle == FillStippled) << 29;
+				b[1] |= blt_depth(drawable->depth) << 24;
+				b[1] |= rop << 16;
+				b[2] = (box.y1 + dy) << 16 | (box.x1 + dx);
+				b[3] = (box.y2 + dy) << 16 | (box.x2 + dx);
+				b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
+						      priv->gpu_bo,
+						      I915_GEM_DOMAIN_RENDER << 16 |
+						      I915_GEM_DOMAIN_RENDER |
+						      KGEM_RELOC_FENCED,
+						      0);
+				b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5,
+						      upload,
+						      I915_GEM_DOMAIN_RENDER << 16 |
+						      KGEM_RELOC_FENCED,
+						      0);
+				b[6] = gc->bgPixel;
+				b[7] = gc->fgPixel;
+
+				sna->kgem.nbatch += 8;
+				kgem_bo_destroy(&sna->kgem, upload);
+			} while (--n);
+		} else {
+			const BoxRec * const clip_start = RegionBoxptr(&clip);
+			const BoxRec * const clip_end = clip_start + clip.data->numRects;
+			const BoxRec *c;
+
+			do {
+				BoxRec unclipped;
+				int bx1, bx2, bw, bh, bstride;
+				int src_stride;
+				uint8_t *dst, *src;
+				uint32_t *b;
+				struct kgem_bo *upload;
+				void *ptr;
+
+				unclipped.x1 = r->x + drawable->x;
+				unclipped.x2 = bound(r->x, r->width);
+				unclipped.y1 = r->y + drawable->y;
+				unclipped.y2 = bound(r->y, r->height);
+				r++;
+
+				c = find_clip_box_for_y(clip_start,
+							clip_end,
+							unclipped.y1);
+				while (c != clip_end) {
+					BoxRec box;
+
+					if (unclipped.y2 <= c->y1)
+						break;
+
+					box = unclipped;
+					if (!box_intersect(&box, c++))
+						continue;
+
+					bx1 = (box.x1 - pat.x) & ~7;
+					bx2 = (box.x2 - pat.x + 7) & ~7;
+					bw = (bx2 - bx1)/8;
+					bh = box.y2 - box.y1;
+					bstride = ALIGN(bw, 8);
+
+					DBG(("%s: rect (%d, %d)x(%d, %d), box (%d,%d),(%d,%d) stipple [%d,%d]\n",
+					     __FUNCTION__,
+					     r->x, r->y, r->width, r->height,
+					     box.x1, box.y1, box.x2, box.y2,
+					     bx1, bx2));
+
+					if (!kgem_check_batch(&sna->kgem, 8) ||
+					    !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) ||
+					    !kgem_check_reloc(&sna->kgem, 2)) {
+						_kgem_submit(&sna->kgem);
+						_kgem_set_mode(&sna->kgem, KGEM_BLT);
+					}
+
+					upload = kgem_create_buffer(&sna->kgem,
+								    bstride*bh,
+								    KGEM_BUFFER_WRITE,
+								    &ptr);
+					if (!upload)
+						break;
+
+					dst = ptr;
+					bstride -= bw;
+
+					src_stride = stipple->devKind;
+					src = (uint8_t*)stipple->devPrivate.ptr;
+					src += (box.y1 - pat.y) * src_stride + bx1/8;
+					src_stride -= bw;
+					do {
+						int i = bw;
+						do {
+							*dst++ = byte_reverse(*src++);
+						} while (--i);
+						dst += bstride;
+						src += src_stride;
+					} while (--bh);
+
+					b = sna->kgem.batch + sna->kgem.nbatch;
+					b[0] = XY_MONO_SRC_COPY;
+					if (drawable->bitsPerPixel == 32)
+						b[0] |= 3 << 20;
+					b[0] |= ((box.x1 - pat.x) & 7) << 17;
+					b[1] = priv->gpu_bo->pitch;
+					if (sna->kgem.gen >= 40) {
+						if (priv->gpu_bo->tiling)
+							b[0] |= BLT_DST_TILED;
+						b[1] >>= 2;
+					}
+					b[1] |= (gc->fillStyle == FillStippled) << 29;
+					b[1] |= blt_depth(drawable->depth) << 24;
+					b[1] |= rop << 16;
+					b[2] = (box.y1 + dy) << 16 | (box.x1 + dx);
+					b[3] = (box.y2 + dy) << 16 | (box.x2 + dx);
+					b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
+							      priv->gpu_bo,
+							      I915_GEM_DOMAIN_RENDER << 16 |
+							      I915_GEM_DOMAIN_RENDER |
+							      KGEM_RELOC_FENCED,
+							      0);
+					b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5,
+							      upload,
+							      I915_GEM_DOMAIN_RENDER << 16 |
+							      KGEM_RELOC_FENCED,
+							      0);
+					b[6] = gc->bgPixel;
+					b[7] = gc->fgPixel;
+
+					sna->kgem.nbatch += 8;
+					kgem_bo_destroy(&sna->kgem, upload);
+				}
+			} while (--n);
+
+		}
+	}
 
 	sna->blt_state.fill_bo = 0;
 	return true;
@@ -6322,7 +6536,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 		struct sna_pixmap *priv = sna_pixmap_from_drawable(draw);
 		uint32_t color = gc->fillStyle == FillTiled ? gc->tile.pixel : gc->fgPixel;
 
-		DBG(("%s: solid fill [%08lx], testing for blt\n",
+		DBG(("%s: solid fill [%08x], testing for blt\n",
 		     __FUNCTION__, color));
 
 		if (sna_drawable_use_gpu_bo(draw, &region.extents) &&


More information about the xorg-commit mailing list