xf86-video-intel: 2 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Dec 18 15:13:07 PST 2011


 src/sna/kgem.c      |  108 +++++++++++++++++++++++++++++++++++++++-------------
 src/sna/kgem.h      |    4 +
 src/sna/sna_accel.c |    4 -
 src/sna/sna_io.c    |    3 -
 4 files changed, 90 insertions(+), 29 deletions(-)

New commits:
commit 15a769a66fa1afbcffc642ef980387cffefc6bef
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Dec 18 22:18:02 2011 +0000

    sna: Distinguish between GTT and CPU maps when searching for VMA
    
    Similarly try to avoid borrowing any vma when all we intend to do is
    pwrite.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3d5d4b0..c0034d5 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1446,9 +1446,10 @@ void kgem_cleanup_cache(struct kgem *kgem)
 }
 
 static struct kgem_bo *
-search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
+search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags)
 {
-	struct kgem_bo *bo, *next;
+	struct kgem_bo *bo, *next, *first = NULL;
+	bool use_active = (flags & CREATE_INACTIVE) == 0;
 	struct list *cache;
 
 	cache = use_active ? active(kgem, size): inactive(kgem, size);
@@ -1469,10 +1470,29 @@ search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
 			continue;
 		}
 
-		if (I915_TILING_NONE != bo->tiling &&
-		    gem_set_tiling(kgem->fd, bo->handle,
-				   I915_TILING_NONE, 0) != I915_TILING_NONE)
-			continue;
+		if (bo->map) {
+			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
+				int for_cpu = !!(flags & CREATE_CPU_MAP);
+				if (IS_CPU_MAP(bo->map) != for_cpu) {
+					if (first == NULL)
+						first = bo;
+					continue;
+				}
+			} else {
+				if (first == NULL)
+					first = bo;
+				continue;
+			}
+		}
+
+		if (I915_TILING_NONE != bo->tiling) {
+			if (use_active)
+				continue;
+
+			if (gem_set_tiling(kgem->fd, bo->handle,
+					   I915_TILING_NONE, 0) != I915_TILING_NONE)
+				continue;
+		}
 
 		list_del(&bo->list);
 		if (bo->rq == &_kgem_static_request)
@@ -1494,6 +1514,44 @@ search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
 		return bo;
 	}
 
+	if (first) {
+		if (I915_TILING_NONE != first->tiling) {
+			if (use_active)
+				return NULL;
+
+			if (gem_set_tiling(kgem->fd, first->handle,
+					   I915_TILING_NONE, 0) != I915_TILING_NONE)
+				return NULL;
+
+			if (first->map) {
+				munmap(CPU_MAP(first->map), first->size);
+				first->map = NULL;
+
+				list_del(&first->vma);
+				kgem->vma_count--;
+			}
+		}
+
+		list_del(&first->list);
+		if (first->rq == &_kgem_static_request)
+			list_del(&first->request);
+		if (first->map) {
+			assert(!list_is_empty(&first->vma));
+			list_move_tail(&first->vma, &kgem->vma_cache);
+		}
+
+		first->tiling = I915_TILING_NONE;
+		first->pitch = 0;
+		first->delta = 0;
+		DBG(("  %s: found handle=%d (size=%d) in linear %s cache\n",
+		     __FUNCTION__, first->handle, first->size,
+		     use_active ? "active" : "inactive"));
+		assert(use_active || first->domain != DOMAIN_GPU);
+		assert(!first->needs_flush || use_active);
+		//assert(use_active || !kgem_busy(kgem, first->handle));
+		return first;
+	}
+
 	return NULL;
 }
 
@@ -1528,13 +1586,13 @@ struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size)
 	DBG(("%s(%d)\n", __FUNCTION__, size));
 
 	size = ALIGN(size, PAGE_SIZE);
-	bo = search_linear_cache(kgem, size, false);
+	bo = search_linear_cache(kgem, size, CREATE_INACTIVE);
 	if (bo)
 		return kgem_bo_reference(bo);
 
 	if (!list_is_empty(&kgem->requests)) {
 		if (kgem_retire(kgem)) {
-			bo = search_linear_cache(kgem, size, false);
+			bo = search_linear_cache(kgem, size, CREATE_INACTIVE);
 			if (bo)
 				return kgem_bo_reference(bo);
 		}
@@ -1719,9 +1777,12 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 	if (tiling < 0)
 		tiling = -tiling, exact = 1;
 
-	DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, scanout?=%d)\n", __FUNCTION__,
+	DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d)\n", __FUNCTION__,
 	     width, height, bpp, tiling,
-	     !!exact, !!(flags & CREATE_INACTIVE), !!(flags & CREATE_SCANOUT)));
+	     !!exact, !!(flags & CREATE_INACTIVE),
+	     !!(flags & CREATE_CPU_MAP),
+	     !!(flags & CREATE_GTT_MAP),
+	     !!(flags & CREATE_SCANOUT)));
 
 	assert(_kgem_can_create_2d(kgem, width, height, bpp, exact ? -tiling : tiling));
 	size = kgem_surface_size(kgem,
@@ -1730,7 +1791,8 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 				 width, height, bpp, tiling, &pitch);
 	assert(size && size <= kgem->max_object_size);
 
