xf86-video-intel: 4 commits - src/sna/kgem.c src/sna/sna.h src/sna/sna_render.c src/sna/sna_tiling.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Apr 28 01:03:25 PDT 2014


 src/sna/kgem.c       |   90 ++++++++++++++++++++++++---------------------------
 src/sna/sna.h        |   17 +++++++++
 src/sna/sna_render.c |    8 +++-
 src/sna/sna_tiling.c |   48 +++++++++++++++------------
 4 files changed, 94 insertions(+), 69 deletions(-)

New commits:
commit f0042850494ac16149ba310c910ca08f86c191fa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 28 08:37:11 2014 +0100

    sna: Rearrange final aperture check
    
    If we cross the high water mark, first flush the batch, then check the
    remaining pages to see if they fit into the aperture.
    
    Reported-by: Bruno Prémont
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index bbd8a06..728f918 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4971,35 +4971,34 @@ inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
 
 static bool aperture_check(struct kgem *kgem, unsigned num_pages)
 {
-	if (kgem->aperture) {
-		struct drm_i915_gem_get_aperture aperture;
+	struct drm_i915_gem_get_aperture aperture;
+	int reserve;
 
-		VG_CLEAR(aperture);
-		aperture.aper_available_size = kgem->aperture_high;
-		aperture.aper_available_size *= PAGE_SIZE;
-		(void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+	if (kgem->aperture)
+		return false;
 
-		DBG(("%s: aperture required %ld bytes, available %ld bytes\n",
-		     __FUNCTION__,
-		     (long)num_pages * PAGE_SIZE,
-		     (long)aperture.aper_available_size));
+	/* Leave some space in case of alignment issues */
+	reserve = kgem->aperture_mappable / 2;
+	if (kgem->gen < 033 && reserve < kgem->aperture_max_fence)
+		reserve = kgem->aperture_max_fence;
+	if (!kgem->has_llc)
+		reserve += kgem->nexec * PAGE_SIZE * 2;
 
-		/* Leave some space in case of alignment issues */
-		aperture.aper_available_size -= 1024 * 1024;
-		aperture.aper_available_size -= kgem->aperture_mappable * PAGE_SIZE / 2;
-		if (kgem->gen < 033)
-			aperture.aper_available_size -= kgem->aperture_max_fence * PAGE_SIZE;
-		if (!kgem->has_llc)
-			aperture.aper_available_size -= 2 * kgem->nexec * PAGE_SIZE;
+	DBG(("%s: num_pages=%d, holding %d pages in reserve, total aperture %d\n",
+	     __FUNCTION__, num_pages, reserve, kgem->aperture_total));
+	num_pages += reserve;
 
-		DBG(("%s: num_pages=%d, estimated max usable=%ld\n",
-		     __FUNCTION__, num_pages, (long)(aperture.aper_available_size/PAGE_SIZE)));
+	VG_CLEAR(aperture);
+	aperture.aper_available_size = kgem->aperture_total;
+	aperture.aper_available_size *= PAGE_SIZE;
+	(void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
 
-		if (num_pages <= aperture.aper_available_size / PAGE_SIZE)
-			return true;
-	}
+	DBG(("%s: aperture required %ld bytes, available %ld bytes\n",
+	     __FUNCTION__,
+	     (long)num_pages * PAGE_SIZE,
+	     (long)aperture.aper_available_size));
 
-	return false;
+	return num_pages <= aperture.aper_available_size / PAGE_SIZE;
 }
 
 static inline bool kgem_flush(struct kgem *kgem, bool flush)
@@ -5066,8 +5065,7 @@ bool kgem_check_bo(struct kgem *kgem, ...)
 	if (num_pages + kgem->aperture > kgem->aperture_high) {
 		DBG(("%s: final aperture usage (%d + %d) is greater than high water mark (%d)\n",
 		     __FUNCTION__, kgem->aperture, num_pages, kgem->aperture_high));
-		if (!aperture_check(kgem, num_pages + kgem->aperture))
-			return false;
+		return aperture_check(kgem, num_pages);
 	}
 
 	if (busy)
@@ -5169,8 +5167,7 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 	if (kgem->aperture + kgem->aperture_fenced + num_pages(bo) > kgem->aperture_high) {
 		DBG(("%s: final aperture usage (%d + %d) is greater than high water mark (%d)\n",
 		     __FUNCTION__, kgem->aperture, num_pages(bo), kgem->aperture_high));
-		if (!aperture_check(kgem, num_pages(bo) + kgem->aperture + kgem->aperture_fenced))
-			return false;
+		return aperture_check(kgem, num_pages(bo));
 	}
 
 	if (bo->rq)
@@ -5269,8 +5266,7 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 	if (num_pages + kgem->aperture > kgem->aperture_high - kgem->aperture_fenced) {
 		DBG(("%s: final aperture usage (%d + %d + %d) is greater than high water mark (%d)\n",
 		     __FUNCTION__, kgem->aperture, kgem->aperture_fenced, num_pages, kgem->aperture_high));
-		if (!aperture_check(kgem, num_pages + kgem->aperture + kgem->aperture_fenced))
-			return false;
+		return aperture_check(kgem, num_pages);
 	}
 
 	if (busy)
commit 7a685d1d7b63a1589ba0fd09168d4f95d18fcae5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 28 08:31:59 2014 +0100

    sna: Add a minor DBG for tiled copies
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index 2552fd3..17826a8 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -1018,6 +1018,9 @@ bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu,
 	int max_size, step;
 	bool ret = false;
 
+	DBG(("%s: alu=%d, src size=%d, dst size=%d\n", __FUNCTION__,
+	     alu, kgem_bo_size(src_bo), kgem_bo_size(dst_bo)));
+
 	if (wedged(sna) ||
 	    !kgem_bo_can_blt(&sna->kgem, src_bo) ||
 	    !kgem_bo_can_blt(&sna->kgem, dst_bo)) {
commit 3e330f3980b7bacad30b25ff144e4162acc854bb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 28 08:15:35 2014 +0100

    sna: Refine fence packing estimates
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 5704f9a..bbd8a06 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -5064,8 +5064,8 @@ bool kgem_check_bo(struct kgem *kgem, ...)
 	}
 
 	if (num_pages + kgem->aperture > kgem->aperture_high) {
-		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
-		     __FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high));
+		DBG(("%s: final aperture usage (%d + %d) is greater than high water mark (%d)\n",
+		     __FUNCTION__, kgem->aperture, num_pages, kgem->aperture_high));
 		if (!aperture_check(kgem, num_pages + kgem->aperture))
 			return false;
 	}
