xf86-video-intel: 6 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_render.c src/sna/sna_render_inline.h

Chris Wilson ickle at kemper.freedesktop.org
Sun Jan 13 06:21:58 PST 2013


 src/sna/kgem.c              |   74 +++++++++-----
 src/sna/kgem.h              |    1 
 src/sna/sna_accel.c         |  220 +++++++++++++++++++++++++++++++++++---------
 src/sna/sna_render.c        |    2 
 src/sna/sna_render_inline.h |    4 
 5 files changed, 226 insertions(+), 75 deletions(-)

New commits:
commit 7a7db06c62228acc6d1c03e800c7afa84e886f5a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 13 13:45:18 2013 +0000

    sna: Add a compile flag for measuring impact of userptr uploads
    
    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 a575777..1cdf4b3 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -62,6 +62,7 @@
 #define USE_WIDE_SPANS 0 /* -1 force CPU, 1 force GPU */
 #define USE_ZERO_SPANS 1 /* -1 force CPU, 1 force GPU */
 #define USE_CPU_BO 1
+#define USE_USERPTR_UPLOADS 1
 
 #define MIGRATE_ALL 0
 #define DBG_NO_CPU_UPLOAD 0
@@ -3703,7 +3704,8 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		return true;
 	}
 
-	if (sna->kgem.has_userptr &&
+	if (USE_USERPTR_UPLOADS &&
+	    sna->kgem.has_userptr &&
 	    box_inplace(pixmap, &region->extents)) {
 		struct kgem_bo *src_bo;
 		bool ok = false;
@@ -4689,7 +4691,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			return;
 		}
 
-		if (src_priv == NULL &&
+		if (USE_USERPTR_UPLOADS &&
+		    src_priv == NULL &&
 		    sna->kgem.has_userptr &&
 		    ((bo->tiling && !bo->scanout) || __kgem_bo_is_busy(&sna->kgem, bo)) &&
 		    box_inplace(src_pixmap, &region->extents)) {
commit bcc212dc7a939505a678f97f6700eee99204249f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 13 13:36:09 2013 +0000

    sna: Use the pixmap size (not drawable) to determine replacement
    
    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 a04c84e..a575777 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3763,8 +3763,11 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 
 	flags = MOVE_WRITE;
 	flags |= MOVE_INPLACE_HINT;
-	if (w == drawable->width)
+	if (w == pixmap->drawable.width) {
 		flags |= MOVE_WHOLE_HINT;
+		if (h != pixmap->drawable.height)
+			flags |= MOVE_READ;
+	}
 
 	if (!sna_drawable_move_region_to_cpu(drawable, region, flags))
 		return false;
commit 32f43f618d9b11ea44b3e01a95ac3f239a731ad2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 13 13:23:24 2013 +0000

    sna: Allow large image uploads to utilize temporary mappings
    
    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 dfea709..a04c84e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3703,6 +3703,64 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		return true;
 	}
 
+	if (sna->kgem.has_userptr &&
+	    box_inplace(pixmap, &region->extents)) {
+		struct kgem_bo *src_bo;
+		bool ok = false;
+
+		DBG(("%s: upload through a temporary map\n",
+		     __FUNCTION__));
+
+		if (priv->gpu_bo == NULL)
+			priv->gpu_bo = kgem_create_2d(&sna->kgem,
+						      pixmap->drawable.width,
+						      pixmap->drawable.height,
+						      pixmap->drawable.bitsPerPixel,
+						      sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
+						      pixmap->usage_hint == SNA_CREATE_FB ?  CREATE_EXACT | CREATE_SCANOUT : 0);
+
+		if (priv->gpu_bo)
+			src_bo = kgem_create_map(&sna->kgem, bits, stride * h, true);
+		if (src_bo) {
+			src_bo->flush = true;
+			src_bo->pitch = stride;
+			src_bo->reusable = false;
+
+			get_drawable_deltas(drawable, pixmap, &dx, &dy);
+			ok = sna->render.copy_boxes(sna, GXcopy,
+						    pixmap, src_bo,
+						    -(x + dx + drawable->x),
+						    -(y + dy + drawable->y),
+						    pixmap, priv->gpu_bo, 0, 0,
+						    REGION_RECTS(region),
+						    REGION_NUM_RECTS(region),
+						    COPY_LAST);
+
+			kgem_bo_sync__cpu(&sna->kgem, src_bo);
+			kgem_bo_destroy(&sna->kgem, src_bo);
+		}
+
+		if (ok) {
+			if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
+				DBG(("%s: marking damage\n", __FUNCTION__));
+				if (region_subsumes_drawable(region, &pixmap->drawable))
+					sna_damage_destroy(&priv->cpu_damage);
+				else
+					sna_damage_subtract(&priv->cpu_damage, region);
+				if (priv->cpu_damage == NULL) {
+					assert(priv->gpu_bo->proxy == NULL);
+					sna_damage_all(&priv->gpu_damage,
+						       pixmap->drawable.width,
+						       pixmap->drawable.height);
+					list_del(&priv->list);
+					priv->undamaged = false;
+				} else
+					sna_damage_add(&priv->gpu_damage, region);
+			}
+			return true;
+		}
+	}
+
 	flags = MOVE_WRITE;
 	flags |= MOVE_INPLACE_HINT;
 	if (w == drawable->width)
commit bf2b2e2f91208412c8b74a95859def501514be43
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 13 12:24:44 2013 +0000

    sna: Allow creation of a CPU map for pixmaps if needed
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 83622b9..4d1d46a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3023,6 +3023,9 @@ search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
 
 		if (flags & CREATE_EXACT)
 			return NULL;
+
+		if (flags & CREATE_CPU_MAP && !kgem->has_llc)
+			return NULL;
 	}
 
 	cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
