diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-23 07:42:30 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-23 07:51:38 +0100 |
commit | a33aa554fa3df8ca34012cf1c6ecb11fa69ac7fc (patch) | |
tree | a9aa4bebcaaef9387bec584304862108a60eeed0 /src/sna/gen4_vertex.c | |
parent | 1909910fdf89216d18703e50728f4604f75d5d66 (diff) |
sna/gen4+: Add box emitters for the generic vertex paths
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/gen4_vertex.c')
-rw-r--r-- | src/sna/gen4_vertex.c | 117 |
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; } |