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

Chris Wilson ickle at kemper.freedesktop.org
Sun Jan 15 13:47:51 PST 2012


 src/sna/kgem.c               |   75 +++++++++++++++++++------------------------
 src/sna/kgem.h               |   12 ++++++
 src/sna/sna.h                |    2 -
 src/sna/sna_accel.c          |   58 ++++++++++++++++++++++++---------
 src/sna/sna_io.c             |    2 -
 src/sna/sna_video_textured.c |    5 ++
 6 files changed, 94 insertions(+), 60 deletions(-)

New commits:
commit 8652bf7a196f53842db70f5c70aded31b470b0ab
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 19:04:01 2012 +0000

    sna: Don't track an unmatching tiled bo when searching the linear 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 31039de..0075bed 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1848,6 +1848,15 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags)
 			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;
+		}
+
 		if (bo->map) {
 			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
 				int for_cpu = !!(flags & CREATE_CPU_MAP);
@@ -1875,15 +1884,6 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags)
 			}
 		}
 
-		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;
-		}
-
 		if (use_active)
 			kgem_bo_remove_from_active(kgem, bo);
 		else
@@ -1903,9 +1903,7 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags)
 
 	if (first) {
 		if (I915_TILING_NONE != first->tiling) {
-			if (use_active)
-				return NULL;
-
+			assert(!use_active);
 			if (gem_set_tiling(kgem->fd, first->handle,
 					   I915_TILING_NONE, 0) != I915_TILING_NONE)
 				return NULL;
commit cc4b616990fa71e96d38512d8cdb4c3e2abb21c0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 19:55:50 2012 +0000

    sna/video: Increase the level of paranoia
    
    In how many different ways can we check that the scanout is allocated
    before we start decoding video?
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 6f72698..185bc1d 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -479,7 +479,7 @@ sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags)
 static inline Bool
 sna_pixmap_is_gpu(PixmapPtr pixmap)
 {
-	struct sna_pixmap *priv = sna_pixmap(pixmap);
+	struct sna_pixmap *priv = pixmap ? sna_pixmap(pixmap) : NULL;
 	return priv && priv->gpu_bo;
 }
 
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index ba0e146..a72d335 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -229,7 +229,10 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 	Bool flush = false;
 	Bool ret;
 
-	if (!sna_pixmap(pixmap))
+	if (buf == 0)
+		return BadAlloc;
+
+	if (!sna_pixmap_is_gpu(pixmap))
 		return BadAlloc;
 
 	sna_video_frame_init(sna, video, id, width, height, &frame);
commit 7f480ba02c66fcc02bad483731c4c0cf6c746c0d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 18:45:06 2012 +0000

    sna: Tidy search through active bo cache
    
    Perform the assertions upon cache consistency upfront, and tidy the
    indentation.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index cafab51..31039de 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2227,13 +2227,14 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 	for (i = 0; i <= I915_TILING_Y; i++)
 		tiled_height[i] = kgem_aligned_height(kgem, height, i);
 
+	/* Best active match, or first near-miss */
 	next = NULL;
 	cache = active(kgem, size);
-search_active: /* Best active match first */
 	list_for_each_entry(bo, cache, list) {
-		uint32_t s;
-
 		assert(bo->bucket == cache_bucket(size));
+		assert(!bo->purged);
+		assert(bo->refcnt == 0);
+		assert(bo->reusable);
 
 		if (bo->tiling) {
 			if (bo->pitch < pitch) {
@@ -2245,30 +2246,22 @@ search_active: /* Best active match first */
 		} else
 			bo->pitch = untiled_pitch;
 
-		s = bo->pitch * tiled_height[bo->tiling];
-		if (s <= bo->size) {
-			if (bo->tiling != tiling) {
-				if (next == NULL && bo->tiling < tiling)
-					next = bo;
-				continue;
-			}
+		if (bo->pitch * tiled_height[bo->tiling] > bo->size)
+			continue;
 
-			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
-				kgem_bo_free(kgem, bo);
-				bo = NULL;
-				goto search_active;
-			}
+		if (bo->tiling != tiling) {
+			if (next == NULL && bo->tiling < tiling)
+				next = bo;
+			continue;
+		}
 
-			kgem_bo_remove_from_active(kgem, bo);
+		kgem_bo_remove_from_active(kgem, bo);
 
-			bo->unique_id = kgem_get_unique_id(kgem);
-			bo->delta = 0;
-			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
-			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
-			assert(bo->refcnt == 0);
-			assert(bo->reusable);
-			return kgem_bo_reference(bo);
-		}
+		bo->unique_id = kgem_get_unique_id(kgem);
+		bo->delta = 0;
+		DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
+		     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
+		return kgem_bo_reference(bo);
 	}
 
 	if (next && (flags & CREATE_EXACT) == 0) {
commit 6f7bc35d7f956f7c2507eabc874ead1a83c85ddb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 18:14:24 2012 +0000

    sna: Use indirect uploads rather than teardown existing CPU maps
    
    Allow the snoopable CPU mapping to be used inplace of the GTT map for
    untiled bo.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index fd5679a..cafab51 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -104,7 +104,6 @@ static inline void list_replace(struct list *old,
 #define MAX_CPU_VMA_CACHE INT16_MAX
 #define MAP_PRESERVE_TIME 10
 
-#define IS_CPU_MAP(ptr) ((uintptr_t)(ptr) & 1)
 #define CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) & ~1))
 #define MAKE_CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1))
 
@@ -2614,8 +2613,13 @@ void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
 	assert(bo->exec == NULL);
 	assert(list_is_empty(&bo->list));
 
-	if (IS_CPU_MAP(bo->map))
+	if (IS_CPU_MAP(bo->map)) {
+		if (bo->tiling == I915_TILING_NONE) {
+			kgem_bo_sync__cpu(kgem, bo);
+			return CPU_MAP(bo->map);
+		}
 		kgem_bo_release_map(kgem, bo);
+	}
 
 	ptr = bo->map;
 	if (ptr == NULL) {
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 421c84f..377d21d 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -50,6 +50,8 @@ struct kgem_bo {
 	struct list vma;
 
 	void *map;
+#define IS_CPU_MAP(ptr) ((uintptr_t)(ptr) & 1)
+#define IS_GTT_MAP(ptr) (ptr && ((uintptr_t)(ptr) & 1) == 0)
 	struct kgem_request *rq;
 	struct drm_i915_gem_exec_object2 *exec;
 
@@ -375,6 +377,16 @@ static inline bool kgem_bo_is_mappable(struct kgem *kgem,
 	return bo->presumed_offset + bo->size <= kgem->aperture_mappable;
 }
 
+static inline bool kgem_bo_mapped(struct kgem_bo *bo)
+{
+	DBG_HDR(("%s: map=%p, tiling=%d\n", __FUNCTION__, bo->map, bo->tiling));
+
+	if (bo->map == NULL)
+		return false;
+
+	return IS_CPU_MAP(bo->map) == !bo->tiling;
+}
+
 static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
 {
 	DBG_HDR(("%s: domain: %d exec? %d, rq? %d\n",
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 5d3e9e5..6b08532 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -906,7 +906,7 @@ struct kgem_bo *sna_replace(struct sna *sna,
 	     pixmap->drawable.bitsPerPixel,
 	     bo->tiling));
 
-	if ((!bo->map || bo->rq) &&
+	if ((!kgem_bo_mapped(bo) || bo->rq) &&
 	    indirect_replace(sna, pixmap, bo, src, stride))
 		return bo;
 
commit 475fa67ed320f94df37ec86fe6c5dda886923751
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 17:30:00 2012 +0000

    sna: Fast path move-area-to-cpu when the pixmap is already on the cpu
    
    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 b9e8caf..537c4d1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1020,6 +1020,9 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		return true;
 	}
 
+	if (DAMAGE_IS_ALL(priv->cpu_damage))
+		goto out;
+
 	if (priv->stride == 0 && priv->gpu_bo == NULL && flags & MOVE_WRITE)
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 
@@ -1035,9 +1038,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 	}
 
-	if (DAMAGE_IS_ALL(priv->cpu_damage))
-		goto done;
-
 	if ((flags & MOVE_READ) == 0) {
 		assert(flags == MOVE_WRITE);
 
@@ -1292,11 +1292,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	}
 
 done:
-	if (priv->cpu_bo) {
-		DBG(("%s: syncing cpu bo\n", __FUNCTION__));
-		kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
-	}
-
 	if (flags & MOVE_WRITE && !DAMAGE_IS_ALL(priv->cpu_damage)) {
 		DBG(("%s: applying cpu damage\n", __FUNCTION__));
 		assert_pixmap_contains_box(pixmap, RegionExtents(region));
@@ -1315,6 +1310,11 @@ done:
 	if (dx | dy)
 		RegionTranslate(region, -dx, -dy);
 
+out:
+	if (priv->cpu_bo) {
+		DBG(("%s: syncing cpu bo\n", __FUNCTION__));
+		kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
+	}
 	return true;
 }
 
commit 37ced44a53008debaf869ec9ef4ba2e5d6982e76
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 15:35:57 2012 +0000

    sna: Be a little more lenient wrt damage migration if we have CPU bo
    
    The idea being that they facilitate copying to and from the CPU, but
    also we want to avoid stalling on any pixels help by the CPU bo.
    
    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 932eef0..b9e8caf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1505,15 +1505,32 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 		return FALSE;
 	}
 
+	if (DAMAGE_IS_ALL(priv->gpu_damage)) {
+		*damage = NULL;
+		return TRUE;
+	}
+
 	if (DAMAGE_IS_ALL(priv->cpu_damage))
 		return FALSE;
 
-	if (priv->gpu_bo == NULL &&
-	    (sna_pixmap_choose_tiling(pixmap) == I915_TILING_NONE ||
-	     (priv->cpu_damage && !box_inplace(pixmap, box)) ||
-	     !sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ))) {
-		DBG(("%s: no GPU bo allocated\n", __FUNCTION__));
-		return FALSE;
+	if (priv->gpu_bo == NULL) {
+		if (sna_pixmap_choose_tiling(pixmap) == I915_TILING_NONE) {
+			DBG(("%s: untiled, will not force allocation\n",
+			     __FUNCTION__));
+			return FALSE;
+		}
+
+		if (priv->cpu_damage && !box_inplace(pixmap, box)) {
+			DBG(("%s: damaged with a small operation, will not force allocation\n",
+			     __FUNCTION__));
+			return FALSE;
+		}
+
+		if (!sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ))
+			return FALSE;
+
+		DBG(("%s: allocated GPU bo for operation\n", __FUNCTION__));
+		goto done;
 	}
 
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
@@ -1536,13 +1553,20 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 			return TRUE;
 		}
 
-		if (ret != PIXMAN_REGION_OUT && kgem_bo_is_busy(priv->gpu_bo)) {
+		if (ret != PIXMAN_REGION_OUT &&
+		    (priv->cpu_bo || kgem_bo_is_busy(priv->gpu_bo))) {
 			DBG(("%s: region partially contained within busy GPU damage\n",
 			     __FUNCTION__));
 			goto move_to_gpu;
 		}
 	}
 
+	if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) {
+		DBG(("%s: busy CPU bo, prefer to use GPU\n",
+		     __FUNCTION__));
+		goto move_to_gpu;
+	}
+
 	if (priv->cpu_damage) {
 		int ret = sna_damage_contains_box(priv->cpu_damage, &extents);
 		if (ret == PIXMAN_REGION_IN) {
@@ -1556,7 +1580,8 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 			goto move_to_gpu;
 		}
 
-		if (ret != PIXMAN_REGION_OUT && !kgem_bo_is_busy(priv->gpu_bo)) {
+		if (ret != PIXMAN_REGION_OUT &&
+		    (priv->cpu_bo || !kgem_bo_is_busy(priv->gpu_bo))) {
 			DBG(("%s: region partially contained within idle CPU damage\n",
 			     __FUNCTION__));
 			return FALSE;
@@ -1569,6 +1594,7 @@ move_to_gpu:
 		return FALSE;
 	}
 
+done:
 	*damage = DAMAGE_IS_ALL(priv->gpu_damage) ? NULL : &priv->gpu_damage;
 	return TRUE;
 }
commit e3732a6f7f61a959521be9a668bba045591e633c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 15 11:06:59 2012 +0000

    sna: Defer ring switching until after a period of idleness
    
    Similar to the desire to flush the next batch after an overflow, we do
    not want to incur any lag in the midst of drawing, even if that lag is
    mitigated by GPU semaphores.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 32d3fa0..fd5679a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1107,7 +1107,7 @@ bool kgem_retire(struct kgem *kgem)
 	}
 
 	kgem->need_retire = !list_is_empty(&kgem->requests);
-	if (!kgem->need_retire && kgem->ring)
+	if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire))
 		kgem->ring = kgem->mode;
 	DBG(("%s -- need_retire=%d\n", __FUNCTION__, kgem->need_retire));
 
@@ -1412,8 +1412,6 @@ void kgem_reset(struct kgem *kgem)
 	kgem->nbatch = 0;
 	kgem->surface = kgem->max_batch_size;
 	kgem->mode = KGEM_NONE;
-	if (kgem->has_semaphores)
-		kgem->ring = KGEM_NONE;
 	kgem->flush = 0;
 	kgem->scanout = 0;
 


More information about the xorg-commit mailing list