xf86-video-intel: 9 commits - src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen4_vertex.c src/sna/gen4_vertex.h src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Dec 28 14:35:16 PST 2012


 src/sna/gen3_render.c |   78 +++++++++------------
 src/sna/gen4_render.c |    2 
 src/sna/gen4_vertex.c |  178 ++++++++++++++++++++++++++++----------------------
 src/sna/gen4_vertex.h |   11 +--
 src/sna/gen5_render.c |    2 
 src/sna/gen6_render.c |    4 -
 src/sna/gen7_render.c |    4 -
 src/sna/kgem.c        |   27 ++++---
 src/sna/kgem.h        |    1 
 src/sna/sna.h         |   13 +++
 src/sna/sna_accel.c   |    2 
 src/sna/sna_display.c |   11 ++-
 12 files changed, 182 insertions(+), 151 deletions(-)

New commits:
commit dba83dacd2ccbb2ac23b205ce2a872a889fa30bd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 19:23:36 2012 +0000

    sna/gen3: Use inline transform+scale function
    
    So as to avoid reading back from the vbo (which may be wc mapped).
    
    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 2c79beb..03b4cd8 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -553,29 +553,27 @@ gen3_emit_composite_primitive_affine_source(struct sna *sna,
 	int16_t dst_y = r->dst.y + op->dst.y;
 	int src_x = r->src.x + (int)op->src.offset[0];
 	int src_y = r->src.y + (int)op->src.offset[1];
-	float sx, sy;
+	float *v;
 
-	_sna_get_transformed_coordinates(src_x + r->width, src_y + r->height,
-					 transform,
-					 &sx, &sy);
+	v = sna->render.vertices + sna->render.vertex_used;
+	sna->render.vertex_used += 12;
 
-	gen3_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height);
-	OUT_VERTEX(sx * op->src.scale[0]);
-	OUT_VERTEX(sy * op->src.scale[1]);
+	v[0] = dst_x + r->width;
+	v[5] = v[1] = dst_y + r->height;
+	v[8] = v[4] = dst_x;
+	v[9] = dst_y;
 
-	_sna_get_transformed_coordinates(src_x, src_y + r->height,
-					 transform,
-					 &sx, &sy);
-	gen3_emit_composite_dstcoord(sna, dst_x, dst_y + r->height);
-	OUT_VERTEX(sx * op->src.scale[0]);
-	OUT_VERTEX(sy * op->src.scale[1]);
+	_sna_get_transformed_scaled(src_x + r->width, src_y + r->height,
+				    transform, op->src.scale,
+				    &v[2], &v[3]);
 
-	_sna_get_transformed_coordinates(src_x, src_y,
-					 transform,
-					 &sx, &sy);
-	gen3_emit_composite_dstcoord(sna, dst_x, dst_y);
-	OUT_VERTEX(sx * op->src.scale[0]);
-	OUT_VERTEX(sy * op->src.scale[1]);
+	_sna_get_transformed_scaled(src_x, src_y + r->height,
+				    transform, op->src.scale,
+				    &v[6], &v[7]);
+
+	_sna_get_transformed_scaled(src_x, src_y,
+				    transform, op->src.scale,
+				    &v[10], &v[11]);
 }
 
 fastcall static void
