xf86-video-intel: 3 commits - src/sna/sna_accel.c src/sna/sna_reg.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Jul 23 07:23:54 PDT 2012


 src/sna/sna_accel.c |  381 ++++++++++++++++++++++++++++++++++++++++++++++------
 src/sna/sna_reg.h   |    1 
 2 files changed, 341 insertions(+), 41 deletions(-)

New commits:
commit e3f6c48d18c316899c71b6fc34971039c6f9e5f8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 23 14:43:23 2012 +0100

    sna: Refactor PutImage to avoid calling drawable_gc_flags() too early
    
    drawable_gc_flags() asserts that the gc has been moved to the CPU prior
    to its calls so that it can read the reduced raster operation.
    
    Reported-by: Zdenek Kabelac <zkabelac at redhat.com>
    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 98a3e68..f51f732 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3698,7 +3698,6 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	RegionRec region;
 	int16_t dx, dy;
-	unsigned hint;
 
 	DBG(("%s((%d, %d)x(%d, %d), depth=%d, format=%d)\n",
 	     __FUNCTION__, x, y, w, h, depth, format));
@@ -3727,47 +3726,39 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 	if (priv == NULL) {
 		DBG(("%s: fallback -- unattached(%d, %d, %d, %d)\n",
 		     __FUNCTION__, x, y, w, h));
-hint_and_fallback:
-		hint = (format == XYPixmap ?
-			MOVE_READ | MOVE_WRITE :
-			drawable_gc_flags(drawable, gc, false));
 		goto fallback;
 	}
 
 	RegionTranslate(&region, dx, dy);
 
 	if (FORCE_FALLBACK)
-		goto hint_and_fallback;
+		goto fallback;
 
 	if (wedged(sna))
-		goto hint_and_fallback;
+		goto fallback;
 
 	if (!ACCEL_PUT_IMAGE)
-		goto hint_and_fallback;
+		goto fallback;
 
 	switch (format) {
 	case ZPixmap:
 		if (!PM_IS_SOLID(drawable, gc->planemask))
-			goto hint_and_fallback;
+			goto fallback;
 
 		if (sna_put_zpixmap_blt(drawable, gc, &region,
 					x, y, w, h,
 					bits, PixmapBytePad(w, depth)))
 			return;
-
-		hint = drawable_gc_flags(drawable, gc, false);
 		break;
 
 	case XYBitmap:
 		if (!PM_IS_SOLID(drawable, gc->planemask))
-			goto hint_and_fallback;
+			goto fallback;
 
 		if (sna_put_xybitmap_blt(drawable, gc, &region,
 					 x, y, w, h,
 					 bits))
 			return;
-
-		hint = drawable_gc_flags(drawable, gc, false);
 		break;
 
 	case XYPixmap:
@@ -3775,8 +3766,6 @@ hint_and_fallback:
 					 x, y, w, h, left,
 					 bits))
 			return;
-
-		hint = MOVE_READ | MOVE_WRITE;
 		break;
 
 	default:
@@ -3789,7 +3778,10 @@ fallback:
 
 	if (!sna_gc_move_to_cpu(gc, drawable, &region))
 		goto out;