@@ -5109,13 +5109,13 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 			if (size > kgem->aperture_max_fence)
 				kgem->aperture_max_fence = size;
 			size += kgem->aperture_fenced;
-			if (kgem->gen < 033)
-				size += kgem->aperture_max_fence;
+			if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
+				size = 2 * kgem->aperture_max_fence;
 			if (kgem->aperture_total == kgem->aperture_mappable)
 				size += kgem->aperture;
 			if (size > kgem->aperture_mappable) {
-				DBG(("%s: estimated fence space required [%d] exceed aperture [%d]\n",
-				     __FUNCTION__, size, kgem->aperture_mappable));
+				DBG(("%s: estimated fence space required %d (fenced=%d, max_fence=%d, aperture=%d) exceeds aperture %d\n",
+				     __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_mappable));
 				return false;
 			}
 		}
@@ -5155,20 +5155,20 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 		if (size > kgem->aperture_max_fence)
 			kgem->aperture_max_fence = size;
 		size += kgem->aperture_fenced;
-		if (kgem->gen < 033)
-			size += kgem->aperture_max_fence;
+		if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
+			size = 2 * kgem->aperture_max_fence;
 		if (kgem->aperture_total == kgem->aperture_mappable)
 			size += kgem->aperture;
 		if (size > kgem->aperture_mappable) {
-			DBG(("%s: estimated fence space required [%d] exceed aperture [%d]\n",
-			     __FUNCTION__, size, kgem->aperture_mappable));
+			DBG(("%s: estimated fence space required %d (fenced=%d, max_fence=%d, aperture=%d) exceeds aperture %d\n",
+			     __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_mappable));
 			return false;
 		}
 	}
 
 	if (kgem->aperture + kgem->aperture_fenced + num_pages(bo) > kgem->aperture_high) {
-		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
-		     __FUNCTION__, num_pages(bo) + kgem->aperture, kgem->aperture_high));
+		DBG(("%s: final aperture usage (%d + %d) is greater than high water mark (%d)\n",
+		     __FUNCTION__, kgem->aperture, num_pages(bo), kgem->aperture_high));
 		if (!aperture_check(kgem, num_pages(bo) + kgem->aperture + kgem->aperture_fenced))
 			return false;
 	}