@@ -3158,7 +3156,7 @@ gen3_emit_composite_spans_primitive_affine_source(struct sna *sna,
 						  float opacity)
 {
 	PictTransform *transform = op->base.src.transform;
-	float x, y, *v;
+	float *v;
 
 	v = sna->render.vertices + sna->render.vertex_used;
 	sna->render.vertex_used += 15;
@@ -3167,30 +3165,22 @@ gen3_emit_composite_spans_primitive_affine_source(struct sna *sna,
 	v[6]  = v[1] = op->base.dst.y + box->y2;
 	v[10] = v[5] = op->base.dst.x + box->x1;
 	v[11] = op->base.dst.y + box->y1;
-	v[4]  = opacity;
-	v[9]  = opacity;
-	v[14] = opacity;
-
-	_sna_get_transformed_coordinates((int)op->base.src.offset[0] + box->x2,
-					 (int)op->base.src.offset[1] + box->y2,
-					 transform,
-					 &x, &y);
-	v[2] = x * op->base.src.scale[0];
-	v[3] = y * op->base.src.scale[1];
-
-	_sna_get_transformed_coordinates((int)op->base.src.offset[0] + box->x1,
-					 (int)op->base.src.offset[1] + box->y2,
-					 transform,
-					 &x, &y);
-	v[7] = x * op->base.src.scale[0];
-	v[8] = y * op->base.src.scale[1];
-
-	_sna_get_transformed_coordinates((int)op->base.src.offset[0] + box->x1,
-					 (int)op->base.src.offset[1] + box->y1,
-					 transform,
-					 &x, &y);
-	v[12] = x * op->base.src.scale[0];
-	v[13] = y * op->base.src.scale[1];
+	v[14] = v[9] = v[4]  = opacity;
+
+	_sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x2,
+				    (int)op->base.src.offset[1] + box->y2,
+				    transform, op->base.src.scale,
+				    &v[2], &v[3]);
+
+	_sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1,
+				    (int)op->base.src.offset[1] + box->y2,
+				    transform, op->base.src.scale,
+				    &v[7], &v[8]);
+
+	_sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1,
+				    (int)op->base.src.offset[1] + box->y1,
+				    transform, op->base.src.scale,
+				    &v[12], &v[13]);
 }
 
 fastcall static void
commit f0fca544b0602bc4ed2f68e8d260e0a3745b4bad
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 18:52:44 2012 +0000

    sna/gen4+: Check for a spare exec slot for an outstanding vbo
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 21c860e..84d7853 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -608,7 +608,7 @@ static int gen4_get_rectangles__flush(struct sna *sna,
 {
 	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 25 : 6))
 		return 0;
-	if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
+	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
 		return 0;
 
 	if (op->need_magic_ca_pass && sna->render.vbo)
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 56178a6..34cfd0e 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -597,7 +597,7 @@ static int gen5_get_rectangles__flush(struct sna *sna,
 {
 	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 20 : 6))
 		return 0;
