summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-06-23 07:42:30 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-06-23 07:51:38 +0100
commita33aa554fa3df8ca34012cf1c6ecb11fa69ac7fc (patch)
treea9aa4bebcaaef9387bec584304862108a60eeed0
parent1909910fdf89216d18703e50728f4604f75d5d66 (diff)
sna/gen4+: Add box emitters for the generic vertex paths
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen4_vertex.c117
1 files changed, 111 insertions, 6 deletions
diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index 0360b862..aaecb78b 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -320,7 +320,7 @@ emit_texcoord(struct sna *sna,
int16_t x, int16_t y)
{
if (channel->is_solid) {
- OUT_VERTEX_F(x);
+ OUT_VERTEX_F(0.5);
return;
}
@@ -377,6 +377,63 @@ emit_primitive(struct sna *sna,
r->dst.x, r->dst.y);
}
+sse2 inline static float *
+vemit_texcoord(float *v,
+ const struct sna_composite_channel *channel,
+ int16_t x, int16_t y)
+{
+ if (channel->is_solid) {
+ *v++ = 0.5;
+ } else {
+ x += channel->offset[0];
+ y += channel->offset[1];
+
+ if (channel->is_affine) {
+ float s, t;
+
+ sna_get_transformed_coordinates(x, y,
+ channel->transform,
+ &s, &t);
+ *v++ = s * channel->scale[0];
+ *v++ = t * channel->scale[1];
+ } else {
+ float s, t, w;
+
+ sna_get_transformed_coordinates_3d(x, y,
+ channel->transform,
+ &s, &t, &w);
+ *v++ = s * channel->scale[0];
+ *v++ = t * channel->scale[1];
+ *v++ = w;
+ }
+ }
+
+ return v;
+}
+
+sse2 force_inline static float *
+vemit_vertex(float *v,
+ const struct sna_composite_op *op,
+ int16_t x, int16_t y)
+{
+ *v++ = pack_2s(x, y);
+ return vemit_texcoord(v, &op->src, x, y);
+}
+
+sse2 fastcall static void
+emit_boxes(const struct sna_composite_op *op,
+ const BoxRec *box, int nbox,
+ float *v)
+{
+ do {
+ v = vemit_vertex(v, op, box->x2, box->y2);
+ v = vemit_vertex(v, op, box->x1, box->y2);
+ v = vemit_vertex(v, op, box->x1, box->y1);
+
+ box++;
+ } while (--nbox);
+}
+
sse2 force_inline static void
emit_vertex_mask(struct sna *sna,
const struct sna_composite_op *op,
@@ -408,6 +465,32 @@ emit_primitive_mask(struct sna *sna,
r->dst.x, r->dst.y);
}
+sse2 force_inline static float *
+vemit_vertex_mask(float *v,
+ const struct sna_composite_op *op,
+ int16_t x, int16_t y)
+{
+ *v++ = pack_2s(x, y);
+ v = vemit_texcoord(v, &op->src, x, y);
+ v = vemit_texcoord(v, &op->mask, x, y);
+ return v;
+}
+
+sse2 fastcall static void
+emit_boxes_mask(const struct sna_composite_op *op,
+ const BoxRec *box, int nbox,
+ float *v)
+{
+ do {
+ v = vemit_vertex_mask(v, op, box->x2, box->y2);
+ v = vemit_vertex_mask(v, op, box->x1, box->y2);
+ v = vemit_vertex_mask(v, op, box->x1, box->y1);
+
+ box++;
+ } while (--nbox);
+}
+
+
sse2 fastcall static void
emit_primitive_solid(struct sna *sna,
const struct sna_composite_op *op,
@@ -1837,6 +1920,7 @@ unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op
}
} else {
tmp->prim_emit = emit_primitive_mask;
+ tmp->emit_boxes = emit_boxes_mask;
tmp->floats_per_vertex = 1;
vb = 0;
if (tmp->mask.is_solid) {
@@ -1943,6 +2027,7 @@ unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op
DBG(("%s: projective src, no mask\n", __FUNCTION__));
assert(!tmp->src.is_solid);
tmp->prim_emit = emit_primitive;
+ tmp->emit_boxes = emit_boxes;
tmp->floats_per_vertex = 4;
vb = 3;
}
@@ -1962,10 +2047,10 @@ emit_span_vertex(struct sna *sna,
}
sse2 fastcall static void
-emit_composite_spans_primitive(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
+emit_span_primitive(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
{
emit_span_vertex(sna, op, box->x2, box->y2);
OUT_VERTEX_F(opacity);
@@ -1978,6 +2063,25 @@ emit_composite_spans_primitive(struct sna *sna,
}
sse2 fastcall static void
+emit_span_boxes(const struct sna_composite_spans_op *op,
+ const struct sna_opacity_box *b, int nbox,
+ float *v)
+{
+ do {
+ v = vemit_vertex(v, &op->base, b->box.x2, b->box.y2);
+ *v++ = b->alpha;
+
+ v = vemit_vertex(v, &op->base, b->box.x1, b->box.y2);
+ *v++ = b->alpha;
+
+ v = vemit_vertex(v, &op->base, b->box.x1, b->box.y1);
+ *v++ = b->alpha;
+
+ b++;
+ } while (--nbox);
+}
+
+sse2 fastcall static void
emit_span_solid(struct sna *sna,
const struct sna_composite_spans_op *op,
const BoxRec *box,
@@ -3085,7 +3189,8 @@ unsigned gen4_choose_spans_emitter(struct sna *sna,
vb = 1 << 2 | 2;
} else {
DBG(("%s: projective transform\n", __FUNCTION__));
- tmp->prim_emit = emit_composite_spans_primitive;
+ tmp->prim_emit = emit_span_primitive;
+ tmp->emit_boxes = emit_span_boxes;
tmp->base.floats_per_vertex = 5;
vb = 1 << 2 | 3;
}