@@ -3642,6 +3645,9 @@ large_inactive:
 			}
 		} while (!list_is_empty(cache) &&
 			 __kgem_throttle_retire(kgem, flags));
+
+		if (flags & CREATE_CPU_MAP && !kgem->has_llc)
+			goto create;
 	}
 
 	if (flags & CREATE_INACTIVE)
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 483981f..dfea709 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -438,17 +438,17 @@ sna_pixmap_alloc_cpu(struct sna *sna,
 						  from_gpu ? 0 : CREATE_CPU_MAP | CREATE_INACTIVE | CREATE_NO_THROTTLE);
 		if (priv->cpu_bo) {
 			priv->ptr = kgem_bo_map__cpu(&sna->kgem, priv->cpu_bo);
-			priv->stride = priv->cpu_bo->pitch;
 			if (priv->ptr) {
 				DBG(("%s: allocated CPU handle=%d (snooped? %d)\n", __FUNCTION__,
 				     priv->cpu_bo->handle, priv->cpu_bo->snoop));
+				priv->stride = priv->cpu_bo->pitch;
 #ifdef DEBUG_MEMORY
 				sna->debug_memory.cpu_bo_allocs++;
 				sna->debug_memory.cpu_bo_bytes += kgem_bo_size(priv->cpu_bo);
+#endif
 			} else {
 				kgem_bo_destroy(&sna->kgem, priv->cpu_bo);
 				priv->cpu_bo = NULL;
-#endif
 			}
 		}
 	}
@@ -1506,11 +1506,10 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 			priv->clear = false;
 			priv->cpu = false;
 			list_del(&priv->list);
-			if (priv->cpu_bo) {
-				assert(!priv->shm);
-				assert(!priv->cpu_bo->flush);
-				sna_pixmap_free_cpu(sna, priv);
-			}
+
+			assert(!priv->shm);
+			assert(priv->cpu_bo == NULL || !priv->cpu_bo->flush);
+			sna_pixmap_free_cpu(sna, priv);
 
 			assert_pixmap_damage(pixmap);
 			return true;