-	if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
+	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
 		return 0;
 
 	if (op->need_magic_ca_pass && sna->render.vbo)
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 013df6f..0c55a2d 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1180,9 +1180,7 @@ static int gen6_get_rectangles__flush(struct sna *sna,
 {
 	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
 		return 0;
-	if (!kgem_check_exec(&sna->kgem, 2))
-		return 0;
-	if (!kgem_check_reloc(&sna->kgem, 4))
+	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
 		return 0;
 
 	if (op->need_magic_ca_pass && sna->render.vbo)
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 52ddb12..d1ab2e3 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1306,9 +1306,7 @@ static int gen7_get_rectangles__flush(struct sna *sna,
 {
 	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 6))
 		return 0;
-	if (!kgem_check_exec(&sna->kgem, 1))
-		return 0;
-	if (!kgem_check_reloc(&sna->kgem, 2))
+	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
 		return 0;
 
 	if (op->need_magic_ca_pass && sna->render.vbo)
commit c6e850b626f4bb44876c683d596ea38f8f6c30ae
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 17:14:52 2012 +0000

    sna/gen4+: Trim an extraneous coordinate from solid composite emission
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index b41476c..1f34fa6 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -230,7 +230,6 @@ emit_texcoord(struct sna *sna,
 {
 	if (channel->is_solid) {
 		OUT_VERTEX_F(x);
-		OUT_VERTEX_F(y);
 		return;
 	}
 
@@ -329,22 +328,21 @@ emit_primitive_solid(struct sna *sna,
 		float f;
 	} dst;
 
-	assert(op->floats_per_rect == 9);
-	assert((sna->render.vertex_used % 3) == 0);
+	assert(op->floats_per_rect == 6);
+	assert((sna->render.vertex_used % 2) == 0);
 	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 9;
+	sna->render.vertex_used += 6;
 	assert(sna->render.vertex_used <= sna->render.vertex_size);
 
 	dst.p.x = r->dst.x + r->width;
 	dst.p.y = r->dst.y + r->height;
 	v[0] = dst.f;
 	dst.p.x = r->dst.x;
-	v[3] = dst.f;
+	v[2] = dst.f;
 	dst.p.y = r->dst.y;
-	v[6] = dst.f;
+	v[4] = dst.f;
 
-	v[5] = v[2] = v[1] = 1.;
-	v[8] = v[7] = v[4] = 0.;
+	v[5] = v[3] = v[1] = .5;
 }
 
 fastcall static void
@@ -478,27 +476,26 @@ emit_primitive_identity_mask(struct sna *sna,
 	DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n",
 	     __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h));
 
-	assert(op->floats_per_rect == 15);
-	assert((sna->render.vertex_used % 5) == 0);
+	assert(op->floats_per_rect == 12);
+	assert((sna->render.vertex_used % 4) == 0);
 	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 15;
+	sna->render.vertex_used += 12;
 
 	dst.p.x = r->dst.x + r->width;
 	dst.p.y = r->dst.y + r->height;
 	v[0] = dst.f;
-	v[3] = (msk_x + w) * op->mask.scale[0];
-	v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
+	v[2] = (msk_x + w) * op->mask.scale[0];
+	v[7] = v[3] = (msk_y + h) * op->mask.scale[1];
 
 	dst.p.x = r->dst.x;
-	v[5] = dst.f;
-	v[13] = v[8] = msk_x * op->mask.scale[0];
+	v[4] = dst.f;
+	v[10] = v[6] = msk_x * op->mask.scale[0];
 
 	dst.p.y = r->dst.y;
-	v[10] = dst.f;
-	v[14] = msk_y * op->mask.scale[1];
+	v[8] = dst.f;
+	v[11] = msk_y * op->mask.scale[1];
 
-	v[7] = v[2] = v[1] = 1;
-	v[12] = v[11] = v[6] = 0;
+	v[9] = v[5] = v[1] = .5;
 }
 
 fastcall static void
@@ -667,7 +664,7 @@ emit_composite_texcoord_affine(struct sna *sna,
 void gen4_choose_composite_emitter(struct sna_composite_op *tmp)
 {
 	tmp->prim_emit = emit_primitive;
-	tmp->floats_per_vertex = 1 + 2 + !tmp->src.is_affine;
+	tmp->floats_per_vertex = 1 + (tmp->src.is_solid ? 1 : 2 + !tmp->src.is_affine);
 	if (tmp->mask.bo) {
 		tmp->floats_per_vertex += 2 + !tmp->mask.is_affine;
 		tmp->prim_emit = emit_primitive_mask;
diff --git a/src/sna/gen4_vertex.h b/src/sna/gen4_vertex.h
index 1d94ab4..63f21bf 100644
--- a/src/sna/gen4_vertex.h
+++ b/src/sna/gen4_vertex.h
@@ -13,11 +13,11 @@ void gen4_vertex_close(struct sna *sna);
 inline static uint32_t
 gen4_choose_composite_vertex_buffer(const struct sna_composite_op *op)
 {
-	int id = 2 + !op->src.is_affine;
+	int id = op->src.is_solid ? 1 : 2 + !op->src.is_affine;
 	if (op->mask.bo)
 		id |= (2 + !op->mask.is_affine) << 2;
 	DBG(("%s: id=%x (%d, %d)\n", __FUNCTION__, id,
-	     2 + !op->src.is_affine,
+	     op->src.is_solid ? 1 : 2 + !op->src.is_affine;
 	     op->mask.bo ?  2 + !op->mask.is_affine : 0));
 	assert(id > 0 && id < 16);
 	return id;
commit 3fdc9923447538ed65bf9ffa189d7290ce804730
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 17:14:52 2012 +0000

    sna/gen4+: Trim an extraneous coordinate from solid span emission
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index 576e3f3..b41476c 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -751,24 +751,23 @@ emit_spans_solid(struct sna *sna,
 		float f;
 	} dst;
 
-	assert(op->base.floats_per_rect == 12);
-	assert((sna->render.vertex_used % 4) == 0);
+	assert(op->base.floats_per_rect == 9);
+	assert((sna->render.vertex_used % 3) == 0);
 	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 3*4;
+	sna->render.vertex_used += 3*3;
 
 	dst.p.x = box->x2;
 	dst.p.y = box->y2;
 	v[0] = dst.f;
 
 	dst.p.x = box->x1;
-	v[4] = dst.f;
+	v[3] = dst.f;
 
 	dst.p.y = box->y1;
-	v[8] = dst.f;
+	v[6] = dst.f;
 
-	v[9] = v[5] = 0.;
-	v[10] = v[6] = v[1] = v[2] = 1.;
-	v[3] = v[7] = v[11] = opacity;
+	v[7] = v[4] = v[1] = .5;
+	v[8] = v[5] = v[2] = opacity;
 }
 
 fastcall static void
@@ -905,8 +904,10 @@ void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp)
 	tmp->prim_emit = emit_composite_spans_primitive;
 	if (tmp->base.src.is_solid) {
 		tmp->prim_emit = emit_spans_solid;
+		tmp->base.floats_per_vertex = 3;
 	} else if (tmp->base.src.transform == NULL) {
 		tmp->prim_emit = emit_spans_identity;
+		tmp->base.floats_per_vertex = 4;
 	} else if (tmp->base.is_affine) {
 		if (!sna_affine_transform_is_rotation(tmp->base.src.transform)) {
 			tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2];
@@ -914,7 +915,8 @@ void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp)
 			tmp->prim_emit = emit_spans_simple;
 		} else
 			tmp->prim_emit = emit_spans_affine;
-	}
-	tmp->base.floats_per_vertex = 4 + !tmp->base.is_affine;
+		tmp->base.floats_per_vertex = 4;
+	} else
+		tmp->base.floats_per_vertex = 5;
 	tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
 }
