xf86-video-intel: 5 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_dri.c src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jan 31 02:31:39 PST 2012


 src/sna/kgem.c      |   14 ++++++++++----
 src/sna/sna_accel.c |   24 ++++++++++++++++++++++--
 src/sna/sna_dri.c   |   39 ++++++++++++++++++++++++++++-----------
 src/sna/sna_io.c    |   36 +++++++++++++++++++++++++++---------
 4 files changed, 87 insertions(+), 26 deletions(-)

New commits:
commit 9c1f8a768ca1f762c722f63bab2747e4ff1fd773
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 31 10:29:02 2012 +0000

    sna: Avoid converting requested Y to X tiling for large pitches on gen4+
    
    The only strong requirement is that to utilize large pitches, the object
    must be tiled. Having it as X tiling is a pure convenience to facilitate
    use of the blitter. A DRI client may want to keep using Y tiling
    instead.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 0b2e1d6..311bac4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2151,7 +2151,10 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
 		if (width*bpp > (MAXSHORT-512) * 8) {
 			DBG(("%s: large pitch [%d], forcing TILING_X\n",
 			     __FUNCTION__, width*bpp/8));
-			tiling = -I915_TILING_X;
+			if (tiling > 0)
+				tiling = -tiling;
+			else if (tiling == 0)
+				tiling = -I915_TILING_X;
 		} else if (tiling && (width|height) > 8192) {
 			DBG(("%s: large tiled buffer [%dx%d], forcing TILING_X\n",
 			     __FUNCTION__, width, height));
commit e872c1011fc7b67683703fd891234f07dd7acd04
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 31 10:21:05 2012 +0000

    sna/dri: We need to reduce tiling on older gen if we cannot fence
    
    Only apply the architectural limits to enable bo creation for DRI buffers.
    
    Reported-by: Alban Browaeys <prahal at yahoo.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45414
    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 2245c03..d0e19cf 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -127,19 +127,37 @@ static inline struct kgem_bo *ref(struct kgem_bo *bo)
 /* Prefer to enable TILING_Y if this buffer will never be a
  * candidate for pageflipping
  */
-static bool color_use_tiling_y(struct sna *sna, DrawablePtr drawable)
+static uint32_t color_tiling(struct sna *sna, DrawablePtr drawable)
 {
-	if (!COLOR_PREFER_TILING_Y)
-		return false;
+	uint32_t tiling;
 
-	return (drawable->width != sna->front->drawable.width ||
-		drawable->height != sna->front->drawable.height);
+	if (COLOR_PREFER_TILING_Y &&
+	    (drawable->width  != sna->front->drawable.width ||
+	     drawable->height != sna->front->drawable.height))
+		tiling = I915_TILING_Y;
+	else
+		tiling = I915_TILING_X;
+
+	return kgem_choose_tiling(&sna->kgem, -tiling,
+				  drawable->width,
+				  drawable->height,
+				  drawable->bitsPerPixel);
+}
+
+static uint32_t other_tiling(struct sna *sna, DrawablePtr drawable)
+{
+	/* XXX Can mix color X / depth Y? */
+	return kgem_choose_tiling(&sna->kgem, -I915_TILING_Y,
+				  drawable->width,
+				  drawable->height,
+				  drawable->bitsPerPixel);
 }
 
 static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 					  PixmapPtr pixmap)
 {
 	struct sna_pixmap *priv;
+	uint32_t tiling;
 
 	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
 	if (priv == NULL)
@@ -148,9 +166,9 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	if (priv->flush)
 		return ref(priv->gpu_bo);
 
-	if (priv->gpu_bo->tiling != I915_TILING_Y &&
-	    color_use_tiling_y(sna, &pixmap->drawable))
-		sna_pixmap_change_tiling(pixmap, I915_TILING_Y);
+	tiling = color_tiling(sna, &pixmap->drawable);
+	if (priv->gpu_bo->tiling != tiling)
+		sna_pixmap_change_tiling(pixmap, tiling);
 
 	/* We need to submit any modifications to and reads from this
 	 * buffer before we send any reply to the Client.
@@ -209,7 +227,7 @@ sna_dri_create_buffer(DrawablePtr drawable,
 				    drawable->width,
 				    drawable->height,
 				    drawable->bitsPerPixel,
-				    color_use_tiling_y(sna, drawable) ?  I915_TILING_Y : I915_TILING_X,
+				    color_tiling(sna, drawable),
 				    CREATE_EXACT);
 		break;
 
@@ -252,8 +270,7 @@ sna_dri_create_buffer(DrawablePtr drawable,
 		bpp = format ? format : drawable->bitsPerPixel,
 		bo = kgem_create_2d(&sna->kgem,
 				    drawable->width, drawable->height, bpp,
-				    //sna->kgem.gen >= 40 ? I915_TILING_Y : I915_TILING_X,
-				    I915_TILING_Y,
+				    other_tiling(sna, drawable),
 				    CREATE_EXACT);
 		break;
 
commit a4caf67d8da37d04f8915d96b10411ba7267937e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 31 00:35:42 2012 +0000

    sna: Trim tile sizes to fit into bo cache
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index ca7eafa..0b2e1d6 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -692,13 +692,14 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	if (kgem->max_gpu_size > kgem->max_cpu_size)
 		kgem->max_gpu_size = kgem->max_cpu_size;
 
-	kgem->max_tile_size = kgem->aperture_total / 4;
+	kgem->max_tile_size = MAX_CACHE_SIZE;
 	if (kgem->max_tile_size > kgem->max_gpu_size / 2)
 		kgem->max_tile_size = kgem->max_gpu_size / 2;
 
 	totalram = total_ram_size();
 	if (totalram == 0) {
-		DBG(("%s: total ram size unknown, assuming maximum of total aperture\n"));
+		DBG(("%s: total ram size unknown, assuming maximum of total aperture\n",
+		     __FUNCTION__));
 		totalram = kgem->aperture_total;
 	}
 	if (kgem->max_object_size > totalram / 2)
@@ -3193,7 +3194,9 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 #if !DBG_NO_MAP_UPLOAD
 	/* Be a little more generous and hope to hold fewer mmappings */
 	alloc = ALIGN(2*size, kgem->partial_buffer_size);
-	if (alloc > kgem->max_gpu_size)
+	if (alloc > kgem->max_tile_size)
+		alloc = ALIGN(size, kgem->partial_buffer_size);
+	if (alloc > kgem->max_tile_size)
 		alloc = PAGE_ALIGN(size);
 	alloc /= PAGE_SIZE;
 	if (kgem->has_cpu_bo) {
commit 3f7c1646c78d8854c88b214d3699e51839ba9711
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 31 00:09:42 2012 +0000

    sna: Check that the intermediate IO buffer can also be used for blitting
    
    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 e35be97..3115bd7 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -716,8 +716,8 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 	} else {
 		struct sna_pixmap *priv;
 
-		DBG(("%s: creating GPU pixmap %dx%d, stride=%d\n",
-		     __FUNCTION__, width, height, pad));
+		DBG(("%s: creating GPU pixmap %dx%d, stride=%d, flags=%x\n",
+		     __FUNCTION__, width, height, pad, flags));
 
 		pixmap = create_pixmap(sna, screen, 0, 0, depth, usage);
 		if (pixmap == NullPixmap)
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 4f86f8d..f4278be 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -59,11 +59,16 @@ box_intersect(BoxPtr a, const BoxRec *b)
 	return a->x1 < a->x2 && a->y1 < a->y2;
 }
 
+static inline bool upload_too_large(struct sna *sna, int width, int height)
+{
+	return width * height * 4 > sna->kgem.max_tile_size;
+}
+
 static inline bool must_tile(struct sna *sna, int width, int height)
 {
 	return (width  > sna->render.max_3d_size ||
 		height > sna->render.max_3d_size ||
-		width * height * 4 > sna->kgem.max_tile_size);
+		upload_too_large(sna, width, height));
 }
 
 static void read_boxes_inplace(struct kgem *kgem,
@@ -118,6 +123,7 @@ void sna_read_boxes(struct sna *sna,
 	void *ptr;
 	int src_pitch, cpp, offset;
 	int n, cmd, br13;
+	bool can_blt;
 
 	DBG(("%s x %d, src=(handle=%d, offset=(%d,%d)), dst=(size=(%d, %d), offset=(%d,%d))\n",
 	     __FUNCTION__, nbox, src_bo->handle, src_dx, src_dy,
@@ -154,6 +160,7 @@ fallback:
 		return;
 	}
 
+	can_blt = kgem_bo_can_blt(kgem, src_bo);
 	extents = box[0];
 	for (n = 1; n < nbox; n++) {
 		if (box[n].x1 < extents.x1)
@@ -161,6 +168,9 @@ fallback:
 		if (box[n].x2 > extents.x2)
 			extents.x2 = box[n].x2;
 
+		if (can_blt)
+			can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4);
+
 		if (box[n].y1 < extents.y1)
 			extents.y1 = box[n].y1;
 		if (box[n].y2 > extents.y2)
@@ -173,9 +183,8 @@ fallback:
 	}
 
 	/* Try to avoid switching rings... */
-	if (kgem->ring == KGEM_RENDER ||
-	    !kgem_bo_can_blt(kgem, src_bo) ||
-	    must_tile(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
+	if (!can_blt || kgem->ring == KGEM_RENDER ||
+	    upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
 		PixmapRec tmp;
 
 		tmp.drawable.width  = extents.x2 - extents.x1;
@@ -531,6 +540,7 @@ bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
 	void *ptr;
 	int offset;
 	int n, cmd, br13;
+	bool can_blt;
 
 	DBG(("%s x %d\n", __FUNCTION__, nbox));
 
@@ -542,6 +552,7 @@ fallback:
 					   box, nbox);
 	}
 
+	can_blt = kgem_bo_can_blt(kgem, dst_bo);
 	extents = box[0];
 	for (n = 1; n < nbox; n++) {
 		if (box[n].x1 < extents.x1)
@@ -549,6 +560,9 @@ fallback:
 		if (box[n].x2 > extents.x2)
 			extents.x2 = box[n].x2;
 
+		if (can_blt)
+			can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4);
+
 		if (box[n].y1 < extents.y1)
 			extents.y1 = box[n].y1;
 		if (box[n].y2 > extents.y2)
@@ -556,9 +570,8 @@ fallback:
 	}
 
 	/* Try to avoid switching rings... */
-	if (kgem->ring == KGEM_RENDER ||
-	    !kgem_bo_can_blt(kgem, dst_bo) ||
-	    must_tile(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
+	if (!can_blt || kgem->ring == KGEM_RENDER ||
+	    upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
 		PixmapRec tmp;
 
 		tmp.drawable.width  = extents.x2 - extents.x1;
@@ -579,6 +592,7 @@ fallback:
 			BoxRec tile, stack[64], *clipped, *c;
 			int step;
 
+tile:
 			step = MIN(sna->render.max_3d_size,
 				   8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel);
 			while (step * step * 4 > sna->kgem.max_tile_size)
@@ -693,7 +707,7 @@ fallback:
 			kgem_bo_destroy(&sna->kgem, src_bo);
 
 			if (!n)
-				goto fallback;
+				goto tile;
 		}
 
 		return true;
@@ -1069,9 +1083,13 @@ indirect_replace(struct sna *sna,
 	if ((int)pixmap->devKind * pixmap->drawable.height >> 12 > kgem->half_cpu_cache_pages)
 		return false;
 
-	if (bo->tiling == I915_TILING_Y || kgem->ring == KGEM_RENDER) {
+	if (kgem->ring == KGEM_RENDER || !kgem_bo_can_blt(kgem, bo)) {
 		BoxRec box;
 
+		assert(!must_tile(sna,
+				  pixmap->drawable.width,
+				  pixmap->drawable.height));
+
 		src_bo = kgem_create_buffer_2d(kgem,
 					       pixmap->drawable.width,
 					       pixmap->drawable.height,
commit e504fab6c5354ae9d18ccefb10bd586fa49b924c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 30 23:49:18 2012 +0000

    sna: Discard the cleared GPU buffer upon PutImage to the CPU buffer
    
    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 26fd1ab..e35be97 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2533,6 +2533,26 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, false))
 		return true;
 
+	if (priv->clear) {
+		DBG(("%s: applying clear [%08x]\n",
+		     __FUNCTION__, priv->clear_color));
+
+		pixman_fill(pixmap->devPrivate.ptr,
+			    pixmap->devKind/sizeof(uint32_t),
+			    pixmap->drawable.bitsPerPixel,
+			    0, 0,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    priv->clear_color);
+
+		sna_damage_all(&priv->cpu_damage,
+			       pixmap->drawable.width,
+			       pixmap->drawable.height);
+		sna_pixmap_free_gpu(sna, priv);
+		priv->undamaged = false;
+		priv->clear = false;
+	}
+
 	if (!DAMAGE_IS_ALL(priv->cpu_damage)) {
 		DBG(("%s: marking damage\n", __FUNCTION__));
 		if (region_subsumes_drawable(region, &pixmap->drawable)) {


More information about the xorg-commit mailing list