xf86-video-intel: 3 commits - src/sna/gen3_render.c src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Jan 3 17:46:05 PST 2012


 src/sna/gen3_render.c   |  121 ++++++++++++++++++++++++++----------------------
 src/sna/kgem.c          |   62 +++++++++++++-----------
 src/sna/sna.h           |    3 +
 src/sna/sna_accel.c     |    6 +-
 src/sna/sna_composite.c |   22 ++++++++
 5 files changed, 133 insertions(+), 81 deletions(-)

New commits:
commit 04a6260016fb5ebefc1056ed6acf5001ec535d5c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 4 01:14:19 2012 +0000

    sna: Fix typo during partial list deletion
    
    And keep the asserts that lead to its discovery.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 1e4d08f..0e83dfb 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -111,6 +111,33 @@ struct kgem_partial_bo {
 static struct kgem_bo *__kgem_freed_bo;
 static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
 
+#ifndef NDEBUG
+static bool validate_partials(struct kgem *kgem)
+{
+	struct kgem_partial_bo *bo, *next;
+
+	list_for_each_entry_safe(bo, next, &kgem->partial, base.list) {
+		if (bo->base.list.next == &kgem->partial)
+			return true;
+		if (bo->alloc - bo->used < next->alloc - next->used) {
+			ErrorF("this rem: %d, next rem: %d\n",
+			       bo->alloc - bo->used,
+			       next->alloc - next->used);
+			goto err;
+		}
+	}
+	return true;
+
+err:
+	list_for_each_entry(bo, &kgem->partial, base.list)
+		ErrorF("bo: used=%d / %d, rem=%d\n",
+		       bo->used, bo->alloc, bo->alloc - bo->used);
+	return false;
+}
+#else
+#define validate_partials(kgem) 1
+#endif
+
 static void kgem_sna_reset(struct kgem *kgem)
 {
 	struct sna *sna = container_of(kgem, struct sna, kgem);
@@ -2141,12 +2168,13 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo)
 		while (io->base.list.prev != &kgem->partial) {
 			struct kgem_partial_bo *p;
 
-			p = list_entry(&io->base.list.prev,
+			p = list_entry(io->base.list.prev,
 				       struct kgem_partial_bo,
 				       base.list);
-			if (remain < p->alloc - p->used)
+			if (remain <= p->alloc - p->used)
 				break;
 
+			assert(p->base.list.next == &io->base.list);
 			io->base.list.prev = p->base.list.prev;
 			p->base.list.prev->next = &io->base.list;
 			p->base.list.prev = &io->base.list;
@@ -2154,8 +2182,13 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo)
 			p->base.list.next = io->base.list.next;
 			io->base.list.next->prev = &p->base.list;
 			io->base.list.next = &p->base.list;
+
+			assert(p->base.list.next->prev == &p->base.list);
+			assert(io->base.list.prev->next == &io->base.list);
 		}
 	}
+
+	assert(validate_partials(kgem));
 }
 
 void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
@@ -2712,31 +2745,6 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
 	return bo;
 }
 
-#ifndef NDEBUG
-static bool validate_partials(struct kgem *kgem)
-{
-	struct kgem_partial_bo *bo, *next;
-
-	list_for_each_entry_safe(bo, next, &kgem->partial, base.list) {
-		if (bo->base.list.next == &kgem->partial)
-			return true;
-		if (bo->alloc - bo->used < next->alloc - next->used) {
-			ErrorF("this rem: %d, next rem: %d\n",
-			       bo->alloc - bo->used,
-			       next->alloc - next->used);
-			goto err;
-		}
-	}
-	return true;
-
-err:
-	list_for_each_entry(bo, &kgem->partial, base.list)
-		ErrorF("bo: used=%d / %d, rem=%d\n",
-		       bo->used, bo->alloc, bo->alloc - bo->used);
-	return false;
-}
-#endif
-
 struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 				   uint32_t size, uint32_t flags,
 				   void **ret)
commit f1dc1eadd84097fc691e85c636535ceeeb601a18
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 4 00:09:30 2012 +0000

    sna/gen3: Remove incorrect premultiplication of solid component-alpha mask
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index fdd2805..fcbe9c7 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2271,10 +2271,10 @@ gen3_composite_set_target(struct sna *sna,
 	return TRUE;
 }
 
-static inline uint8_t mult(uint32_t s, uint32_t m, int shift)
+static inline uint8_t multa(uint32_t s, uint32_t m, int shift)
 {
 	s = (s >> shift) & 0xff;
-	m = (m >> shift) & 0xff;
+	m >>= 24;
 	return (s * m) >> 8;
 }
 