diff --git a/src/sna/gen4_vertex.h b/src/sna/gen4_vertex.h
index 418bdef..1d94ab4 100644
--- a/src/sna/gen4_vertex.h
+++ b/src/sna/gen4_vertex.h
@@ -26,10 +26,9 @@ gen4_choose_composite_vertex_buffer(const struct sna_composite_op *op)
 inline inline static uint32_t
 gen4_choose_spans_vertex_buffer(const struct sna_composite_op *op)
 {
-	DBG(("%s: id=%x (%d, 1)\n", __FUNCTION__,
-	     1 << 2 | (2+!op->src.is_affine),
-	     2 + !op->src.is_affine));
-	return 1 << 2 | (2+!op->src.is_affine);
+	int id = op->src.is_solid ? 1 : 2 + !op->src.is_affine;
+	DBG(("%s: id=%x (%d, 1)\n", __FUNCTION__, 1 << 2 | id, id));
+	return 1 << 2 | id;
 }
 
 void gen4_choose_composite_emitter(struct sna_composite_op *tmp);
commit fdd6d222bc92b3e385f5d62f5e03dfd86f290e45
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 17:08:00 2012 +0000

    sna/gen4+: Tidy emit_spans_affine()
    
    gcc produced abysmal code for the inlined emission, so hand unroll it
    for sanity.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index a5b9be7..576e3f3 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -437,30 +437,24 @@ emit_primitive_affine_source(struct sna *sna,
 	dst.p.x = r->dst.x + r->width;
 	dst.p.y = r->dst.y + r->height;
 	v[0] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
-					 op->src.offset[1] + r->src.y + r->height,
-					 op->src.transform,
-					 &v[1], &v[2]);
-	v[1] *= op->src.scale[0];
-	v[2] *= op->src.scale[1];
+	_sna_get_transformed_scaled(op->src.offset[0] + r->src.x + r->width,
+				    op->src.offset[1] + r->src.y + r->height,
+				    op->src.transform, op->src.scale,
+				    &v[1], &v[2]);
 
 	dst.p.x = r->dst.x;
 	v[3] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