@@ -5249,13 +5249,13 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 
 		size = kgem->aperture_fenced;
 		size += fenced_size;
-		if (kgem->gen < 033)
-			size += kgem->aperture_max_fence;
+		if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
+			size = 2 * kgem->aperture_max_fence;
 		if (kgem->aperture_total == kgem->aperture_mappable)
 			size += kgem->aperture;
 		if (size > kgem->aperture_mappable) {
-			DBG(("%s: estimated fence space required [%d] exceed aperture [%d]\n",
-			     __FUNCTION__, size, kgem->aperture_mappable));
+			DBG(("%s: estimated fence space required %d (fenced=%d, max_fence=%d, aperture=%d) exceeds aperture %d\n",
+			     __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_mappable));
 			return false;
 		}
 	}
@@ -5267,8 +5267,8 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 		return false;
 
 	if (num_pages + kgem->aperture > kgem->aperture_high - kgem->aperture_fenced) {
-		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
-		     __FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high));
+		DBG(("%s: final aperture usage (%d + %d + %d) is greater than high water mark (%d)\n",
+		     __FUNCTION__, kgem->aperture, kgem->aperture_fenced, num_pages, kgem->aperture_high));
 		if (!aperture_check(kgem, num_pages + kgem->aperture + kgem->aperture_fenced))
 			return false;
 	}
commit 534a0e6433a37c95f7181f7ce9046a4e7c82532d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 28 07:53:13 2014 +0100

    sna: Factor in destination sizes for choosing intermediate tiling bo size
    
    When tiling, factor in the destination usage of the aperture in case
    that reduces the available aperture for the intermediate bo.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 1e23ac1..8522a49 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -524,6 +524,23 @@ static inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap)
 		(sna->flags & SNA_NO_WAIT) == 0);
 }
 