@@ -1541,7 +1540,7 @@ skip_inplace_map:
 
 	if (operate_inplace(priv, flags) &&
 	    pixmap_inplace(sna, pixmap, priv) &&
-	    sna_pixmap_move_to_gpu(pixmap, flags)) {
+	    sna_pixmap_move_to_gpu(pixmap, flags | MOVE_INPLACE_HINT)) {
 		kgem_bo_submit(&sna->kgem, priv->gpu_bo);
 
 		DBG(("%s: try to operate inplace (GTT)\n", __FUNCTION__));
@@ -1554,11 +1553,11 @@ skip_inplace_map:
 			pixmap->devKind = priv->gpu_bo->pitch;
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
-				sna_pixmap_free_cpu(sna, priv);
 				sna_damage_all(&priv->gpu_damage,
 					       pixmap->drawable.width,
 					       pixmap->drawable.height);
 				sna_damage_destroy(&priv->cpu_damage);
+				sna_pixmap_free_cpu(sna, priv);
 				list_del(&priv->list);
 				priv->undamaged = false;
 				priv->clear = false;
@@ -1593,11 +1592,11 @@ skip_inplace_map:
 			pixmap->devKind = priv->gpu_bo->pitch;
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
-				sna_pixmap_free_cpu(sna, priv);
 				sna_damage_all(&priv->gpu_damage,
 					       pixmap->drawable.width,
 					       pixmap->drawable.height);
 				sna_damage_destroy(&priv->cpu_damage);
+				sna_pixmap_free_cpu(sna, priv);
 				list_del(&priv->list);
 				priv->undamaged = false;
 				priv->clear = false;
@@ -1617,6 +1616,59 @@ skip_inplace_map:
 		sna_pixmap_free_cpu(sna, priv);
 	}
 
+	if (priv->ptr == NULL &&
+	    (flags & MOVE_READ) == 0 &&
+	    sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING) == I915_TILING_NONE) {
+		assert(flags & MOVE_WRITE);
+		assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
+
+		DBG(("%s: uninitialised, try to create inplace (CPU)\n",
+		     __FUNCTION__));
+
+		assert(pixmap->devPrivate.ptr == NULL);
+		assert(pixmap->usage_hint != SNA_CREATE_FB);
+
+		if (priv->gpu_bo && priv->gpu_bo->domain != DOMAIN_CPU) {
+			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+			priv->gpu_bo = NULL;
+		}
+
+		if (priv->gpu_bo == NULL)
+			priv->gpu_bo = kgem_create_2d(&sna->kgem,
+						      pixmap->drawable.width,
+						      pixmap->drawable.height,
+						      pixmap->drawable.bitsPerPixel,
+						      I915_TILING_NONE,
+						      CREATE_CPU_MAP | CREATE_INACTIVE);
+		if (priv->gpu_bo)
+			pixmap->devPrivate.ptr =
+				kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
+		if (pixmap->devPrivate.ptr != NULL) {
+			priv->clear = false;
+			priv->cpu = true;
+			priv->mapped = true;
+			pixmap->devKind = priv->gpu_bo->pitch;
+
+			sna_damage_all(&priv->gpu_damage,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height);
+			sna_damage_destroy(&priv->cpu_damage);
+			sna_pixmap_free_cpu(sna, priv);
+			list_del(&priv->list);
+			priv->undamaged = false;
+
+			kgem_bo_sync__cpu(&sna->kgem, priv->gpu_bo);
+			assert_pixmap_damage(pixmap);
+			DBG(("%s: operate inplace (CPU)\n", __FUNCTION__));
+			return true;
+		}
+
+		if (priv->gpu_bo) {
+			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+			priv->gpu_bo = NULL;
+		}
+	}
+
 	if (pixmap->devPrivate.ptr == NULL &&
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL && !priv->clear))
 		return false;
@@ -3117,6 +3169,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 			create = 0;
 			if (priv->cpu_damage && priv->cpu_bo == NULL)
 				create = CREATE_GTT_MAP | CREATE_INACTIVE;
+			if (flags & MOVE_INPLACE_HINT)
+				create = CREATE_GTT_MAP | CREATE_INACTIVE;
 
 			priv->gpu_bo =
 				kgem_create_2d(&sna->kgem,
@@ -3634,7 +3688,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		}
 
 		/* And mark as having a valid GTT mapping for future uploads */