-					 op->src.offset[1] + r->src.y + r->height,
-					 op->src.transform,
-					 &v[4], &v[5]);
-	v[4] *= op->src.scale[0];
-	v[5] *= op->src.scale[1];
+	_sna_get_transformed_scaled(op->src.offset[0] + r->src.x,
+				    op->src.offset[1] + r->src.y + r->height,
+				    op->src.transform, op->src.scale,
+				    &v[4], &v[5]);
 
 	dst.p.y = r->dst.y;
 	v[6] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
-					 op->src.offset[1] + r->src.y,
-					 op->src.transform,
-					 &v[7], &v[8]);
-	v[7] *= op->src.scale[0];
-	v[8] *= op->src.scale[1];
+	_sna_get_transformed_scaled(op->src.offset[0] + r->src.x,
+				    op->src.offset[1] + r->src.y,
+				    op->src.transform, op->src.scale,
+				    &v[7], &v[8]);
 }
 
 fastcall static void
@@ -629,34 +623,28 @@ emit_primitive_affine_source_identity(struct sna *sna,
 	dst.p.x = r->dst.x + r->width;
 	dst.p.y = r->dst.y + r->height;
 	v[0] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
-					 op->src.offset[1] + r->src.y + r->height,
-					 op->src.transform,
-					 &v[1], &v[2]);
-	v[1] *= op->src.scale[0];
-	v[2] *= op->src.scale[1];
+	_sna_get_transformed_scaled(op->src.offset[0] + r->src.x + r->width,
+				    op->src.offset[1] + r->src.y + r->height,
+				    op->src.transform, op->src.scale,
+				    &v[1], &v[2]);
 	v[3] = (msk_x + w) * op->mask.scale[0];
 	v[4] = (msk_y + h) * op->mask.scale[1];
 
 	dst.p.x = r->dst.x;
 	v[5] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
-					 op->src.offset[1] + r->src.y + r->height,
-					 op->src.transform,
-					 &v[6], &v[7]);
-	v[6] *= op->src.scale[0];
-	v[7] *= op->src.scale[1];
+	_sna_get_transformed_scaled(op->src.offset[0] + r->src.x,
+				    op->src.offset[1] + r->src.y + r->height,
+				    op->src.transform, op->src.scale,
+				    &v[6], &v[7]);
 	v[8] = msk_x * op->mask.scale[0];
 	v[9] = v[4];
 
 	dst.p.y = r->dst.y;
 	v[10] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
-					 op->src.offset[1] + r->src.y,
-					 op->src.transform,
-					 &v[11], &v[12]);
-	v[11] *= op->src.scale[0];
-	v[12] *= op->src.scale[1];
+	_sna_get_transformed_scaled(op->src.offset[0] + r->src.x,
+				    op->src.offset[1] + r->src.y,
+				    op->src.transform, op->src.scale,
+				    &v[11], &v[12]);
 	v[13] = v[8];
 	v[14] = msk_y * op->mask.scale[1];
 }
