xf86-video-intel: 5 commits - src/sna/compiler.h src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_damage.c src/sna/sna.h src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Dec 24 14:13:39 PST 2011


 src/sna/compiler.h   |    2 +
 src/sna/kgem.c       |    2 -
 src/sna/kgem.h       |   15 +++++++++++++
 src/sna/sna.h        |   10 ++++----
 src/sna/sna_accel.c  |   58 ++++++++++++++++++++++++++++++++++++++++++---------
 src/sna/sna_damage.c |    4 ++-
 src/sna/sna_io.c     |   28 +++++++++++++++++++-----
 7 files changed, 96 insertions(+), 23 deletions(-)

New commits:
commit b117f65520919f4ba36010cfe913a8c53166bf23
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 21:03:01 2011 +0000

    sna: Jump straight to the fallback copy routines if the dst is not attached
    
    Marginally simplify the convoluted logic for choosing the most
    appropriate path and help prevent further errors.
    
    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 0815bc9..284c489 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2431,11 +2431,14 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	     src_priv ? src_priv->cpu_bo : NULL,
 	     replaces));
 
-	if (dst_priv && replaces)
+	if (dst_priv == NULL)
+		goto fallback;
+
+	if (replaces)
 		sna_damage_destroy(&dst_priv->cpu_damage);
 
 	/* Try to maintain the data on the GPU */
-	if (dst_priv && dst_priv->gpu_bo == NULL &&
+	if (dst_priv->gpu_bo == NULL &&
 	    ((dst_priv->cpu_damage == NULL && copy_use_gpu_bo(sna, dst_priv, &region)) ||
 	     (src_priv && (src_priv->gpu_bo != NULL || (src_priv->cpu_bo && kgem_bo_is_busy(src_priv->cpu_bo)))))) {
 		uint32_t tiling = sna_pixmap_choose_tiling(dst_pixmap);
@@ -2455,7 +2458,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 					       tiling, 0);
 	}
 
-	if (dst_priv && dst_priv->gpu_bo) {
+	if (dst_priv->gpu_bo) {
 		if (!src_priv && !copy_use_gpu_bo(sna, dst_priv, &region)) {
 			DBG(("%s: fallback - src_priv=%p and not use dst gpu bo\n",
 			     __FUNCTION__, src_priv));
commit 72217790ee2c080d618274456360b481d015e898
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 19:14:09 2011 +0000

    sna: Use shadow if the GPU is busy or not immediately mappable
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b8c05fa..ee2b969 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1848,7 +1848,7 @@ bool kgem_can_create_2d(struct kgem *kgem,
 }
 #endif
 
-static int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
+inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
 {
 	unsigned int size;
 
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 42a0ba4..3e69be5 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -338,6 +338,21 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo);
 Bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
 		   const void *data, int length);
 
+int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo);
+
+static inline bool kgem_bo_is_mappable(struct kgem *kgem,
+				       struct kgem_bo *bo)
+{
+	DBG_HDR(("%s: offset: %d size: %d\n",
+		 __FUNCTION__, bo->presumed_offset, bo->size));
+
+	if (kgem->gen < 40 && bo->tiling &&
+	    bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1))
+			return false;
+
+	return bo->presumed_offset + bo->size <= kgem->aperture_mappable;
+}
+
 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_accel.c b/src/sna/sna_accel.c
index 837dacf..0815bc9 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -814,6 +814,9 @@ static inline bool region_inplace(struct sna *sna,
 	if (priv->mapped)
 		return true;
 
+	if (priv->gpu_bo && !kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo))
+		return false;
+
 	return ((region->extents.x2 - region->extents.x1) *
 		(region->extents.y2 - region->extents.y1) *
 		pixmap->drawable.bitsPerPixel >> 12)