-		if ( kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
+		if (kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
 			pixmap->devPrivate.ptr =
 				kgem_bo_map__async(&sna->kgem, priv->gpu_bo);
 			if (pixmap->devPrivate.ptr) {
commit b266ae6f6f8fb4c494ece532ae4621055e66beb2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 13 11:30:07 2013 +0000

    sna: Relax limitation on not mapping GPU bo with shadow pointers
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index bffe13a..83622b9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3362,6 +3362,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem,
 {
 	uint32_t pitch, size;
 	unsigned flags = 0;
+	int tiling;
 	int bpp;
 
 	DBG(("%s: %dx%d @ %d\n", __FUNCTION__, width, height, depth));
@@ -3381,33 +3382,41 @@ unsigned kgem_can_create_2d(struct kgem *kgem,
 	size = kgem_surface_size(kgem, false, 0,
 				 width, height, bpp,
 				 I915_TILING_NONE, &pitch);
-	if (size > 0 && size <= kgem->max_cpu_size)
-		flags |= KGEM_CAN_CREATE_CPU | KGEM_CAN_CREATE_GPU;
-	if (size > 0 && size <= kgem->aperture_mappable/4)
-		flags |= KGEM_CAN_CREATE_GTT;
-	if (size > kgem->large_object_size)
-		flags |= KGEM_CAN_CREATE_LARGE;
-	if (size > kgem->max_object_size) {
-		DBG(("%s: too large (untiled) %d > %d\n",
-		     __FUNCTION__, size, kgem->max_object_size));
-		return 0;
+	if (size > 0) {
+		if (size < 4096)
+			flags |= KGEM_CAN_CREATE_SMALL;
+		if (size <= kgem->max_cpu_size)
+			flags |= KGEM_CAN_CREATE_CPU;
+		if (size <= kgem->max_gpu_size)
+			flags |= KGEM_CAN_CREATE_GPU;
+		if (size <= kgem->aperture_mappable/4)
+			flags |= KGEM_CAN_CREATE_GTT;
+		if (size > kgem->large_object_size)
+			flags |= KGEM_CAN_CREATE_LARGE;
+		if (size > kgem->max_object_size) {
+			DBG(("%s: too large (untiled) %d > %d\n",
+			     __FUNCTION__, size, kgem->max_object_size));
+			return 0;
+		}
 	}
 
-	size = kgem_surface_size(kgem, false, 0,
-				 width, height, bpp,
-				 kgem_choose_tiling(kgem, I915_TILING_X,
-						    width, height, bpp),
-				 &pitch);
-	if (size > 0 && size <= kgem->max_gpu_size)
-		flags |= KGEM_CAN_CREATE_GPU;
-	if (size > 0 && size <= kgem->aperture_mappable/4)
-		flags |= KGEM_CAN_CREATE_GTT;
-	if (size > kgem->large_object_size)
-		flags |= KGEM_CAN_CREATE_LARGE;
-	if (size > kgem->max_object_size) {
-		DBG(("%s: too large (tiled) %d > %d\n",
-		     __FUNCTION__, size, kgem->max_object_size));
-		return 0;
+	tiling = kgem_choose_tiling(kgem, I915_TILING_X,
+				    width, height, bpp);
+	if (tiling != I915_TILING_NONE) {
+		size = kgem_surface_size(kgem, false, 0,
+					 width, height, bpp, tiling,
+					 &pitch);
+		if (size > 0 && size <= kgem->max_gpu_size)
+			flags |= KGEM_CAN_CREATE_GPU;
+		if (size > 0 && size <= kgem->aperture_mappable/4)
+			flags |= KGEM_CAN_CREATE_GTT;
+		if (size > kgem->large_object_size)
+			flags |= KGEM_CAN_CREATE_LARGE;
+		if (size > kgem->max_object_size) {
+			DBG(("%s: too large (tiled) %d > %d\n",
+			     __FUNCTION__, size, kgem->max_object_size));
+			return 0;
+		}
 	}
 
 	return flags;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index d2b89f5..372bfdb 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -248,6 +248,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth)
 #define KGEM_CAN_CREATE_CPU	0x2
 #define KGEM_CAN_CREATE_LARGE	0x4
 #define KGEM_CAN_CREATE_GTT	0x8
+#define KGEM_CAN_CREATE_SMALL	0x10
 
 struct kgem_bo *
 kgem_replace_bo(struct kgem *kgem,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e9ecfaf..483981f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -92,6 +92,10 @@
 #define NO_TILE_8x8 0
 #define NO_STIPPLE_8x8 0
 
+#define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1)
+#define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1))
+#define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1))
+
 #if 0
 static void __sna_fallback_flush(DrawablePtr d)
 {
@@ -457,9 +461,9 @@ sna_pixmap_alloc_cpu(struct sna *sna,
 
 	assert(priv->ptr);
 done:
-	pixmap->devPrivate.ptr = priv->ptr;
-	pixmap->devKind = priv->stride;
 	assert(priv->stride);
+	pixmap->devPrivate.ptr = PTR(priv->ptr);
+	pixmap->devKind = priv->stride;
 	return priv->ptr != NULL;
 }
 
@@ -468,6 +472,9 @@ static void sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv)
 	assert(priv->cpu_damage == NULL);
 	assert(list_is_empty(&priv->list));
 
+	if (IS_STATIC_PTR(priv->ptr))
+		return;
+
 	if (priv->cpu_bo) {
 		DBG(("%s: discarding CPU buffer, handle=%d, size=%d\n",
 		     __FUNCTION__, priv->cpu_bo->handle, kgem_bo_size(priv->cpu_bo)));
@@ -484,8 +491,8 @@ static void sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv)
 		priv->cpu_bo = NULL;
 	} else
 		free(priv->ptr);
-
 	priv->ptr = NULL;
+
 	if (!priv->mapped)
 		priv->pixmap->devPrivate.ptr = NULL;
 }
@@ -762,7 +769,7 @@ sna_pixmap_create_shm(ScreenPtr screen,
 	DBG(("%s(%dx%d, depth=%d, bpp=%d, pitch=%d)\n",
 	     __FUNCTION__, width, height, depth, bpp, pitch));
 
-	if (wedged(sna) || bpp == 0 || pitch*height <= 4096) {
+	if (wedged(sna) || bpp == 0 || pitch*height < 4096) {
 fallback:
 		pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
 		if (pixmap == NULL)
@@ -831,6 +838,8 @@ fallback:
 
 	priv->cpu = true;
 	priv->shm = true;
+	priv->stride = pitch;
+	priv->ptr = MAKE_STATIC_PTR(addr);
 	sna_damage_all(&priv->cpu_damage, width, height);
 
 	pixmap->devKind = pitch;
@@ -1134,8 +1143,10 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 {
 	struct sna *sna = to_sna_from_screen(screen);
 	PixmapPtr pixmap;
+	struct sna_pixmap *priv;
 	unsigned flags;
 	int pad;
+	void *ptr;
 
 	DBG(("%s(%d, %d, %d, usage=%x)\n", __FUNCTION__,
 	     width, height, depth, usage));
@@ -1196,7 +1207,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 		usage = 0;
 
 	pad = PixmapBytePad(width, depth);
-	if (pad * height <= 4096) {
+	if (pad * height < 4096) {
 		DBG(("%s: small buffer [%d], attaching to shadow pixmap\n",
 		     __FUNCTION__, pad * height));
 		pixmap = create_pixmap(sna, screen,
@@ -1204,10 +1215,10 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 		if (pixmap == NullPixmap)
 			return NullPixmap;
 
-		sna_pixmap_attach(pixmap);
+		ptr = MAKE_STATIC_PTR(pixmap->devPrivate.ptr);
+		pad = pixmap->devKind;
+		flags |= KGEM_CAN_CREATE_SMALL;
 	} else {
-		struct sna_pixmap *priv;
-
 		DBG(("%s: creating GPU pixmap %dx%d, stride=%d, flags=%x\n",
 		     __FUNCTION__, width, height, pad, flags));
 
@@ -1220,16 +1231,19 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 		pixmap->devKind = pad;
 		pixmap->devPrivate.ptr = NULL;
 
-		priv = sna_pixmap_attach(pixmap);
-		if (priv == NULL) {
-			free(pixmap);
-			goto fallback;
-		}
+		ptr = NULL;
+	}
 
-		priv->stride = pad;
-		priv->create = flags;
+	priv = sna_pixmap_attach(pixmap);
+	if (priv == NULL) {
+		free(pixmap);
+		goto fallback;
 	}
 
+	priv->stride = pad;
+	priv->create = flags;
+	priv->ptr = ptr;
+
 	return pixmap;
 
 fallback:
@@ -1422,7 +1436,7 @@ static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags)
 	if (flags & MOVE_WRITE && kgem_bo_is_busy(priv->gpu_bo))
 		return false;
 
-	return priv->stride != 0;
+	return true;
 }
 
 bool
@@ -1540,6 +1554,7 @@ skip_inplace_map:
 			pixmap->devKind = priv->gpu_bo->pitch;
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
+				sna_pixmap_free_cpu(sna, priv);
 				sna_damage_all(&priv->gpu_damage,
 					       pixmap->drawable.width,
 					       pixmap->drawable.height);
@@ -1563,11 +1578,10 @@ skip_inplace_map:
 		priv->mapped = false;
 	}
 
-	if (priv->gpu_bo &&
+	if (priv->gpu_damage &&
 	    priv->gpu_bo->tiling == I915_TILING_NONE &&
 	    sna_pixmap_move_to_gpu(pixmap, flags)) {
 		kgem_bo_submit(&sna->kgem, priv->gpu_bo);
-		sna_pixmap_free_cpu(sna, priv);
 
 		DBG(("%s: try to operate inplace (CPU)\n", __FUNCTION__));
 
@@ -1579,6 +1593,7 @@ skip_inplace_map:
 			pixmap->devKind = priv->gpu_bo->pitch;
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
+				sna_pixmap_free_cpu(sna, priv);
 				sna_damage_all(&priv->gpu_damage,
 					       pixmap->drawable.width,
 					       pixmap->drawable.height);
@@ -1876,7 +1891,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		     __FUNCTION__));
 		assert(flags & MOVE_WRITE);
 
-		if (priv->stride && priv->gpu_bo &&
+		if (priv->gpu_bo &&
 		    kgem_bo_can_map(&sna->kgem, priv->gpu_bo) &&
 		    region_inplace(sna, pixmap, region, priv, true)) {
 			assert(priv->gpu_bo->proxy == NULL);
@@ -1926,7 +1941,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 			}
 		}
 
-		if (priv->gpu_bo == NULL && priv->stride &&
+		if (priv->gpu_bo == NULL &&
 		    sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING) != I915_TILING_NONE &&
 		    region_inplace(sna, pixmap, region, priv, true) &&
 		    sna_pixmap_create_mappable_gpu(pixmap)) {
@@ -2490,8 +2505,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 			}
 			if (!ok) {
 				if (pixmap->devPrivate.ptr == NULL) {
-					assert(priv->stride && priv->ptr);
-					pixmap->devPrivate.ptr = priv->ptr;
+					assert(priv->ptr);
+					pixmap->devPrivate.ptr = PTR(priv->ptr);
 					pixmap->devKind = priv->stride;
 				}
 				assert(!priv->mapped);
@@ -2535,8 +2550,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 		}
 		if (!ok) {
 			if (pixmap->devPrivate.ptr == NULL) {
-				assert(priv->stride && priv->ptr);
-				pixmap->devPrivate.ptr = priv->ptr;
+				assert(priv->ptr);
+				pixmap->devPrivate.ptr = PTR(priv->ptr);
 				pixmap->devKind = priv->stride;
 			}
 			assert(!priv->mapped);
@@ -2571,8 +2586,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 		}
 		if (!ok) {
 			if (pixmap->devPrivate.ptr == NULL) {
-				assert(priv->stride && priv->ptr);
-				pixmap->devPrivate.ptr = priv->ptr;
+				assert(priv->ptr);
+				pixmap->devPrivate.ptr = PTR(priv->ptr);
 				pixmap->devKind = priv->stride;
 			}
 			assert(!priv->mapped);
@@ -3064,7 +3079,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		sna_damage_destroy(&priv->cpu_damage);
 		list_del(&priv->list);
 		priv->undamaged = false;
-		assert(priv->cpu == false);
+		assert(priv->cpu == false || IS_CPU_MAP(priv->gpu_bo->map));
 		goto active;
 	}
 
@@ -3145,7 +3160,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 
 	if (priv->mapped) {
 		assert(priv->stride);
-		pixmap->devPrivate.ptr = priv->ptr;
+		pixmap->devPrivate.ptr = PTR(priv->ptr);
 		pixmap->devKind = priv->stride;
 		priv->mapped = false;
 	}
@@ -3167,8 +3182,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		}
 		if (!ok) {
 			if (pixmap->devPrivate.ptr == NULL) {
-				assert(priv->stride && priv->ptr);
-				pixmap->devPrivate.ptr = priv->ptr;
+				assert(priv->ptr);
+				pixmap->devPrivate.ptr = PTR(priv->ptr);
 				pixmap->devKind = priv->stride;
 			}
 			assert(!priv->mapped);
@@ -3203,7 +3218,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 
 	/* For large bo, try to keep only a single copy around */
 	if (priv->create & KGEM_CAN_CREATE_LARGE ||
-	    (priv->stride && flags & MOVE_SOURCE_HINT)) {
+	    flags & MOVE_SOURCE_HINT) {
 		DBG(("%s: disposing of system copy for large/source\n",
 		     __FUNCTION__));
 		assert(!priv->shm);
@@ -3619,7 +3634,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		}
 
 		/* And mark as having a valid GTT mapping for future uploads */
-		if (priv->stride && kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
+		if ( kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
 			pixmap->devPrivate.ptr =
 				kgem_bo_map__async(&sna->kgem, priv->gpu_bo);
 			if (pixmap->devPrivate.ptr) {
@@ -4679,8 +4694,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				if (src_pixmap->devPrivate.ptr == NULL) {
 					if (!src_priv->ptr) /* uninitialised!*/
 						return;
-					assert(src_priv->stride);
-					src_pixmap->devPrivate.ptr = src_priv->ptr;
+					src_pixmap->devPrivate.ptr = PTR(src_priv->ptr);
 					src_pixmap->devKind = src_priv->stride;
 				}
 			}
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index d7fa5cb..46ce64b 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -508,7 +508,7 @@ static struct kgem_bo *upload(struct sna *sna,
 			if (priv->ptr == NULL) /* uninitialised */
 				return NULL;
 			assert(priv->stride);
-			pixmap->devPrivate.ptr = priv->ptr;
+			pixmap->devPrivate.ptr = PTR(priv->ptr);
 			pixmap->devKind = priv->stride;
 		}
 	}
diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 2feb7ca..a329707 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -71,7 +71,7 @@ is_gpu(DrawablePtr drawable)
 {
 	struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
 
-	if (priv == NULL || priv->clear)
+	if (priv == NULL || priv->clear || priv->cpu)
 		return false;
 
 	if (priv->cpu_damage == NULL)
@@ -97,7 +97,7 @@ too_small(struct sna_pixmap *priv)
 	if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo))
 		return false;
 
-	return (priv->create & KGEM_CAN_CREATE_GPU) == 0;
+	return priv->create & KGEM_CAN_CREATE_SMALL;
 }
 
 static inline bool
commit a2d82161436e489f23637d793c737bc6950a62b8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 13 10:17:33 2013 +0000

    sna: Correct a few assertions after enabling read-only mappings
    
    As these do not flush the active state if we have read-read mappings, we
    need to be careful with our asserts concerning the busy flag.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 8604488..bffe13a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1894,7 +1894,7 @@ static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq)
 
 		assert(RQ(bo->rq) == rq);
 		assert(bo->exec == NULL);
-		assert(bo->domain == DOMAIN_GPU);
+		assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE);
 
 		list_del(&bo->request);
 
@@ -4695,8 +4695,11 @@ void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write)
 		set_domain.write_domain = write ? I915_GEM_DOMAIN_CPU : 0;
 
 		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) {
-			kgem_bo_retire(kgem, bo);
-			bo->domain = write ? DOMAIN_CPU : DOMAIN_NONE;
+			if (write) {
+				kgem_bo_retire(kgem, bo);
+				bo->domain = DOMAIN_CPU;
+			} else
+				bo->domain = DOMAIN_NONE;
 		}
 	}
 }


More information about the xorg-commit mailing list