@@ -873,17 +861,43 @@ emit_spans_affine(struct sna *sna,
 		  const BoxRec *box,
 		  float opacity)
 {
-	OUT_VERTEX(box->x2, box->y2);
-	emit_composite_texcoord_affine(sna, &op->base.src, box->x2, box->y2);
-	OUT_VERTEX_F(opacity);
+	union {
+		struct sna_coordinate p;
+		float f;
+	} dst;
+	float *v;
 
-	OUT_VERTEX(box->x1, box->y2);
-	emit_composite_texcoord_affine(sna, &op->base.src, box->x1, box->y2);
-	OUT_VERTEX_F(opacity);
+	assert(op->base.floats_per_rect == 12);
+	assert((sna->render.vertex_used % 4) == 0);
+	v = sna->render.vertices + sna->render.vertex_used;
+	sna->render.vertex_used += 12;
 
-	OUT_VERTEX(box->x1, box->y1);
-	emit_composite_texcoord_affine(sna, &op->base.src, box->x1, box->y1);
-	OUT_VERTEX_F(opacity);
+	dst.p.x = box->x2;
+	dst.p.y = box->y2;
+	v[0] = dst.f;
+	_sna_get_transformed_scaled(op->base.src.offset[0] + box->x2,
+				    op->base.src.offset[1] + box->y2,
+				    op->base.src.transform,
+				    op->base.src.scale,
+				    &v[1], &v[2]);
+
+	dst.p.x = box->x1;
+	v[4] = dst.f;
+	_sna_get_transformed_scaled(op->base.src.offset[0] + box->x1,
+				    op->base.src.offset[1] + box->y2,
+				    op->base.src.transform,
+				    op->base.src.scale,
+				    &v[5], &v[6]);
+
+	dst.p.y = box->y1;
+	v[8] = dst.f;
+	_sna_get_transformed_scaled(op->base.src.offset[0] + box->x1,
+				    op->base.src.offset[1] + box->y1,
+				    op->base.src.transform,
+				    op->base.src.scale,
+				    &v[9], &v[10]);
+
+	v[11] = v[7] = v[3] = opacity;
 }
 
 void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp)
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 3abe36d..267c4ff 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -604,6 +604,19 @@ _sna_get_transformed_coordinates(int x, int y,
 	*y_out = result[1] / (double)result[2];
 }
 
+static inline void
+_sna_get_transformed_scaled(int x, int y,
+			    const PictTransform *transform, const float *sf,
+			    float *x_out, float *y_out)
+{
+
+	int64_t result[3];
+
+	_sna_transform_point(transform, x, y, result);
+	*x_out = result[0] * sf[0] / (double)result[2];
+	*y_out = result[1] * sf[1] / (double)result[2];
+}
+
 void
 sna_get_transformed_coordinates(int x, int y,
 				const PictTransform *transform,
commit 5d222d4d21e6e3af5316728e0da49a014e9fea21
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 17:08:00 2012 +0000

    sna/gen4+: Tidy emit_spans_solid()
    
    gcc produced abysmal code for the inlined emission, so hand unroll it
    for sanity.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index a70c3c8..a5b9be7 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -757,17 +757,30 @@ emit_spans_solid(struct sna *sna,
 		 const BoxRec *box,
 		 float opacity)
 {
-	OUT_VERTEX(box->x2, box->y2);
-	OUT_VERTEX_F(1); OUT_VERTEX_F(1);
-	OUT_VERTEX_F(opacity);
+	float *v;
+	union {
+		struct sna_coordinate p;
+		float f;
+	} dst;
 
-	OUT_VERTEX(box->x1, box->y2);
-	OUT_VERTEX_F(0); OUT_VERTEX_F(1);
-	OUT_VERTEX_F(opacity);
+	assert(op->base.floats_per_rect == 12);
+	assert((sna->render.vertex_used % 4) == 0);
+	v = sna->render.vertices + sna->render.vertex_used;
+	sna->render.vertex_used += 3*4;
 
-	OUT_VERTEX(box->x1, box->y1);
-	OUT_VERTEX_F(0); OUT_VERTEX_F(0);
-	OUT_VERTEX_F(opacity);
+	dst.p.x = box->x2;
+	dst.p.y = box->y2;
+	v[0] = dst.f;
+
+	dst.p.x = box->x1;
+	v[4] = dst.f;
+
+	dst.p.y = box->y1;
+	v[8] = dst.f;
+
+	v[9] = v[5] = 0.;
+	v[10] = v[6] = v[1] = v[2] = 1.;
+	v[3] = v[7] = v[11] = opacity;
 }
 
 fastcall static void
commit 4528f68eff33a5c2f9c1d884e9b3f7228053e0f4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 16:45:50 2012 +0000

    sna: Only allocate a busy CPU bo for a GPU readback
    
    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 408c98c..7def353 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1568,7 +1568,7 @@ skip_inplace_map:
 	}
 
 	if (pixmap->devPrivate.ptr == NULL &&
-	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL))
+	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL && !priv->clear))
 		return false;
 
 	if (priv->clear) {
commit 99fdd1a1c6aa52688c2c821a90f86700b7ee34b2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 16:33:59 2012 +0000

    sna: Mark kgem_bo_retire() as static
    
    The exported function is not used, so mark it static and strengthen the
    assertions.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index dbc7f14..1e8d656 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -384,26 +384,25 @@ kgem_busy(struct kgem *kgem, int handle)
 	return busy.busy;
 }
 