@@ -1747,7 +1750,9 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 	 * immediately flushed...
 	 */
 	if ((priv->flush ||
-	     (priv->gpu_bo && region_inplace(sna, pixmap, region, priv))) &&
+	     (priv->gpu_bo &&
+	      region_inplace(sna, pixmap, region, priv) &&
+	      !kgem_bo_is_busy(priv->gpu_bo))) &&
 	    sna_put_image_upload_blt(drawable, gc, region,
 				     x, y, w, h, bits, stride)) {
 		if (region_subsumes_drawable(region, &pixmap->drawable)) {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 1e4a9fb..15fe42c 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -87,8 +87,7 @@ static bool map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
 	if (kgem_bo_is_busy(bo))
 		return true;
 
-	if (bo->presumed_offset &&
-	    bo->presumed_offset + bo->size >= kgem->aperture_mappable)
+	if (!kgem_bo_is_mappable(kgem, bo))
 		return true;
 
 	return false;
commit 0be136c21f0373d1eb2259b83c598655f4eb841e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 18:44:15 2011 +0000

    sna: use indirect uploads if the bo was last known to be unmappable
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 55fb88d..1e4a9fb 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -82,6 +82,18 @@ static void read_boxes_inplace(struct kgem *kgem,
 	} while (--n);
 }
 
+static bool map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
+{
+	if (kgem_bo_is_busy(bo))
+		return true;
+
+	if (bo->presumed_offset &&
+	    bo->presumed_offset + bo->size >= kgem->aperture_mappable)
+		return true;
+
+	return false;
+}
+
 void sna_read_boxes(struct sna *sna,
 		    struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
 		    PixmapPtr dst, int16_t dst_dx, int16_t dst_dy,
@@ -100,9 +112,15 @@ void sna_read_boxes(struct sna *sna,
 	     __FUNCTION__, nbox, src_bo->handle, src_dx, src_dy,
 	     dst->drawable.width, dst->drawable.height, dst_dx, dst_dy));
 
-	if (DEBUG_NO_IO || kgem->wedged ||
-	    !kgem_bo_is_busy(src_bo) ||
-	    src_bo->tiling != I915_TILING_X) {
+	if (DEBUG_NO_IO || kgem->wedged || src_bo->tiling == I915_TILING_Y) {
+		read_boxes_inplace(kgem,
+				   src_bo, src_dx, src_dy,
+				   dst, dst_dx, dst_dy,
+				   box, nbox);
+		return;
+	}
+
+	if (src_bo->tiling != I915_TILING_X && !map_will_stall(kgem, src_bo)){
 		read_boxes_inplace(kgem,
 				   src_bo, src_dx, src_dy,
 				   dst, dst_dx, dst_dy,
@@ -296,9 +314,8 @@ void sna_write_boxes(struct sna *sna,
 
 	DBG(("%s x %d\n", __FUNCTION__, nbox));
 
-	if (DEBUG_NO_IO || kgem->wedged ||
-	    !kgem_bo_is_busy(dst_bo) ||
-	    dst_bo->tiling == I915_TILING_Y) {
+	if (DEBUG_NO_IO || kgem->wedged || dst_bo->tiling == I915_TILING_Y ||
+	    !map_will_stall(kgem, dst_bo)) {
 		write_boxes_inplace(kgem,
 				    src, stride, bpp, src_dx, src_dy,
 				    dst_bo, dst_dx, dst_dy,
commit e764a52ee8f0c552e218b3110318be9ba06634ae
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 15:17:06 2011 +0000

    sna: Encourage large operations to be migrated to the GPU
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/compiler.h b/src/sna/compiler.h
index bd84973..364ea62 100644
--- a/src/sna/compiler.h
+++ b/src/sna/compiler.h
@@ -34,12 +34,14 @@
 #define noinline __attribute__((noinline))
 #define fastcall __attribute__((regparm(3)))
 #define must_check __attribute__((warn_unused_result))
+#define constant __attribute__((const))
 #else
 #define likely(expr) (expr)
 #define unlikely(expr) (expr)
 #define noinline
 #define fastcall
 #define must_check
+#define constant
 #endif
 
 #ifdef HAVE_VALGRIND
diff --git a/src/sna/sna.h b/src/sna/sna.h
index b99d0fd..79aa08f 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -177,7 +177,7 @@ static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
 		return get_window_pixmap((WindowPtr)drawable);
 }
 
-static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
+constant static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
 {
 	return ((void **)pixmap->devPrivates)[1];
 }
@@ -322,25 +322,25 @@ extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
 
 void sna_mode_delete_fb(struct sna *sna, uint32_t fb);
 
-static inline struct sna *
+constant static inline struct sna *
 to_sna(ScrnInfoPtr scrn)
 {
 	return (struct sna *)(scrn->driverPrivate);
 }
 
-static inline struct sna *
+constant static inline struct sna *
 to_sna_from_screen(ScreenPtr screen)
 {
 	return to_sna(xf86Screens[screen->myNum]);
 }
 
-static inline struct sna *
+constant static inline struct sna *
 to_sna_from_pixmap(PixmapPtr pixmap)
 {
 	return *(void **)pixmap->devPrivates;
 }
 
-static inline struct sna *
+constant static inline struct sna *
 to_sna_from_drawable(DrawablePtr drawable)
 {
 	return to_sna_from_screen(drawable->pScreen);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index a8723d1..837dacf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1030,7 +1030,7 @@ done:
 	return true;
 }
 
-static void
+static bool
 sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
 {
 	struct sna *sna = to_sna_from_pixmap(pixmap);
@@ -1039,7 +1039,27 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	assert(priv->gpu_bo);
+	if (priv->gpu_bo == NULL) {
+		struct sna *sna = to_sna_from_pixmap(pixmap);
+		unsigned flags;
+
+		flags = 0;
+		if (priv->cpu_damage)
+			flags |= CREATE_INACTIVE;
+		if (pixmap->usage_hint == SNA_CREATE_FB)
+			flags |= CREATE_EXACT | CREATE_SCANOUT;
+
+		priv->gpu_bo = kgem_create_2d(&sna->kgem,
+					      pixmap->drawable.width,
+					      pixmap->drawable.height,
+					      pixmap->drawable.bitsPerPixel,
+					      sna_pixmap_choose_tiling(pixmap),
+					      flags);
+		if (priv->gpu_bo == NULL)
+			return false;
+
+		DBG(("%s: created gpu bo\n", __FUNCTION__));
+	}
 
 	sna_damage_reduce(&priv->cpu_damage);
 	DBG(("%s: CPU damage? %d\n", __FUNCTION__, priv->cpu_damage != NULL));
@@ -1092,6 +1112,14 @@ done:
 	if (!priv->pinned)
 		list_move(&priv->inactive, &sna->active_pixmaps);
 	priv->gpu = true;
+	return true;
+}
+
+static inline bool
+box_inplace(PixmapPtr pixmap, const BoxRec *box)
+{
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	return ((box->x2 - box->x1) * (box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 15) >= sna->kgem.half_cpu_cache_pages;
 }
 
 static inline Bool
@@ -1112,7 +1140,9 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 	    !sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE))
 		return FALSE;
 
-	if (priv->gpu_bo == NULL)
+	if (priv->gpu_bo == NULL &&
+	    sna_pixmap_choose_tiling(pixmap) != I915_TILING_NONE &&
+	    !box_inplace(pixmap, box))
 		return FALSE;
 
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
@@ -1137,7 +1167,7 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 		if (priv->cpu_damage == NULL ||
 		    sna_damage_contains_box(priv->cpu_damage,
 					    &extents) == PIXMAN_REGION_OUT)
-			goto done;
+			goto move_to_gpu;
 
 		if (priv->gpu_damage == NULL ||
 		    sna_damage_contains_box(priv->gpu_damage,
@@ -1146,8 +1176,8 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 	}
 
 move_to_gpu:
-	sna_pixmap_move_area_to_gpu(pixmap, &extents);
-done:
+	if (!sna_pixmap_move_area_to_gpu(pixmap, &extents))
+		return FALSE;
 	if (sna_damage_contains_box(priv->gpu_damage,
 				    &extents) != PIXMAN_REGION_IN)
 		*damage = &priv->gpu_damage;
commit f9f8535db6a9e3affba9ba2c2a9314dfe12ab270
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 21:01:39 2011 +0000

    sna: Fix damage reduction by adding new boxes to the tail of the box list
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index cc4bf6a..b34c7a5 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -206,7 +206,7 @@ static bool _sna_damage_create_boxes(struct sna_damage *damage,
 	if (box == NULL)
 		return false;
 
-	list_add(&box->list, &damage->embedded_box.list);
+	list_add_tail(&box->list, &damage->embedded_box.list);
 
 	box->size = damage->remain = n;
 	damage->box = (BoxRec *)(box + 1);
@@ -400,6 +400,7 @@ static void __sna_damage_reduce(struct sna_damage *damage)
 	boxes = damage->embedded_box.box;
 	list_for_each_entry(iter, &damage->embedded_box.list, list)
 		nboxes += iter->size;
+	DBG(("   nboxes=%d, residual=%d\n", nboxes, damage->remain));
 	nboxes -= damage->remain;
 	if (nboxes == 0)
 		goto done;
@@ -414,6 +415,7 @@ static void __sna_damage_reduce(struct sna_damage *damage)
 			int len = iter->size;
 			if (n + len > nboxes)
 				len = nboxes - n;
+			DBG(("   copy %d/%d boxes from %d\n", len, iter->size, n));
 			memcpy(boxes + n, iter+1, len * sizeof(BoxRec));
 			n += len;
 		}


More information about the xorg-commit mailing list