xf86-video-intel: 7 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_render.c src/sna/sna_render.h

Chris Wilson ickle at kemper.freedesktop.org
Sat Aug 11 04:46:31 PDT 2012


 src/sna/gen2_render.c |   15 ++----
 src/sna/gen3_render.c |   16 +++---
 src/sna/gen4_render.c |    9 +++
 src/sna/gen5_render.c |   17 +++---
 src/sna/gen6_render.c |   71 ++++++++++++++++------------
 src/sna/gen7_render.c |   74 ++++++++++++++++-------------
 src/sna/kgem.c        |    6 +-
 src/sna/sna_accel.c   |   24 +++++----
 src/sna/sna_blt.c     |  125 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sna/sna_render.c  |    7 ++
 src/sna/sna_render.h  |    5 ++
 11 files changed, 268 insertions(+), 101 deletions(-)

New commits:
commit 029934662e0bad6cf47baf4d7202656dd3e0ba08
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 10:47:44 2012 +0100

    sna: Add a little DBG for promotion of CPU source bo
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index f507f49..757b2f4 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -352,8 +352,11 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt)
 			bool want_tiling;
 
 			if (priv->cpu_bo->pitch >= 4096) {
-				DBG(("%s: promoting snooped CPU bo due to TLB miss\n",
-				     __FUNCTION__));
+				DBG(("%s: size=%dx%d, promoting reused (%d) CPU bo due to TLB miss (%dx%d, pitch=%d)\n",
+				     __FUNCTION__, w, h, priv->source_count,
+				     pixmap->drawable.width,
+				     pixmap->drawable.height,
+				     priv->cpu_bo->pitch));
 				return NULL;
 			}
 
commit f20f8556bfc8b4df6ba5050cca656a4ff0fdf18f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 10:46:40 2012 +0100

    sna: Treat ShmPixmap as ordinary
    
    In theory the code handles the automatic promotion and demotion of the
    GPU buffers.
    
    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 ac88641..227bb01 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -776,7 +776,7 @@ fallback:
 		pixmap = sna->freed_pixmap;
 		sna->freed_pixmap = pixmap->devPrivate.ptr;
 
-		pixmap->usage_hint = -1;
+		pixmap->usage_hint = 0;
 		pixmap->refcnt = 1;
 
 		pixmap->drawable.width = width;
@@ -793,7 +793,7 @@ fallback:
 
 		priv = _sna_pixmap_reset(pixmap);
 	} else {
-		pixmap = create_pixmap(sna, screen, 0, 0, depth, -1);
+		pixmap = create_pixmap(sna, screen, 0, 0, depth, 0);
 		if (pixmap == NullPixmap)
 			return NullPixmap;
 
commit 16c751a06c503b85c5ab6588bae277af4348487d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 10:44:08 2012 +0100

    sna: Only mark userptr bo as snooped on non-LLC architectures
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 1fdd89c..6db986f 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3808,7 +3808,7 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
 		return NULL;
 	}
 