-void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
+static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
 {
 	DBG(("%s: handle=%d, domain=%d\n",
 	     __FUNCTION__, bo->handle, bo->domain));
 	assert(bo->flush || !kgem_busy(kgem, bo->handle));
+	assert(bo->exec == NULL);
 
-	if (bo->rq)
-		kgem_retire(kgem);
+	DBG(("%s: retiring bo handle=%d (needed flush? %d), rq? %d\n",
+	     __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL));
 
-	if (bo->exec == NULL) {
-		DBG(("%s: retiring bo handle=%d (needed flush? %d), rq? %d\n",
-		     __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL));
-		assert(list_is_empty(&bo->vma));
+	if (bo->rq) {
+		kgem_retire(kgem);
 		bo->rq = NULL;
-		list_del(&bo->request);
-
-		bo->needs_flush = false;
 	}
 
-	bo->domain = DOMAIN_NONE;
+	assert(list_is_empty(&bo->vma));
+	list_del(&bo->request);
+
+	bo->needs_flush = false;
 }
 
 bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
@@ -419,7 +418,10 @@ bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
 		return false;
 
 	DBG(("%s: flush=%d, domain=%d\n", __FUNCTION__, bo->flush, bo->domain));
-	kgem_bo_retire(kgem, bo);
+	if (bo->exec == NULL) {
+		kgem_bo_retire(kgem, bo);
+		bo->domain = DOMAIN_NONE;
+	}
 	return true;
 }
 
@@ -5320,6 +5322,7 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
 			return;
 	}
 	kgem_bo_retire(kgem, &bo->base);
+	bo->base.domain = DOMAIN_NONE;
 }
 
 uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index b7126c0..cc4ef6a 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -282,7 +282,6 @@ uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format);
 void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
 int kgem_bo_get_swizzling(struct kgem *kgem, struct kgem_bo *bo);
 
-void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo);
 bool kgem_retire(struct kgem *kgem);
 
 bool __kgem_ring_is_idle(struct kgem *kgem, int ring);
commit 548d284b8cf8cc2b311efe3287e0ae956738189a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 28 14:49:38 2012 +0000

    sna: Skip copying fbcon if we are already on the scanout
    
    If we are already the scanout, then there is little point copying to
    ourselves... Should be paranoia.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 2f8e6df..c66bb47 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -886,6 +886,9 @@ void sna_copy_fbcon(struct sna *sna)
 
 	DBG(("%s\n", __FUNCTION__));
 
+	priv = sna_pixmap(sna->front);
+	assert(priv && priv->gpu_bo);
+
 	/* Scan the connectors for a framebuffer and assume that is the fbcon */
 	VG_CLEAR(fbcon);
 	fbcon.fb_id = 0;
@@ -912,6 +915,11 @@ void sna_copy_fbcon(struct sna *sna)
 		return;
 	}
 
+	if (fbcon.fb_id == priv->gpu_bo->delta) {
+		DBG(("%s: fb already installed as scanout\n", __FUNCTION__));
+		return;
+	}
+
 	/* Wrap the fbcon in a pixmap so that we select the right formats
 	 * in the render copy in case we need to preserve the fbcon
 	 * across a depth change upon starting X.
@@ -933,9 +941,6 @@ void sna_copy_fbcon(struct sna *sna)
 
 	DBG(("%s: fbcon handle=%d\n", __FUNCTION__, bo->handle));
 
-	priv = sna_pixmap(sna->front);
-	assert(priv && priv->gpu_bo);
-
 	sx = dx = 0;
 	if (box.x2 < (uint16_t)fbcon.width)
 		sx = (fbcon.width - box.x2) / 2;


More information about the xorg-commit mailing list