xf86-video-intel: 4 commits - src/sna/kgem.c src/sna/sna_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Aug 8 15:19:14 PDT 2013


 src/sna/kgem.c    |   88 ++++++++++++++++++++++++++++++++----------------------
 src/sna/sna_dri.c |    3 +
 2 files changed, 55 insertions(+), 36 deletions(-)

New commits:
commit 31b4110b5119ad1643f3e75c5e23a44c4ceb30fe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 8 22:25:57 2013 +0100

    sna: Use create2 to allocate a DISPLAY bo even if we have not enough stolen
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f06c6f2..a04b954 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3802,8 +3802,7 @@ inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
 }
 
 static struct kgem_bo *
-__kgem_bo_create_from_stolen(struct kgem *kgem, int size, int tiling, int pitch)
-
+__kgem_bo_create_as_display(struct kgem *kgem, int size, int tiling, int pitch)
 {
 	struct local_i915_gem_create2 args;
 	struct kgem_bo *bo;
@@ -3818,8 +3817,11 @@ __kgem_bo_create_from_stolen(struct kgem *kgem, int size, int tiling, int pitch)
 	args.tiling_mode = tiling;
 	args.stride = pitch;
 
-	if (drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args))
-		return NULL;
+	if (drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args)) {
+		args.placement = LOCAL_I915_CREATE_PLACEMENT_SYSTEM;
+		if (drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args))
+			return NULL;
+	}
 
 	bo = __kgem_bo_alloc(args.handle, size);
 	if (bo == NULL) {
@@ -3830,7 +3832,9 @@ __kgem_bo_create_from_stolen(struct kgem *kgem, int size, int tiling, int pitch)
 	bo->unique_id = kgem_get_unique_id(kgem);
 	bo->tiling = tiling;
 	bo->pitch = pitch;
-	bo->purged = true; /* for asserts against CPU access */
+	if (args.placement == LOCAL_I915_CREATE_PLACEMENT_STOLEN) {
+		bo->purged = true; /* for asserts against CPU access */
+	}
 	bo->reusable = false; /* so that unclaimed scanouts are freed */
 	bo->domain = DOMAIN_NONE;
 
@@ -3931,7 +3935,7 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			return last;
 		}
 
-		bo = __kgem_bo_create_from_stolen(kgem, size, tiling, pitch);
+		bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch);
 		if (bo)
 			return bo;
 	}
commit 0f82c1a451a2d5763d9cf53b48f55200f7716966
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 8 22:05:34 2013 +0100

    sna: Always reuse scanout bo where possible
    
    When looking for an inactive scanout and all are busy, select the oldest
    for reuse.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index ed90588..f06c6f2 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3878,7 +3878,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 	size /= PAGE_SIZE;
 	bucket = cache_bucket(size);
 
-	if ((flags & (CREATE_SCANOUT | CREATE_INACTIVE)) == CREATE_SCANOUT) {
+	if (flags & CREATE_SCANOUT) {
+		struct kgem_bo *last = NULL;
+
 		list_for_each_entry_reverse(bo, &kgem->scanout, list) {
 			assert(bo->scanout);
 			assert(bo->delta);
@@ -3901,6 +3903,11 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 				bo->pitch = pitch;
 			}
 
+			if (flags & CREATE_INACTIVE && bo->rq) {
+				last = bo;
+				continue;
+			}
+
 			list_del(&bo->list);
 
 			bo->unique_id = kgem_get_unique_id(kgem);
@@ -3912,6 +3919,18 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			return bo;
 		}
 
+		if (last) {
+			list_del(&last->list);
+
+			last->unique_id = kgem_get_unique_id(kgem);
+			DBG(("  1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n",
+			     last->pitch, last->tiling, last->handle, last->unique_id));
+			assert(last->pitch*kgem_aligned_height(kgem, height, last->tiling) <= kgem_bo_size(last));
+			assert_tiling(kgem, last);
+			last->refcnt = 1;
+			return last;
+		}
+
 		bo = __kgem_bo_create_from_stolen(kgem, size, tiling, pitch);
 		if (bo)
 			return bo;
commit bd7e653e1ee009e225b0bbf60dcaebc9b0fa2788
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 8 22:03:16 2013 +0100

    sna: Avoid leaking stolen framebuffer bo
    
    Framebuffers created from stolen bo were not being released and so the
    kernel would keep the fb and bo alive, causing the memory to be
    remain unreusable whilst X lived and us to leak all available stolen
    memory.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 498c200..ed90588 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1795,30 +1795,6 @@ static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
 		io->used = bo->delta;
 }
 
-static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
-{
-	assert(bo->scanout);
-	assert(!bo->refcnt);
-	assert(bo->exec == NULL);
-	assert(bo->proxy == NULL);
-
-	DBG(("%s: handle=%d, fb=%d (reusable=%d)\n",
-	     __FUNCTION__, bo->handle, bo->delta, bo->reusable));
-	if (bo->delta) {
-		/* XXX will leak if we are not DRM_MASTER. *shrug* */
-		drmIoctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
-		bo->delta = 0;
-	}
-
-	bo->scanout = false;
-	bo->flush = false;
-	bo->reusable = true;
-
-	if (kgem->has_llc &&
-	    !gem_set_cacheing(kgem->fd, bo->handle, SNOOPED))
-		bo->reusable = false;
-}
-
 static bool check_scanout_size(struct kgem *kgem,
 			       struct kgem_bo *bo,
 			       int width, int height)
@@ -3029,15 +3005,34 @@ void kgem_clean_scanout_cache(struct kgem *kgem)
 		struct kgem_bo *bo;
 
 		bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
+
+		assert(bo->scanout);
+		assert(bo->delta);
+		assert(!bo->refcnt);
+		assert(bo->exec == NULL);
+		assert(bo->proxy == NULL);
+
 		if (bo->exec || __kgem_busy(kgem, bo->handle))
 			break;
 
+		DBG(("%s: handle=%d, fb=%d (reusable=%d)\n",
+		     __FUNCTION__, bo->handle, bo->delta, bo->reusable));
 		list_del(&bo->list);
+
+		/* XXX will leak if we are not DRM_MASTER. *shrug* */
+		drmIoctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
+		bo->delta = 0;
+		bo->scanout = false;
+
 		if (!bo->purged) {
-			kgem_bo_clear_scanout(kgem, bo);
-			__kgem_bo_destroy(kgem, bo);
-		} else
-			kgem_bo_free(kgem, bo);
+			bo->reusable = true;
+			if (kgem->has_llc &&
+			    !gem_set_cacheing(kgem->fd, bo->handle, SNOOPED))
+				bo->reusable = false;
+
+		}
+
+		__kgem_bo_destroy(kgem, bo);
 	}
 }
 
commit 097669cd728e612bf3e3c531b83892e37481ee7b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 8 20:44:24 2013 +0100

    sna/dri: Do not create a scanout-capable buffer if not flipping
    
    Avoid paying the penalty of creating an uncached buffer if we never
    intend to flip to it.
    
    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 0083b52..1569251 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -305,7 +305,8 @@ sna_dri_create_buffer(DrawablePtr draw,
 	case DRI2BufferFakeFrontRight:
 		bpp = draw->bitsPerPixel;
 		if (draw->width  == sna->front->drawable.width &&
-		    draw->height == sna->front->drawable.height)
+		    draw->height == sna->front->drawable.height &&
+		    (sna->flags & SNA_NO_FLIP) == 0)
 			flags |= CREATE_SCANOUT;
 		DBG(("%s: creating back buffer %dx%d, suitable for scanout? %d\n",
 		     __FUNCTION__,


More information about the xorg-commit mailing list