-	if (!sna_drawable_move_region_to_cpu(drawable, &region, hint))
+	if (!sna_drawable_move_region_to_cpu(drawable, &region,
+					      format == XYPixmap ?
+					      MOVE_READ | MOVE_WRITE :
+					      drawable_gc_flags(drawable, gc, false)))
 		goto out_gc;
 
 	DBG(("%s: fbPutImage(%d, %d, %d, %d)\n",
commit 1af26ea4228a9d7768b475b4f9164d2c7620d4fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 23 14:39:44 2012 +0100

    sna: Flesh out tiled operations using the BLT
    
    Before enabling the RENDER pipeline for this operation, let's just see
    what is required to fully use the BLT pipeline as well.
    
    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 9ae8775..98a3e68 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9423,6 +9423,277 @@ sna_pixmap_get_source_bo(PixmapPtr pixmap)
 	return kgem_bo_reference(priv->gpu_bo);
 }
 
+/*
+static bool
+tile(DrawablePtr drawable,
+	struct kgem_bo *bo, struct sna_damage **damage,
+	PixmapPtr tile, const DDXPointRec * const origin, int alu,
+	int n, xRectangle *rect,
+	const BoxRec *extents, unsigned clipped)
+	*/
+
+static bool
+sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
+				 struct kgem_bo *bo, struct sna_damage **damage,
+				 struct kgem_bo *tile_bo, GCPtr gc,
+				 int n, xRectangle *r,
+				 const BoxRec *extents, unsigned clipped)
+{
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	const DDXPointRec * const origin = &gc->patOrg;
+	uint32_t br00, br13;
+	int tx, ty;
+	int16_t dx, dy;
+	uint32_t *b;
+
+	DBG(("%s x %d [(%d, %d)+(%d, %d)...], clipped=%x\n",
+	     __FUNCTION__, n, r->x, r->y, r->width, r->height, clipped));
+
+	br00 = XY_PAT_BLT | 3 << 20;
+	br13 = bo->pitch;
+	if (bo->tiling && sna->kgem.gen >= 40) {
+		br13 >>= 2;
+		br00 |= BLT_DST_TILED;
+	}
+	br13 |= blt_depth(drawable->depth) << 24;
+	br13 |= fill_ROP[gc->alu] << 16;
+
+	kgem_set_mode(&sna->kgem, KGEM_BLT);
+	get_drawable_deltas(drawable, pixmap, &dx, &dy);
+	if (!clipped) {
+		dx += drawable->x;
+		dy += drawable->y;
+
+		if (!kgem_check_batch(&sna->kgem, 6) ||
+		    !kgem_check_reloc(&sna->kgem, 2) ||
+		    !kgem_check_bo_fenced(&sna->kgem, bo)) {
+			_kgem_submit(&sna->kgem);
+			_kgem_set_mode(&sna->kgem, KGEM_BLT);
+		}
+
+		sna_damage_add_rectangles(damage, r, n, dx, dy);
+		do {
+			int n_this_time;
+
+			n_this_time = n;
+			if (6*n_this_time > sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED)
+				n_this_time = (sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED) / 8;
+			if (2*n_this_time > KGEM_RELOC_SIZE(&sna->kgem) - sna->kgem.nreloc)
+				n_this_time = (KGEM_RELOC_SIZE(&sna->kgem) - sna->kgem.nreloc)/2;
+			assert(n_this_time);
+			n -= n_this_time;
+
+			assert(r->x + dx >= 0);
+			assert(r->y + dy >= 0);
+			assert(r->x + dx + r->width  <= pixmap->drawable.width);
+			assert(r->y + dy + r->height <= pixmap->drawable.height);
+
+			b = sna->kgem.batch + sna->kgem.nbatch;
+			sna->kgem.nbatch += 6*n_this_time;
+			do {
+				tx = (r->x - origin->x) % 8;
+				if (tx < 8)
+					tx = 8 - tx;
+				ty = (r->y - origin->y) % 8;
+				if (ty < 8)
+					ty = 8 - ty;
+
+				b[0] = br00 | tx << 12 | ty << 8;
+				b[1] = br13;
+				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, b - sna->kgem.batch + 4, bo,
+						      I915_GEM_DOMAIN_RENDER << 16 |
+						      I915_GEM_DOMAIN_RENDER |
+						      KGEM_RELOC_FENCED,
+						      0);
+				b[5] = kgem_add_reloc(&sna->kgem, b - sna->kgem.batch + 5, tile_bo,
+						      I915_GEM_DOMAIN_RENDER << 16 |
+						      KGEM_RELOC_FENCED,
+						      0);
+				b += 6;
+				r++;
+			} while (--n_this_time);
+
+			if (!n)
+				break;
+
+			_kgem_submit(&sna->kgem);
+			_kgem_set_mode(&sna->kgem, KGEM_BLT);
+		} while (1);
+	} else {
+		RegionRec clip;
+
+		region_set(&clip, extents);
+		region_maybe_clip(&clip, gc->pCompositeClip);
+		if (!RegionNotEmpty(&clip))
+			goto done;
+
+		if (clip.data == NULL) {
+			const BoxRec *c = &clip.extents;
+			while (n--) {
+				BoxRec box;
+
+				box.x1 = r->x + drawable->x;
+				box.y1 = r->y + drawable->y;
+				box.x2 = bound(box.x1, r->width);
+				box.y2 = bound(box.y1, r->height);
+				r++;
+
+				if (box_intersect(&box, c)) {
+					ty = (box.y1 - drawable->y - origin->y) % 8;
+					if (ty < 0)
+						ty = 8 - ty;
+
+					tx = (box.x1 - drawable->x - origin->x) % 8;
+					if (tx < 0)
+						tx = 8 - tx;
+
+					if (!kgem_check_batch(&sna->kgem, 6) ||
+					    !kgem_check_reloc(&sna->kgem, 2) ||
+					    !kgem_check_bo_fenced(&sna->kgem, bo)) {
+						_kgem_submit(&sna->kgem);
+						_kgem_set_mode(&sna->kgem, KGEM_BLT);
+					}
+
+					b = sna->kgem.batch + sna->kgem.nbatch;
+					b[0] = br00 | tx << 12 | ty << 8;
+					b[1] = br13;
+					b[2] = box.y1 << 16 | box.x1;
+					b[3] = box.y2 << 16 | box.x2;
+					b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, 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, tile_bo,
+							      I915_GEM_DOMAIN_RENDER << 16 |
+							      KGEM_RELOC_FENCED,
+							      0);
+					sna->kgem.nbatch += 6;
+				}
+			}
+		} else {
+			const BoxRec * const clip_start = RegionBoxptr(&clip);
+			const BoxRec * const clip_end = clip_start + clip.data->numRects;
+			const BoxRec *c;
+
+			do {
+				BoxRec box;
+
+				box.x1 = r->x + drawable->x;
+				box.y1 = r->y + drawable->y;
+				box.x2 = bound(box.x1, r->width);
+				box.y2 = bound(box.y1, r->height);
+				r++;
+
+				c = find_clip_box_for_y(clip_start,
+							clip_end,
+							box.y1);
+				while (c != clip_end) {
+					BoxRec bb;
+
+					if (box.y2 <= c->y1)
+						break;
+
+					bb = box;
+					if (box_intersect(&bb, c++)) {
+						ty = (bb.y1 - drawable->y - origin->y) % 8;
+						if (ty < 0)
+							ty = 8 - ty;
+
+						tx = (bb.x1 - drawable->x - origin->x) % 8;
+						if (tx < 0)
+							tx = 8 - tx;
+
+						if (!kgem_check_batch(&sna->kgem, 6) ||
+						    !kgem_check_reloc(&sna->kgem, 2) ||
+						    !kgem_check_bo_fenced(&sna->kgem, bo)) {
+							_kgem_submit(&sna->kgem);
+							_kgem_set_mode(&sna->kgem, KGEM_BLT);
+						}
+
+						b = sna->kgem.batch + sna->kgem.nbatch;
+						b[0] = br00 | tx << 12 | ty << 8;
+						b[1] = br13;
+						b[2] = (bb.y1+dy) << 16 | (bb.x1+dx);
+						b[3] = (bb.y2+dy) << 16 | (bb.x2+dx);
+						b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, 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, tile_bo,
+								      I915_GEM_DOMAIN_RENDER << 16 |
+								      KGEM_RELOC_FENCED,
+								      0);
+						sna->kgem.nbatch += 6;
+					}
+				}
+			} while (--n);
+		}
+	}
+done:
+	assert_pixmap_damage(pixmap);
+	return true;
+}
+
+static bool
+sna_poly_fill_rect_tiled_nxm_blt(DrawablePtr drawable,
+				 struct kgem_bo *bo,
+				 struct sna_damage **damage,
+				 GCPtr gc, int n, xRectangle *rect,
+				 const BoxRec *extents, unsigned clipped)
+{
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	PixmapPtr tile = gc->tile.pixmap;
+	struct kgem_bo *upload;
+	int w, h, cpp;
+	void *ptr;
+	bool ret;
+
+	DBG(("%s: %dx%d\n", __FUNCTION__,
+	     tile->drawable.width, tile->drawable.height));
+
+	if (!sna_pixmap_move_to_cpu(tile, MOVE_READ))
+		return false;
+
+	upload = kgem_create_buffer(&sna->kgem, 8*tile->drawable.bitsPerPixel,
+				    KGEM_BUFFER_WRITE_INPLACE,
+				    &ptr);
+	if (upload == NULL)
+		return false;
+
+	assert(tile->drawable.height && tile->drawable.height <= 8);
+	assert(tile->drawable.width && tile->drawable.width <= 8);
+
+	cpp = tile->drawable.bitsPerPixel/8;
+	for (h = 0; h < tile->drawable.height; h++) {
+		uint8_t *src = (uint8_t *)tile->devPrivate.ptr + tile->devKind*h;
+		uint8_t *dst = (uint8_t *)ptr + 8*cpp*h;
+
+		w = tile->drawable.width*cpp;
+		memcpy(dst, src, w);
+		while (w < 8*cpp) {
+			memcpy(dst+w, dst, w);
+			w *= 2;
+		}
+	}
+	while (h < 8) {
+		memcpy((uint8_t*)ptr + h*w, ptr, h*w);
+		h *= 2;
+	}
+
+	ret = sna_poly_fill_rect_tiled_8x8_blt(drawable, bo, damage,
+					       upload, gc, n, rect,
+					       extents, clipped);
+
+	kgem_bo_destroy(&sna->kgem, upload);
+	return ret;
+}
+
 static bool
 sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
 			     struct kgem_bo *bo,