@@ -2292,7 +2292,6 @@ static inline bool is_constant_ps(uint32_t type)
 	}
 }
 
-
 static bool
 is_solid(PicturePtr picture)
 {
@@ -2315,6 +2314,7 @@ source_fallback(PicturePtr p)
 
 static bool
 gen3_composite_fallback(struct sna *sna,
+			uint8_t op,
 			PicturePtr src,
 			PicturePtr mask,
 			PicturePtr dst)
@@ -2347,6 +2347,15 @@ gen3_composite_fallback(struct sna *sna,
 		return TRUE;
 	}
 
+	if (mask &&
+	    mask->componentAlpha && PICT_FORMAT_RGB(mask->format) &&
+	    op != PictOpOver)
+	{
+		DBG(("%s: component-alpha mask with op=%d, should fallback\n",
+		     __FUNCTION__, op));
+		return TRUE;
+	}
+
 	/* If anything is on the GPU, push everything out to the GPU */
 	priv = sna_pixmap(dst_pixmap);
 	if (priv && priv->gpu_damage) {
@@ -2482,7 +2491,7 @@ gen3_render_composite(struct sna *sna,
 			      tmp))
 		return TRUE;
 
-	if (gen3_composite_fallback(sna, src, mask, dst))
+	if (gen3_composite_fallback(sna, op, src, mask, dst))
 		return FALSE;
 
 	if (need_tiling(sna, width, height))
@@ -2563,7 +2572,6 @@ gen3_render_composite(struct sna *sna,
 			}
 		}
 		DBG(("%s: mask type=%d\n", __FUNCTION__, tmp->mask.u.gen3.type));