-	if (flags & CREATE_INACTIVE) {
+	if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
+		int for_cpu = !!(flags & CREATE_CPU_MAP);
 		/* We presume that we will need to upload to this bo,
 		 * and so would prefer to have an active VMA.
 		 */
@@ -1741,6 +1803,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 				assert(bo->rq == NULL);
 				assert(list_is_empty(&bo->request));
 
+				if (IS_CPU_MAP(bo->map) != for_cpu)
+					continue;
+
 				if (size > bo->size || 2*size < bo->size) {
 					DBG(("inactive vma too small/large: %d < %d\n",
 					     bo->size, size));
@@ -2580,9 +2645,9 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 
 		old = NULL;
 		if (!write)
-			old = search_linear_cache(kgem, alloc, true);
+			old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP);
 		if (old == NULL)
-			old = search_linear_cache(kgem, alloc, false);
+			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP);
 		if (old) {
 			DBG(("%s: reusing handle=%d for buffer\n",
 			     __FUNCTION__, old->handle));
@@ -2621,9 +2686,9 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 
 		old = NULL;
 		if (!write)
-			old = search_linear_cache(kgem, alloc, true);
+			old = search_linear_cache(kgem, alloc, 0);
 		if (old == NULL)
-			old = search_linear_cache(kgem, alloc, false);
+			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
 		if (old) {
 			alloc = old->size;
 			bo = malloc(sizeof(*bo) + alloc);
@@ -2873,9 +2938,9 @@ kgem_replace_bo(struct kgem *kgem,
 
 	size = height * pitch;
 
-	dst = search_linear_cache(kgem, size, true);
+	dst = search_linear_cache(kgem, size, 0);
 	if (dst == NULL)
-		dst = search_linear_cache(kgem, size, false);
+		dst = search_linear_cache(kgem, size, CREATE_INACTIVE);
 	if (dst == NULL) {
 		handle = gem_create(kgem->fd, size);
 		if (handle == 0)
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 97eedb5..4e30d58 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -189,7 +189,9 @@ kgem_replace_bo(struct kgem *kgem,
 enum {
 	CREATE_EXACT = 0x1,
 	CREATE_INACTIVE = 0x2,
-	CREATE_SCANOUT = 0x4,
+	CREATE_CPU_MAP = 0x4,
+	CREATE_GTT_MAP = 0x8,
+	CREATE_SCANOUT = 0x10,
 };
 struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			       int width,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index aef002f..c44dcc1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -202,7 +202,7 @@ sna_pixmap_alloc_cpu(struct sna *sna,
 					      pixmap->drawable.height,
 					      pixmap->drawable.bitsPerPixel,
 					      I915_TILING_NONE,
-					      from_gpu ? 0 : CREATE_INACTIVE);
+					      from_gpu ? 0 : CREATE_CPU_MAP | CREATE_INACTIVE);
 		DBG(("%s: allocated CPU handle=%d\n", __FUNCTION__,
 		     priv->cpu_bo->handle));
 
@@ -1286,7 +1286,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap)
 					       pixmap->drawable.bitsPerPixel,
 					       sna_pixmap_choose_tiling(pixmap,
 									default_tiling(pixmap)),
-					       priv->cpu_damage ? CREATE_INACTIVE : 0);
+					       priv->cpu_damage ? CREATE_GTT_MAP | CREATE_INACTIVE : 0);
 		if (priv->gpu_bo == NULL) {
 			assert(list_is_empty(&priv->list));
 			return NULL;
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 767824f..4841845 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -441,7 +441,8 @@ struct kgem_bo *sna_replace(struct sna *sna,
 					pixmap->drawable.width,
 					pixmap->drawable.height,
 					pixmap->drawable.bitsPerPixel,
-					bo->tiling, CREATE_INACTIVE);
+					bo->tiling,
+					CREATE_GTT_MAP | CREATE_INACTIVE);
 		if (new_bo) {
 			kgem_bo_destroy(kgem, bo);
 			bo = new_bo;
commit d0ee695ef091671e2cc69b773f517030ebe961b2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Dec 18 20:28:18 2011 +0000

    sna: the active cache is not marked as purgeable, so skip checking it
    
    Otherwise we do a lot of list walking for no-ops.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 6ac1342..3d5d4b0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1338,12 +1338,6 @@ void kgem_purge_cache(struct kgem *kgem)
 				kgem_bo_free(kgem, bo);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(kgem->active); i++) {
-		list_for_each_entry_safe(bo, next, &kgem->active[i], list)
-			if (!kgem_bo_is_retained(kgem, bo))
-				kgem_bo_free(kgem, bo);
-	}
-
 	kgem->need_purge = false;
 }
 
@@ -1393,8 +1387,7 @@ bool kgem_expire_cache(struct kgem *kgem)
 			bo = list_last_entry(&kgem->inactive[i],
 					     struct kgem_bo, list);
 
-			if (kgem_bo_is_retained(kgem, bo) &&
-			    bo->delta > expire) {
+			if (bo->delta > expire) {
 				idle = false;
 				break;
 			}


More information about the xorg-commit mailing list