@@ -9459,6 +9730,25 @@ sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
 	 * RENDER.
 	 */
 
+	if ((tile->drawable.width | tile->drawable.height) == 8) {
+		bool ret;
+
+		tile_bo = sna_pixmap_get_source_bo(tile);
+		ret = sna_poly_fill_rect_tiled_8x8_blt(drawable, bo, damage,
+						       tile_bo, gc, n, rect,
+						       extents, clipped);
+		kgem_bo_destroy(&sna->kgem, tile_bo);
+
+		return ret;
+	}
+
+	if ((tile->drawable.width | tile->drawable.height) <= 0xc &&
+	    is_power_of_two(tile->drawable.width) &&
+	    is_power_of_two(tile->drawable.height))
+		return sna_poly_fill_rect_tiled_nxm_blt(drawable, bo, damage,
+							gc, n, rect,
+							extents, clipped);
+
 	tile_bo = sna_pixmap_get_source_bo(tile);
 	if (tile_bo == NULL) {
 		DBG(("%s: unable to move tile go GPU, fallback\n",
diff --git a/src/sna/sna_reg.h b/src/sna/sna_reg.h
index 551d64b..2628236 100644
--- a/src/sna/sna_reg.h
+++ b/src/sna/sna_reg.h
@@ -51,6 +51,7 @@
 #define XY_TEXT_IMMEDIATE_BLT		((2<<29)|(0x31<<22)|(1<<16))
 #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
 #define SRC_COPY_BLT_CMD		((2<<29)|(0x43<<22)|0x4)
+#define XY_PAT_BLT			((2<<29)|(0x51<<22)|0x4)
 #define XY_PAT_BLT_IMMEDIATE		((2<<29)|(0x72<<22))
 #define XY_MONO_PAT			((0x2<<29)|(0x52<<22)|0x7)
 #define XY_MONO_SRC_COPY		((0x2<<29)|(0x54<<22)|(0x6))
commit ac182a006732525a921a9c539e5ebfb537ad3b52
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 23 11:05:05 2012 +0100

    sna: Hold a reference to the full stipple pattern for repeated tiles
    
    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 5f14f4e..9ae8775 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -10440,6 +10440,7 @@ sna_poly_fill_rect_stippled_n_box__imm(struct sna *sna,
 static void
 sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 				  struct kgem_bo *bo,
+				  struct kgem_bo **tile,
 				  uint32_t br00, uint32_t br13,
 				  const GC *gc,
 				  const BoxRec *box,
@@ -10471,6 +10472,7 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 		row = oy * stride;
 		for (x1 = box->x1; x1 < box->x2; x1 = x2) {
 			int bx1, bx2, bw, bh, len, ox;
+			bool use_tile;
 
 			x2 = box->x2;
 			ox = (x1 - origin->x) % w;
@@ -10483,11 +10485,14 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 				x2 = x1 + bx2-ox;
 			}
 
-			DBG(("%s: box((%d, %d)x(%d, %d)) origin=(%d, %d), pat=(%d, %d), up=(%d, %d), stipple=%dx%d\n",
+			use_tile = y2-y1 == h && x2-x1 == w;
+
+			DBG(("%s: box((%d, %d)x(%d, %d)) origin=(%d, %d), pat=(%d, %d), up=(%d, %d), stipple=%dx%d, full tile?=%d\n",
 			     __FUNCTION__,
 			     x1, y1, x2-x1, y2-y1,
 			     origin->x, origin->y,
-			     ox, oy, bx1, bx2, w, h));
+			     ox, oy, bx1, bx2, w, h,
+			     use_tile));
 
 			bw = (bx2 - bx1 + 7)/8;
 			bw = ALIGN(bw, 2);
@@ -10504,7 +10509,7 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 
 			b = sna->kgem.batch + sna->kgem.nbatch;
 
-			if (len <= 128) {
+			if (!use_tile && len <= 128) {
 				uint8_t *dst, *src;
 
 				b[0] = XY_MONO_SRC_COPY_IMM;
@@ -10540,15 +10545,20 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 					src += len;
 				} while (--bh);
 			} else {
+				bool has_tile = use_tile && *tile;
 				struct kgem_bo *upload;
 				uint8_t *dst, *src;
 				void *ptr;
 
-				upload = kgem_create_buffer(&sna->kgem, bw*bh,
-							    KGEM_BUFFER_WRITE_INPLACE,
-							    &ptr);
-				if (!upload)
-					return;
+				if (has_tile) {
+					upload = kgem_bo_reference(*tile);
+				} else {
+					upload = kgem_create_buffer(&sna->kgem, bw*bh,
+								    KGEM_BUFFER_WRITE_INPLACE,
+								    &ptr);
+					if (!upload)
+						return;
+				}
 
 				b = sna->kgem.batch + sna->kgem.nbatch;
 				b[0] = br00 | (ox & 7) << 17;
@@ -10571,20 +10581,24 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 
 				sna->kgem.nbatch += 8;
 
-				dst = ptr;
-				len = stride;
-				src = gc->stipple->devPrivate.ptr;
-				src += row + (ox >> 3);
-				len -= bw;
-				do {
-					int i = bw;
+				if (!has_tile) {
+					dst = ptr;
+					len = stride;
+					src = gc->stipple->devPrivate.ptr;
+					src += row + (ox >> 3);
+					len -= bw;
 					do {
-						*dst++ = byte_reverse(*src++);
-						*dst++ = byte_reverse(*src++);
-						i -= 2;
-					} while (i);
-					src += len;
-				} while (--bh);
+						int i = bw;
+						do {
+							*dst++ = byte_reverse(*src++);
+							*dst++ = byte_reverse(*src++);
+							i -= 2;
+						} while (i);
+						src += len;
+					} while (--bh);
+					if (use_tile)
+						*tile = kgem_bo_reference(upload);
+				}
 
 				kgem_bo_destroy(&sna->kgem, upload);
 			}
@@ -10740,6 +10754,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	DDXPointRec origin = gc->patOrg;
+	struct kgem_bo *tile = NULL;
 	int16_t dx, dy;
 	uint32_t br00, br13;
 
@@ -10784,7 +10799,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 			box.x2 = box.x1 + r->width;
 			box.y2 = box.y1 + r->height;
 
-			sna_poly_fill_rect_stippled_n_box(sna, bo,
+			sna_poly_fill_rect_stippled_n_box(sna, bo, &tile,
 							  br00, br13, gc,
 							  &box, &origin);
 			r++;
@@ -10822,7 +10837,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 				box.x1 += dx; box.x2 += dx;
 				box.y1 += dy; box.y2 += dy;
 
-				sna_poly_fill_rect_stippled_n_box(sna, bo,
+				sna_poly_fill_rect_stippled_n_box(sna, bo, &tile,
 								  br00, br13, gc,
 								  &box, &origin);
 			} while (--n);
@@ -10861,7 +10876,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 					box.x1 += dx; box.x2 += dx;
 					box.y1 += dy; box.y2 += dy;
 
-					sna_poly_fill_rect_stippled_n_box(sna, bo,
+					sna_poly_fill_rect_stippled_n_box(sna, bo, &tile,
 									  br00, br13, gc,
 									  &box, &origin);
 				}
@@ -10870,6 +10885,8 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 	}
 
 	assert_pixmap_damage(pixmap);
+	if (tile)
+		kgem_bo_destroy(&sna->kgem, tile);
 	sna->blt_state.fill_bo = 0;
 	return true;
 }


More information about the xorg-commit mailing list