-
 		if (tmp->mask.u.gen3.type == SHADER_ZERO) {
 			if (tmp->src.bo) {
 				kgem_bo_destroy(&sna->kgem,
@@ -2574,53 +2582,60 @@ gen3_render_composite(struct sna *sna,
 			tmp->mask.u.gen3.type = SHADER_NONE;
 		}
 
-		if (tmp->mask.u.gen3.type != SHADER_NONE &&
-		    mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
-			/* Check if it's component alpha that relies on a source alpha
-			 * and on the source value.  We can only get one of those
-			 * into the single source value that we get to blend with.
-			 */
-			tmp->has_component_alpha = TRUE;
-			if (tmp->mask.u.gen3.type == SHADER_WHITE) {
-				tmp->mask.u.gen3.type = SHADER_NONE;
-				tmp->has_component_alpha = FALSE;
-			} else if (is_constant_ps(tmp->src.u.gen3.type) &&
-				   is_constant_ps(tmp->mask.u.gen3.type)) {
-				uint32_t a,r,g,b;
-
-				a = mult(tmp->src.u.gen3.mode,
-					 tmp->mask.u.gen3.mode,
-					 24);
-				r = mult(tmp->src.u.gen3.mode,
-					 tmp->mask.u.gen3.mode,
-					 16);
-				g = mult(tmp->src.u.gen3.mode,
-					 tmp->mask.u.gen3.mode,
-					 8);
-				b = mult(tmp->src.u.gen3.mode,
-					 tmp->mask.u.gen3.mode,
-					 0);
-
-				DBG(("%s: combining constant source/mask: %x x %x -> %x\n",
-				     __FUNCTION__,
-				     tmp->src.u.gen3.mode,
-				     tmp->mask.u.gen3.mode,
-				     a << 24 | r << 16 | g << 8 | b));
-
-				tmp->src.u.gen3.type = SHADER_CONSTANT;
-				tmp->src.u.gen3.mode =
-					a << 24 | r << 16 | g << 8 | b;
-
-				tmp->mask.u.gen3.type = SHADER_NONE;
-				tmp->has_component_alpha = FALSE;
-			} else if (gen3_blend_op[op].src_alpha &&
-				   (gen3_blend_op[op].src_blend != BLENDFACT_ZERO)) {
-				if (op != PictOpOver)
-					goto cleanup_mask;
-
-				tmp->need_magic_ca_pass = TRUE;
-				tmp->op = PictOpOutReverse;
-				sna->render.vertex_start = sna->render.vertex_index;
+		if (tmp->mask.u.gen3.type != SHADER_NONE) {
+			if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
+				/* Check if it's component alpha that relies on a source alpha
+				 * and on the source value.  We can only get one of those
+				 * into the single source value that we get to blend with.
+				 */
+				DBG(("%s: component-alpha mask: %d\n",
+				     __FUNCTION__, tmp->mask.u.gen3.type));
+				tmp->has_component_alpha = TRUE;
+				if (tmp->mask.u.gen3.type == SHADER_WHITE) {
+					tmp->mask.u.gen3.type = SHADER_NONE;
+					tmp->has_component_alpha = FALSE;
+				} else if (gen3_blend_op[op].src_alpha &&
+					   (gen3_blend_op[op].src_blend != BLENDFACT_ZERO)) {
+					if (op != PictOpOver)
+						goto cleanup_mask;
+
+					tmp->need_magic_ca_pass = TRUE;
+					tmp->op = PictOpOutReverse;
+					sna->render.vertex_start = sna->render.vertex_index;
+				}
+			} else {
+				if (tmp->mask.is_opaque) {
+					tmp->mask.u.gen3.type = SHADER_NONE;
+					tmp->has_component_alpha = FALSE;
+				} else if (is_constant_ps(tmp->src.u.gen3.type) &&
+					   is_constant_ps(tmp->mask.u.gen3.type)) {
+					uint32_t a,r,g,b;
+
+					a = multa(tmp->src.u.gen3.mode,
+						  tmp->mask.u.gen3.mode,
+						  24);
+					r = multa(tmp->src.u.gen3.mode,
+						  tmp->mask.u.gen3.mode,
+						  16);
+					g = multa(tmp->src.u.gen3.mode,
+						  tmp->mask.u.gen3.mode,
+						  8);
+					b = multa(tmp->src.u.gen3.mode,
+						  tmp->mask.u.gen3.mode,
+						  0);
+
+					DBG(("%s: combining constant source/mask: %x x %x -> %x\n",
+					     __FUNCTION__,
+					     tmp->src.u.gen3.mode,
+					     tmp->mask.u.gen3.mode,
+					     a << 24 | r << 16 | g << 8 | b));
+
+					tmp->src.u.gen3.type = SHADER_CONSTANT;
+					tmp->src.u.gen3.mode =
+						a << 24 | r << 16 | g << 8 | b;
+
+					tmp->mask.u.gen3.type = SHADER_NONE;
+				}
 			}
 		}
 	}
@@ -3036,7 +3051,7 @@ gen3_render_composite_spans(struct sna *sna,
 		return FALSE;
 	}
 
-	if (gen3_composite_fallback(sna, src, NULL, dst))
+	if (gen3_composite_fallback(sna, op, src, NULL, dst))
 		return FALSE;
 
 	if (need_tiling(sna, width, height))
commit 8cb9b8d7d7a1eb62eb3b20e6a50d3f1c9bde40c1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 3 23:13:24 2012 +0000

    sna: Discard mask and source for PictOpClear
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index f23e6e5..32288ca 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -604,6 +604,9 @@ void sna_accel_free(struct sna *sna);
 Bool sna_accel_create(struct sna *sna);
 void sna_copy_fbcon(struct sna *sna);
 
+Bool sna_composite_create(struct sna *sna);
+void sna_composite_close(struct sna *sna);
+
 void sna_composite(CARD8 op,
 		   PicturePtr src,
 		   PicturePtr mask,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f4f3521..186041f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9652,6 +9652,9 @@ Bool sna_accel_create(struct sna *sna)
 	if (!sna_gradients_create(sna))
 		return FALSE;
 
+	if (!sna_composite_create(sna))
+		return FALSE;
+
 	return TRUE;
 }
 
@@ -9663,8 +9666,9 @@ void sna_accel_close(struct sna *sna)
 		sna->freed_pixmap = NULL;
 	}
 
-	sna_glyphs_close(sna);
+	sna_composite_close(sna);
 	sna_gradients_close(sna);
+	sna_glyphs_close(sna);
 
 	DeleteCallback(&FlushCallback, sna_accel_flush_callback, sna);
 
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 84b633d..5732047 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -43,6 +43,22 @@
 
 #define BOUND(v)	(INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
 
+static PicturePtr clear;
+
+Bool sna_composite_create(struct sna *sna)
+{
+	xRenderColor color ={ 0 };
+	int error;
+
+	clear = CreateSolidPicture(0, &color, &error);
+	return clear != NULL;
+}
+
+void sna_composite_close(struct sna *sna)
+{
+	FreePicture(clear, 0);
+}
+
 static inline bool
 region_is_singular(pixman_region16_t *region)
 {
@@ -417,6 +433,12 @@ sna_composite(CARD8 op,
 		return;
 	}
 
+	if (op == PictOpClear) {
+		DBG(("%s: discarind sourceand mask for clear\n", __FUNCTION__));
+		mask = NULL;
+		src = clear;
+	}
+
 	if (mask && sna_composite_mask_is_opaque(mask)) {
 		DBG(("%s: removing opaque %smask\n",
 		     __FUNCTION__,


More information about the xorg-commit mailing list