+static inline int sna_max_tile_copy_size(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst)
+{
+	int max_size;
+
+	max_size = sna->kgem.aperture_high * PAGE_SIZE;
+	max_size -= MAX(kgem_bo_size(src), kgem_bo_size(dst));
+	if (max_size <= 0) {
+		DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__));
+		return 0;
+	}
+
+	if (max_size > sna->kgem.max_copy_tile_size)
+		max_size = sna->kgem.max_copy_tile_size;
+	DBG(("%s: using max tile size of %d\n", __FUNCTION__, max_size));
+	return max_size;
+}
+
 PixmapPtr sna_pixmap_create_upload(ScreenPtr screen,
 				   int width, int height, int depth,
 				   unsigned flags);
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 73dcf45..b67bd26 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -708,7 +708,7 @@ static int sna_render_picture_downsample(struct sna *sna,
 	struct sna_pixmap *priv;
 	pixman_transform_t t;
 	PixmapPtr tmp;
-	int width, height, size;
+	int width, height, size, max_size;
 	int sx, sy, sw, sh;
 	int error, ret = 0;
 	BoxRec box, b;
@@ -818,8 +818,12 @@ fixup:
 	ValidatePicture(tmp_src);
 
 	/* Use a small size to accommodate enlargement through tile alignment */
+	max_size = sna_max_tile_copy_size(sna, sna_pixmap(pixmap)->gpu_bo, priv->gpu_bo);
+	if (max_size == 0)
+		goto cleanup_dst;
+
 	size = sna->render.max_3d_size - 4096 / pixmap->drawable.bitsPerPixel;
-	while (size * size * 4 > sna->kgem.max_copy_tile_size)
+	while (size * size * 4 > max_size)
 		size /= 2;
 
 	sw = size / sx - 2 * sx;
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index 5fc7b40..2552fd3 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -138,14 +138,19 @@ sna_tiling_composite_done(struct sna *sna,
 {
 	struct sna_tile_state *tile = op->priv;
 	struct sna_composite_op tmp;
-	int x, y, n, step;
+	int x, y, n, step, max_size;
 
 	/* Use a small step to accommodate enlargement through tile alignment */
 	step = sna->render.max_3d_size;
 	if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) ||
 	    tile->dst_y & 63)
 		step /= 2;
-	while (step * step * 4 > sna->kgem.max_copy_tile_size)
+
+	max_size = sna_max_tile_copy_size(sna, op->dst.bo, op->dst.bo);
+	if (max_size == 0)
+		goto done;
+
+	while (step * step * 4 > max_size)
 		step /= 2;
 
 	DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__,
@@ -373,7 +378,7 @@ sna_tiling_composite_spans_done(struct sna *sna,
 {
 	struct sna_tile_state *tile = op->base.priv;
 	struct sna_composite_spans_op tmp;
-	int x, y, n, step;
+	int x, y, n, step, max_size;
 	bool force_fallback = false;
 
 	/* Use a small step to accommodate enlargement through tile alignment */
@@ -381,7 +386,12 @@ sna_tiling_composite_spans_done(struct sna *sna,
 	if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) ||
 	    tile->dst_y & 63)
 		step /= 2;
-	while (step * step * 4 > sna->kgem.max_copy_tile_size)
+
+	max_size = sna_max_tile_copy_size(sna, op->base.dst.bo, op->base.dst.bo);
+	if (max_size == 0)
+		goto done;
+
+	while (step * step * 4 > max_size)
 		step /= 2;
 
 	DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__,
@@ -589,7 +599,7 @@ sna_tiling_fill_boxes(struct sna *sna,
 {
 	RegionRec region, tile, this;
 	struct kgem_bo *bo;
-	int step;
+	int step, max_size;
 	bool ret = false;
 
 	pixman_region_init_rects(&region, box, n);
@@ -599,7 +609,12 @@ sna_tiling_fill_boxes(struct sna *sna,
 	if (region.extents.x1 & (8*512 / dst->drawable.bitsPerPixel - 1) ||
 	    region.extents.y1 & 63)
 		step /= 2;
-	while (step * step * 4 > sna->kgem.max_copy_tile_size)
+
+	max_size = sna_max_tile_copy_size(sna, dst_bo, dst_bo);
+	if (max_size == 0)
+		goto done;
+
+	while (step * step * 4 > max_size)
 		step /= 2;
 
 	DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n",
@@ -790,14 +805,9 @@ sna_tiling_blt_copy_boxes__with_alpha(struct sna *sna, uint8_t alu,
 		return false;
 	}
 
-	max_size = sna->kgem.aperture_high * PAGE_SIZE;
-	max_size -= MAX(kgem_bo_size(src_bo), kgem_bo_size(dst_bo));
-	if (max_size <= 0) {
-		DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__));
+	max_size = sna_max_tile_copy_size(sna, src_bo, dst_bo);
+	if (max_size == 0)
 		return false;
-	}
-	if (max_size > sna->kgem.max_copy_tile_size)
-		max_size = sna->kgem.max_copy_tile_size;
 
 	pixman_region_init_rects(&region, box, nbox);
 
@@ -1019,14 +1029,9 @@ bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		return false;
 	}
 
-	max_size = sna->kgem.aperture_high * PAGE_SIZE;
-	max_size -= MAX(kgem_bo_size(src_bo), kgem_bo_size(dst_bo));
-	if (max_size <= 0) {
-		DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__));
+	max_size = sna_max_tile_copy_size(sna, src_bo, dst_bo);
+	if (max_size == 0)
 		return false;
-	}
-	if (max_size > sna->kgem.max_copy_tile_size)
-		max_size = sna->kgem.max_copy_tile_size;
 
 	pixman_region_init_rects(&region, box, nbox);
 


More information about the xorg-commit mailing list