-	bo->snoop = true;
+	bo->snoop = !kgem->has_llc;
 	debug_alloc__bo(kgem, bo);
 
 	DBG(("%s(ptr=%p, size=%d, pages=%d, read_only=%d) => handle=%d\n",
@@ -4011,6 +4011,8 @@ create_snoopable_buffer(struct kgem *kgem, unsigned alloc)
 	struct kgem_buffer *bo;
 	uint32_t handle;
 
+	assert(!kgem->has_llc);
+
 	if (kgem->has_cacheing) {
 		struct kgem_bo *old;
 
commit 59359dba6496229eff7c60dd04536c5add69cec8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 10:25:40 2012 +0100

    sna: Mark SHM userptr bo as unreusable
    
    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 517c698..ac88641 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -819,6 +819,7 @@ fallback:
 	}
 	priv->cpu_bo->flush = true;
 	priv->cpu_bo->pitch = pitch;
+	priv->cpu_bo->reusable = false;
 	sna_accel_watch_flush(sna, 1);
 
 	priv->cpu = true;
commit 64488010504a6e76008bb3b3c1e61caeb025913c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 10:21:39 2012 +0100

    sna/gen2-5: Substitute an equivalent BLT composite operation
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index b65454d..431b972 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1755,14 +1755,6 @@ gen2_render_composite(struct sna *sna,
 		return false;
 	}
 
-	if (mask == NULL && sna->kgem.mode == KGEM_BLT &&
-	    sna_blt_composite(sna, op,
-			      src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height, tmp))
-		return true;
-
 	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
 
 	tmp->op = op;
@@ -1783,6 +1775,13 @@ gen2_render_composite(struct sna *sna,
 	case 0:
 		gen2_composite_solid_init(sna, &tmp->src, 0);
 	case 1:
+		if (mask == NULL &&
+		    sna_blt_composite__convert(sna,
+					       src_x, src_y,
+					       width, height,
+					       dst_x, dst_y,
+					       tmp))
+			return true;
 		break;
 	}
 
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 18c5d85..ce71d82 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2832,14 +2832,6 @@ gen3_render_composite(struct sna *sna,
 		return false;
 	}
 
-	if (mask == NULL && sna->kgem.mode != KGEM_RENDER &&
-	    sna_blt_composite(sna, op,
-			      src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height, tmp))
-		return true;
-
 	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
 
 	tmp->op = op;
@@ -2866,6 +2858,14 @@ gen3_render_composite(struct sna *sna,
 		tmp->src.u.gen3.type = SHADER_ZERO;
 		break;
 	case 1:
+		if (mask == NULL &&
+		    sna_blt_composite__convert(sna,
+					       src_x, src_y,
+					       width, height,
+					       dst_x, dst_y,
+					       tmp))
+			return true;
+
 		gen3_composite_channel_convert(&tmp->src);
 		break;
 	}
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 7dab92b..ab06295 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1913,6 +1913,7 @@ gen4_composite_picture(struct sna *sna,
 	} else
 		channel->transform = picture->transform;
 
+	channel->pict_format = picture->format;
 	channel->card_format = gen4_get_card_format(picture->format);
 	if (channel->card_format == -1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
@@ -2305,6 +2306,14 @@ gen4_render_composite(struct sna *sna,
 		gen4_composite_solid_init(sna, &tmp->src, 0);
 		/* fall through to fixup */
 	case 1:
+		if (mask == NULL &&
+		    sna_blt_composite__convert(sna,
+					       src_x, src_y,
+					       width, height,
+					       dst_x, dst_y,
+					       tmp))
+			return true;
+
 		gen4_composite_channel_convert(&tmp->src);
 		break;
 	}
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index f50e785..488ac34 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1923,6 +1923,7 @@ gen5_composite_picture(struct sna *sna,
 	} else
 		channel->transform = picture->transform;
 
+	channel->pict_format = picture->format;
 	channel->card_format = gen5_get_card_format(picture->format);
 	if (channel->card_format == -1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
@@ -2302,14 +2303,6 @@ gen5_render_composite(struct sna *sna,
 		return false;
 	}
 
-	if (mask == NULL && sna->kgem.mode == KGEM_BLT &&
-	    sna_blt_composite(sna, op,
-			      src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height, tmp))
-		return true;
-
 	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
 
 	if (too_large(tmp->dst.width, tmp->dst.height) &&
@@ -2330,6 +2323,14 @@ gen5_render_composite(struct sna *sna,
 		gen5_composite_solid_init(sna, &tmp->src, 0);
 		/* fall through to fixup */
 	case 1:
+		if (mask == NULL &&
+		    sna_blt_composite__convert(sna,
+					       src_x, src_y,
+					       width, height,
+					       dst_x, dst_y,
+					       tmp))
+			return true;
+
 		gen5_composite_channel_convert(&tmp->src);
 		break;
 	}
commit f464d508c870293699616626d64bd64f16051467
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 10:10:32 2012 +0100

    sna/gen6+: Try to use the BLT to avoid TLB misses
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 6d4d79e..f8b1e71 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2267,6 +2267,7 @@ gen6_composite_picture(struct sna *sna,
 	} else
 		channel->transform = picture->transform;
 
+	channel->pict_format = picture->format;
 	channel->card_format = gen6_get_card_format(picture->format);
 	if (channel->card_format == (unsigned)-1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
@@ -2369,6 +2370,16 @@ static bool can_switch_rings(struct sna *sna)
 	return sna->kgem.mode == KGEM_NONE && sna->kgem.has_semaphores && !NO_RING_SWITCH;
 }
 
+static inline bool untiled_tlb_miss(struct kgem_bo *bo)
+{
+	return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096;
+}
+
+static bool prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
+{
+	return untiled_tlb_miss(bo) && kgem_bo_can_blt(&sna->kgem, bo);
+}
+
 static bool
 try_blt(struct sna *sna,
 	PicturePtr dst, PicturePtr src,
@@ -2607,6 +2618,19 @@ reuse_source(struct sna *sna,
 }
 
 static bool
+prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
+{
+	if (sna->kgem.ring == KGEM_BLT)
+		return true;
+
+	if (!prefer_blt_ring(sna))
+		return false;
+
+	return (prefer_blt_bo(sna, tmp->dst.bo) ||
+		prefer_blt_bo(sna, tmp->src.bo));
+}
+
+static bool
 gen6_render_composite(struct sna *sna,
 		      uint8_t op,
 		      PicturePtr src,
@@ -2677,23 +2701,20 @@ gen6_render_composite(struct sna *sna,
 		gen6_composite_solid_init(sna, &tmp->src, 0);
 		/* fall through to fixup */
 	case 1:
+		/* Did we just switch rings to prepare the source? */
+		if (mask == NULL &&
+		    prefer_blt_composite(sna, tmp) &&
+		    sna_blt_composite__convert(sna,
+					       src_x, src_y,
+					       width, height,
+					       dst_x, dst_y,
+					       tmp))
+			return true;
+
 		gen6_composite_channel_convert(&tmp->src);
 		break;
 	}
 
-	/* Did we just switch rings to prepare the source? */
-	if (sna->kgem.ring == KGEM_BLT && mask == NULL &&
-	    sna_blt_composite(sna, op,
-			      src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height, tmp)) {
-		if (tmp->redirect.real_bo)
-			kgem_bo_destroy(&sna->kgem, tmp->redirect.real_bo);
-		kgem_bo_destroy(&sna->kgem, tmp->src.bo);
-		return true;
-	}
-
 	tmp->is_affine = tmp->src.is_affine;
 	tmp->has_component_alpha = false;
 	tmp->need_magic_ca_pass = false;
@@ -3216,21 +3237,9 @@ gen6_emit_copy_state(struct sna *sna,
 	gen6_emit_state(sna, op, offset | dirty);
 }
 
-static inline bool untiled_tlb_miss(struct kgem_bo *bo)
-{
-	return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096;
-}
-
-static bool prefer_blt_bo(struct sna *sna,
-			  PixmapPtr pixmap,
-			  struct kgem_bo *bo)
-{
-	return untiled_tlb_miss(bo) && kgem_bo_can_blt(&sna->kgem, bo);
-}
-
 static inline bool prefer_blt_copy(struct sna *sna,
-				   PixmapPtr src, struct kgem_bo *src_bo,
-				   PixmapPtr dst, struct kgem_bo *dst_bo,
+				   struct kgem_bo *src_bo,
+				   struct kgem_bo *dst_bo,
 				   unsigned flags)
 {
 	if (PREFER_RENDER)
@@ -3238,8 +3247,8 @@ static inline bool prefer_blt_copy(struct sna *sna,
 
 	return (sna->kgem.ring == KGEM_BLT ||
 		(flags & COPY_LAST && sna->kgem.mode == KGEM_NONE) ||
-		prefer_blt_bo(sna, src, src_bo) ||
-		prefer_blt_bo(sna, dst, dst_bo));
+		prefer_blt_bo(sna, src_bo) ||
+		prefer_blt_bo(sna, dst_bo));
 }
 
 static inline bool
@@ -3289,7 +3298,7 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
 		      dst_bo, dst_dx, dst_dy,
 		      box, n, &extents)));
 
-	if (prefer_blt_copy(sna, src, src_bo, dst, dst_bo, flags) &&
+	if (prefer_blt_copy(sna, src_bo, dst_bo, flags) &&
 	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 	    sna_blt_copy_boxes(sna, alu,
 			       src_bo, src_dx, src_dy,
@@ -3528,7 +3537,7 @@ gen6_render_copy(struct sna *sna, uint8_t alu,
 	     src->drawable.width, src->drawable.height,
 	     dst->drawable.width, dst->drawable.height));
 
-	if (prefer_blt_copy(sna, src, src_bo, dst, dst_bo, 0) &&
+	if (prefer_blt_copy(sna, src_bo, dst_bo, 0) &&
 	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 	    sna_blt_copy(sna, alu,
 			 src_bo, dst_bo,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 954e42f..318cbef 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2367,6 +2367,7 @@ gen7_composite_picture(struct sna *sna,
 	} else
 		channel->transform = picture->transform;
 
+	channel->pict_format = picture->format;
 	channel->card_format = gen7_get_card_format(picture->format);
 	if (channel->card_format == (unsigned)-1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
@@ -2457,6 +2458,16 @@ inline static bool can_switch_rings(struct sna *sna)
 	return sna->kgem.mode == KGEM_NONE && sna->kgem.has_semaphores && !NO_RING_SWITCH;
 }
 
+static inline bool untiled_tlb_miss(struct kgem_bo *bo)
+{
+	return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096;
+}
+
+static bool prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
+{
+	return untiled_tlb_miss(bo) && kgem_bo_can_blt(&sna->kgem, bo);
+}
+
 inline static bool prefer_blt_ring(struct sna *sna)
 {
 	return sna->kgem.ring != KGEM_RENDER || can_switch_rings(sna);
@@ -2709,6 +2720,19 @@ reuse_source(struct sna *sna,
 }
 
 static bool
+prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
+{
+	if (sna->kgem.ring == KGEM_BLT)
+		return true;
+
+	if (!prefer_blt_ring(sna))
+		return false;
+
+	return (prefer_blt_bo(sna, tmp->dst.bo) ||
+		prefer_blt_bo(sna, tmp->src.bo));
+}
+
+static bool
 gen7_render_composite(struct sna *sna,
 		      uint8_t op,
 		      PicturePtr src,
@@ -2752,7 +2776,8 @@ gen7_render_composite(struct sna *sna,
 	if (!gen7_composite_set_target(sna, tmp, dst))
 		return false;
 
-	if (mask == NULL && sna->kgem.mode == KGEM_BLT &&
+	if (mask == NULL &&
+	    sna->kgem.mode == KGEM_BLT &&
 	    sna_blt_composite(sna, op,
 			      src, dst,
 			      src_x, src_y,
@@ -2779,23 +2804,20 @@ gen7_render_composite(struct sna *sna,
 		gen7_composite_solid_init(sna, &tmp->src, 0);
 		/* fall through to fixup */
 	case 1:
+		/* Did we just switch rings to prepare the source? */
+		if (mask == NULL &&
+		    prefer_blt_composite(sna, tmp) &&
+		    sna_blt_composite__convert(sna,
+					       src_x, src_y,
+					       width, height,
+					       dst_x, dst_y,
+					       tmp))
+			return true;
+
 		gen7_composite_channel_convert(&tmp->src);
 		break;
 	}
 
-	/* Did we just switch rings to prepare the source? */
-	if (sna->kgem.ring == KGEM_BLT && mask == NULL &&
-	    sna_blt_composite(sna, op,
-			      src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height, tmp)) {
-		if (tmp->redirect.real_bo)
-			kgem_bo_destroy(&sna->kgem, tmp->redirect.real_bo);
-		kgem_bo_destroy(&sna->kgem, tmp->src.bo);
-		return true;
-	}
-
 	tmp->is_affine = tmp->src.is_affine;
 	tmp->has_component_alpha = false;
 	tmp->need_magic_ca_pass = false;
@@ -3305,27 +3327,15 @@ gen7_emit_copy_state(struct sna *sna,
 	gen7_emit_state(sna, op, offset);
 }
 
-static inline bool untiled_tlb_miss(struct kgem_bo *bo)
-{
-	return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096;
-}
-
-static bool prefer_blt_bo(struct sna *sna,
-			  PixmapPtr pixmap,
-			  struct kgem_bo *bo)
-{
-	return untiled_tlb_miss(bo) && kgem_bo_can_blt(&sna->kgem, bo);
-}
-
 static inline bool prefer_blt_copy(struct sna *sna,
-				   PixmapPtr src, struct kgem_bo *src_bo,
-				   PixmapPtr dst, struct kgem_bo *dst_bo,
+				   struct kgem_bo *src_bo,
+				   struct kgem_bo *dst_bo,
 				   unsigned flags)
 {
 	return (sna->kgem.ring == KGEM_BLT ||
 		(flags & COPY_LAST && sna->kgem.mode == KGEM_NONE) ||
-		prefer_blt_bo(sna, src, src_bo) ||
-		prefer_blt_bo(sna, dst, dst_bo));
+		prefer_blt_bo(sna, src_bo) ||
+		prefer_blt_bo(sna, dst_bo));
 }
 
 static inline bool
@@ -3375,7 +3385,7 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
 		      dst_bo, dst_dx, dst_dy,
 		      box, n, &extents)));
 
-	if (prefer_blt_copy(sna, src, src_bo, dst, dst_bo, flags) &&
+	if (prefer_blt_copy(sna, src_bo, dst_bo, flags) &&
 	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 	    sna_blt_copy_boxes(sna, alu,
 			       src_bo, src_dx, src_dy,
@@ -3604,7 +3614,7 @@ gen7_render_copy(struct sna *sna, uint8_t alu,
 	     src->drawable.width, src->drawable.height,
 	     dst->drawable.width, dst->drawable.height));
 
-	if (prefer_blt_copy(sna, src, src_bo, dst, dst_bo, 0) &&
+	if (prefer_blt_copy(sna, src_bo, dst_bo, 0) &&
 	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 	    sna_blt_copy(sna, alu,
 			 src_bo, dst_bo,
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 6bf223a..77fca3d 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1674,6 +1674,131 @@ clear:
 	return ret;
 }
 
+static void convert_done(struct sna *sna, const struct sna_composite_op *op)
+{
+	struct kgem *kgem = &sna->kgem;
+
+	if (kgem->gen >= 60 && kgem_check_batch(kgem, 3)) {
+		uint32_t *b = kgem->batch + kgem->nbatch;
+		b[0] = XY_SETUP_CLIP;
+		b[1] = b[2] = 0;
+		kgem->nbatch += 3;
+	}
+
+	kgem_bo_destroy(kgem, op->src.bo);
+	sna_render_composite_redirect_done(sna, op);
+}
+
+bool
+sna_blt_composite__convert(struct sna *sna,
+			   int x, int y,
+			   int width, int height,
+			   int dst_x, int dst_y,
+			   struct sna_composite_op *tmp)
+{
+	uint32_t alpha_fixup;
+	uint8_t op;
+
+#if DEBUG_NO_BLT || NO_BLT_COMPOSITE
+	return false;
+#endif
+
+	DBG(("%s\n", __FUNCTION__));
+
+	if (!kgem_bo_can_blt(&sna->kgem, tmp->dst.bo) ||
+	    !kgem_bo_can_blt(&sna->kgem, tmp->src.bo)) {
+		DBG(("%s: cannot blt from src or to dst\n", __FUNCTION__));
+		return false;
+	}
+
+	if (tmp->src.transform) {
+		DBG(("%s: transforms not handled by the BLT\n"));
+		return false;
+	}
+
+	if (tmp->src.filter == PictFilterConvolution) {
+		DBG(("%s: convolutions filters not handled\n",
+		     __FUNCTION__));
+		return false;
+	}
+
+	op = tmp->op;
+	if (op == PictOpOver && PICT_FORMAT_A(tmp->src.pict_format) == 0)
+		op = PictOpSrc;
+	if (op != PictOpSrc) {
+		DBG(("%s: unsuported op [%d] for blitting\n",
+		     __FUNCTION__, op));
+		return false;
+	}
+
+	alpha_fixup = 0;
+	if (!(tmp->dst.format == tmp->src.pict_format ||
+	      tmp->dst.format == alphaless(tmp->src.pict_format) ||
+	      (alphaless(tmp->dst.format) == alphaless(tmp->src.pict_format) &&
+	       sna_get_pixel_from_rgba(&alpha_fixup,
+				       0, 0, 0, 0xffff,
+				       tmp->dst.format)))) {
+		DBG(("%s: incompatible src/dst formats src=%08x, dst=%08x\n",
+		     __FUNCTION__,
+		     (unsigned)tmp->src.pict_format,
+		     tmp->dst.format));
+		return false;
+	}
+
+	x += tmp->src.offset[0];
+	y += tmp->src.offset[1];
+	if (x < 0 || y < 0 ||
+	    x + width  > tmp->src.width ||
+	    y + height > tmp->src.height) {
+		DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid drawable %dx%d\n",
+		     __FUNCTION__,
+		     x, y, x+width, y+width, tmp->src.width, tmp->src.height));
+		return false;
+	}
+
+	if (!kgem_check_many_bo_fenced(&sna->kgem, tmp->dst.bo, tmp->src.bo, NULL)) {
+		_kgem_submit(&sna->kgem);
+		if (!kgem_check_many_bo_fenced(&sna->kgem,
+					       tmp->dst.bo, tmp->src.bo, NULL)) {
+			DBG(("%s: fallback -- no room in aperture\n", __FUNCTION__));
+			return false;
+		}
+		_kgem_set_mode(&sna->kgem, KGEM_BLT);
+	}
+
+	tmp->u.blt.src_pixmap = NULL;
+	tmp->u.blt.sx = x - dst_x;
+	tmp->u.blt.sy = y - dst_y;
+	DBG(("%s: blt dst offset (%d, %d), source offset (%d, %d), with alpha fixup? %x\n",
+	     __FUNCTION__,
+	     tmp->dst.x, tmp->dst.y, tmp->u.blt.sx, tmp->u.blt.sy, alpha_fixup));
+
+	if (alpha_fixup) {
+		tmp->blt   = blt_composite_copy_with_alpha;
+		tmp->box   = blt_composite_copy_box_with_alpha;
+		tmp->boxes = blt_composite_copy_boxes_with_alpha;
+
+		if (!sna_blt_alpha_fixup_init(sna, &tmp->u.blt,
+					      tmp->src.bo, tmp->dst.bo,
+					      PICT_FORMAT_BPP(tmp->src.pict_format),
+					      alpha_fixup))
+			return false;
+	} else {
+		tmp->blt   = blt_composite_copy;
+		tmp->box   = blt_composite_copy_box;
+		tmp->boxes = blt_composite_copy_boxes;
+
+		if (!sna_blt_copy_init(sna, &tmp->u.blt,
+				       tmp->src.bo, tmp->dst.bo,
+				       PICT_FORMAT_BPP(tmp->src.pict_format),
+				       GXcopy))
+			return false;
+	}
+
+	tmp->done = convert_done;
+	return true;
+}
+
 static void sna_blt_fill_op_blt(struct sna *sna,
 				const struct sna_fill_op *op,
 				int16_t x, int16_t y,
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index a2bcb45..b079178 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -570,6 +570,11 @@ bool sna_blt_composite(struct sna *sna,
 		       int16_t dst_x, int16_t dst_y,
 		       int16_t width, int16_t height,
 		       struct sna_composite_op *tmp);
+bool sna_blt_composite__convert(struct sna *sna,
+				int x, int y,
+				int width, int height,
+				int dst_x, int dst_y,
+				struct sna_composite_op *tmp);
 
 bool sna_blt_fill(struct sna *sna, uint8_t alu,
 		  struct kgem_bo *bo,
commit e9c0e54e69a5ce93bb4e79d56da4a83fddf49c4e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 11 08:58:14 2012 +0100

    sna: Handle userptr failures more gracefully
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 50e0321..1fdd89c 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2190,7 +2190,7 @@ void _kgem_submit(struct kgem *kgem)
 					       i,
 					       kgem->exec[i].handle,
 					       (int)kgem->exec[i].offset,
-					       found ? bytes(found) : -1,
+					       found ? kgem_bo_size(found) : -1,
 					       found ? found->tiling : -1,
 					       (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE),
 					       found ? found->purged : -1);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index dc6557a..517c698 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -754,9 +754,11 @@ sna_pixmap_create_shm(ScreenPtr screen,
 	struct sna_pixmap *priv;
 	PixmapPtr pixmap;
 
-	DBG(("%s(%d, %d, %d)\n", __FUNCTION__, width, height, depth));
+	DBG(("%s(%dx%d, depth=%d, bpp=%d, pitch=%d)\n",
+	     __FUNCTION__, width, height, depth, bpp, pitch));
 
-	if (wedged(sna)) {
+	if (wedged(sna) || bpp == 0) {
+fallback:
 		pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
 		if (pixmap == NULL)
 			return NULL;
@@ -807,19 +809,20 @@ sna_pixmap_create_shm(ScreenPtr screen,
 		}
 	}
 
-	priv->cpu_bo = kgem_create_map(&sna->kgem, addr, pitch*height, false);
+	priv->cpu_bo = kgem_create_map(&sna->kgem,
+				       addr, pitch*(height-1)+width*bpp/8,
+				       false);
 	if (priv->cpu_bo == NULL) {
-		free(priv);
-		FreePixmap(pixmap);
-		return GetScratchPixmapHeader(screen, width, height, depth,
-					      bpp, pitch, addr);
+		priv->header = true;
+		sna_pixmap_destroy(pixmap);
+		goto fallback;
 	}
 	priv->cpu_bo->flush = true;
 	priv->cpu_bo->pitch = pitch;
 	sna_accel_watch_flush(sna, 1);
 
+	priv->cpu = true;
 	priv->shm = true;
-	priv->header = true;
 	sna_damage_all(&priv->cpu_damage, width, height);
 
 	pixmap->devKind = pitch;


More information about the xorg-commit mailing list