34,6 → 34,10 |
#include "sna_render_inline.h" |
#include "gen4_vertex.h" |
|
#ifndef sse2 |
#define sse2 |
#endif |
|
void gen4_vertex_flush(struct sna *sna) |
{ |
DBG(("%s[%x] = %d\n", __FUNCTION__, |
223,7 → 227,601 |
kgem_bo_destroy(&sna->kgem, free_bo); |
} |
|
fastcall static void |
/* specialised vertex emission routines */ |
|
#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) /* XXX assert(!too_large(x, y)); */ |
#define OUT_VERTEX_F(v) vertex_emit(sna, v) |
|
force_inline static float |
compute_linear(const struct sna_composite_channel *channel, |
int16_t x, int16_t y) |
{ |
return ((x+channel->offset[0]) * channel->u.linear.dx + |
(y+channel->offset[1]) * channel->u.linear.dy + |
channel->u.linear.offset); |
} |
|
sse2 inline static void |
emit_texcoord(struct sna *sna, |
const struct sna_composite_channel *channel, |
int16_t x, int16_t y) |
{ |
if (channel->is_solid) { |
OUT_VERTEX_F(x); |
return; |
} |
|
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); |
OUT_VERTEX_F(s * channel->scale[0]); |
OUT_VERTEX_F(t * channel->scale[1]); |
} else { |
float s, t, w; |
|
sna_get_transformed_coordinates_3d(x, y, |
channel->transform, |
&s, &t, &w); |
OUT_VERTEX_F(s * channel->scale[0]); |
OUT_VERTEX_F(t * channel->scale[1]); |
OUT_VERTEX_F(w); |
} |
} |
|
sse2 force_inline static void |
emit_vertex(struct sna *sna, |
const struct sna_composite_op *op, |
int16_t srcX, int16_t srcY, |
int16_t mskX, int16_t mskY, |
int16_t dstX, int16_t dstY) |
{ |
OUT_VERTEX(dstX, dstY); |
emit_texcoord(sna, &op->src, srcX, srcY); |
} |
|
sse2 fastcall static void |
emit_primitive(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
emit_vertex(sna, op, |
r->src.x + r->width, r->src.y + r->height, |
r->mask.x + r->width, r->mask.y + r->height, |
r->dst.x + r->width, r->dst.y + r->height); |
emit_vertex(sna, op, |
r->src.x, r->src.y + r->height, |
r->mask.x, r->mask.y + r->height, |
r->dst.x, r->dst.y + r->height); |
emit_vertex(sna, op, |
r->src.x, r->src.y, |
r->mask.x, r->mask.y, |
r->dst.x, r->dst.y); |
} |
|
sse2 force_inline static void |
emit_vertex_mask(struct sna *sna, |
const struct sna_composite_op *op, |
int16_t srcX, int16_t srcY, |
int16_t mskX, int16_t mskY, |
int16_t dstX, int16_t dstY) |
{ |
OUT_VERTEX(dstX, dstY); |
emit_texcoord(sna, &op->src, srcX, srcY); |
emit_texcoord(sna, &op->mask, mskX, mskY); |
} |
|
sse2 fastcall static void |
emit_primitive_mask(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
emit_vertex_mask(sna, op, |
r->src.x + r->width, r->src.y + r->height, |
r->mask.x + r->width, r->mask.y + r->height, |
r->dst.x + r->width, r->dst.y + r->height); |
emit_vertex_mask(sna, op, |
r->src.x, r->src.y + r->height, |
r->mask.x, r->mask.y + r->height, |
r->dst.x, r->dst.y + r->height); |
emit_vertex_mask(sna, op, |
r->src.x, r->src.y, |
r->mask.x, r->mask.y, |
r->dst.x, r->dst.y); |
} |
|
sse2 fastcall static void |
emit_primitive_solid(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
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 += 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[2] = dst.f; |
dst.p.y = r->dst.y; |
v[4] = dst.f; |
|
v[5] = v[3] = v[1] = .5; |
} |
|
sse2 fastcall static void |
emit_boxes_solid(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[2] = dst.f; |
dst.p.y = box->y1; |
v[4] = dst.f; |
|
v[5] = v[3] = v[1] = .5; |
box++; |
v += 6; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_linear(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
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 += 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[2] = dst.f; |
dst.p.y = r->dst.y; |
v[4] = dst.f; |
|
v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); |
v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); |
v[5] = compute_linear(&op->src, r->src.x, r->src.y); |
} |
|
sse2 fastcall static void |
emit_boxes_linear(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
do { |
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[2] = dst.f; |
dst.p.y = box->y1; |
v[4] = dst.f; |
|
v[1] = compute_linear(&op->src, box->x2, box->y2); |
v[3] = compute_linear(&op->src, box->x1, box->y2); |
v[5] = compute_linear(&op->src, box->x1, box->y1); |
|
v += 6; |
box++; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_identity_source(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float *v; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 9; |
|
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; |
dst.p.y = r->dst.y; |
v[6] = dst.f; |
|
v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; |
v[1] = v[4] + r->width * op->src.scale[0]; |
|
v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; |
v[5] = v[2] = v[8] + r->height * op->src.scale[1]; |
} |
|
sse2 fastcall static void |
emit_boxes_identity_source(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[3] = dst.f; |
dst.p.y = box->y1; |
v[6] = dst.f; |
|
v[7] = v[4] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; |
v[1] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; |
|
v[8] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; |
v[2] = v[5] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; |
|
v += 9; |
box++; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_simple_source(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 3*3; |
|
dst.p.x = r->dst.x + r->width; |
dst.p.y = r->dst.y + r->height; |
v[0] = dst.f; |
v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; |
v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; |
|
dst.p.x = r->dst.x; |
v[3] = dst.f; |
v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx; |
|
dst.p.y = r->dst.y; |
v[6] = dst.f; |
v[8] = ((r->src.y + ty) * yy + y0) * sy; |
} |
|
sse2 fastcall static void |
emit_boxes_simple_source(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[1] = ((box->x2 + tx) * xx + x0) * sx; |
v[5] = v[2] = ((box->y2 + ty) * yy + y0) * sy; |
|
dst.p.x = box->x1; |
v[3] = dst.f; |
v[7] = v[4] = ((box->x1 + tx) * xx + x0) * sx; |
|
dst.p.y = box->y1; |
v[6] = dst.f; |
v[8] = ((box->y1 + ty) * yy + y0) * sy; |
|
v += 9; |
box++; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_affine_source(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float *v; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 9; |
|
dst.p.x = r->dst.x + r->width; |
dst.p.y = r->dst.y + r->height; |
v[0] = dst.f; |
_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_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_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]); |
} |
|
sse2 fastcall static void |
emit_boxes_affine_source(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
_sna_get_transformed_scaled(op->src.offset[0] + box->x2, |
op->src.offset[1] + box->y2, |
op->src.transform, op->src.scale, |
&v[1], &v[2]); |
|
dst.p.x = box->x1; |
v[3] = dst.f; |
_sna_get_transformed_scaled(op->src.offset[0] + box->x1, |
op->src.offset[1] + box->y2, |
op->src.transform, op->src.scale, |
&v[4], &v[5]); |
|
dst.p.y = box->y1; |
v[6] = dst.f; |
_sna_get_transformed_scaled(op->src.offset[0] + box->x1, |
op->src.offset[1] + box->y1, |
op->src.transform, op->src.scale, |
&v[7], &v[8]); |
box++; |
v += 9; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_identity_mask(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x, msk_y; |
float w, h; |
float *v; |
|
msk_x = r->mask.x + op->mask.offset[0]; |
msk_y = r->mask.y + op->mask.offset[1]; |
w = r->width; |
h = r->height; |
|
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 == 12); |
assert((sna->render.vertex_used % 4) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
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[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[4] = dst.f; |
v[10] = v[6] = msk_x * op->mask.scale[0]; |
|
dst.p.y = r->dst.y; |
v[8] = dst.f; |
v[11] = msk_y * op->mask.scale[1]; |
|
v[9] = v[5] = v[1] = .5; |
} |
|
sse2 fastcall static void |
emit_boxes_identity_mask(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float msk_x = op->mask.offset[0]; |
float msk_y = op->mask.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[2] = (msk_x + box->x2) * op->mask.scale[0]; |
v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; |
|
dst.p.x = box->x1; |
v[4] = dst.f; |
v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; |
|
dst.p.y = box->y1; |
v[8] = dst.f; |
v[11] = (msk_y + box->y1) * op->mask.scale[1]; |
|
v[9] = v[5] = v[1] = .5; |
v += 12; |
box++; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_linear_identity_mask(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x, msk_y; |
float w, h; |
float *v; |
|
msk_x = r->mask.x + op->mask.offset[0]; |
msk_y = r->mask.y + op->mask.offset[1]; |
w = r->width; |
h = r->height; |
|
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 == 12); |
assert((sna->render.vertex_used % 4) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
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[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[4] = dst.f; |
v[10] = v[6] = msk_x * op->mask.scale[0]; |
|
dst.p.y = r->dst.y; |
v[8] = dst.f; |
v[11] = msk_y * op->mask.scale[1]; |
|
v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); |
v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); |
v[9] = compute_linear(&op->src, r->src.x, r->src.y); |
} |
|
sse2 fastcall static void |
emit_boxes_linear_identity_mask(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float msk_x = op->mask.offset[0]; |
float msk_y = op->mask.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[2] = (msk_x + box->x2) * op->mask.scale[0]; |
v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; |
|
dst.p.x = box->x1; |
v[4] = dst.f; |
v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; |
|
dst.p.y = box->y1; |
v[8] = dst.f; |
v[11] = (msk_y + box->y1) * op->mask.scale[1]; |
|
v[1] = compute_linear(&op->src, box->x2, box->y2); |
v[5] = compute_linear(&op->src, box->x1, box->y2); |
v[9] = compute_linear(&op->src, box->x1, box->y1); |
|
v += 12; |
box++; |
} while (--nbox); |
} |
|
sse2 fastcall static void |
emit_primitive_identity_source_mask(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
272,8 → 870,831 |
v[14] = msk_y * op->mask.scale[1]; |
} |
|
unsigned gen4_choose_composite_emitter(struct sna_composite_op *tmp) |
sse2 fastcall static void |
emit_primitive_simple_source_identity(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
float msk_x = r->mask.x + op->mask.offset[0]; |
float msk_y = r->mask.y + op->mask.offset[1]; |
float w = r->width, h = r->height; |
|
assert(op->floats_per_rect == 15); |
assert((sna->render.vertex_used % 5) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 3*5; |
|
dst.p.x = r->dst.x + r->width; |
dst.p.y = r->dst.y + r->height; |
v[0] = dst.f; |
v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; |
v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; |
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; |
v[6] = ((r->src.x + tx) * xx + x0) * sx; |
v[7] = v[2]; |
v[8] = msk_x * op->mask.scale[0]; |
v[9] = v[4]; |
|
dst.p.y = r->dst.y; |
v[10] = dst.f; |
v[11] = v[6]; |
v[12] = ((r->src.y + ty) * yy + y0) * sy; |
v[13] = v[8]; |
v[14] = msk_y * op->mask.scale[1]; |
} |
|
sse2 fastcall static void |
emit_primitive_affine_source_identity(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x = r->mask.x + op->mask.offset[0]; |
float msk_y = r->mask.y + op->mask.offset[1]; |
float w = r->width, h = r->height; |
|
assert(op->floats_per_rect == 15); |
assert((sna->render.vertex_used % 5) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 3*5; |
|
dst.p.x = r->dst.x + r->width; |
dst.p.y = r->dst.y + r->height; |
v[0] = dst.f; |
_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_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_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]; |
} |
|
/* SSE4_2 */ |
#if defined(sse4_2) |
|
sse4_2 fastcall static void |
emit_primitive_linear__sse4_2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
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 += 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[2] = dst.f; |
dst.p.y = r->dst.y; |
v[4] = dst.f; |
|
v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); |
v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); |
v[5] = compute_linear(&op->src, r->src.x, r->src.y); |
} |
|
sse4_2 fastcall static void |
emit_boxes_linear__sse4_2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
do { |
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[2] = dst.f; |
dst.p.y = box->y1; |
v[4] = dst.f; |
|
v[1] = compute_linear(&op->src, box->x2, box->y2); |
v[3] = compute_linear(&op->src, box->x1, box->y2); |
v[5] = compute_linear(&op->src, box->x1, box->y1); |
|
v += 6; |
box++; |
} while (--nbox); |
} |
|
sse4_2 fastcall static void |
emit_primitive_identity_source__sse4_2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float *v; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 9; |
|
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; |
dst.p.y = r->dst.y; |
v[6] = dst.f; |
|
v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; |
v[1] = v[4] + r->width * op->src.scale[0]; |
|
v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; |
v[5] = v[2] = v[8] + r->height * op->src.scale[1]; |
} |
|
sse4_2 fastcall static void |
emit_boxes_identity_source__sse4_2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[3] = dst.f; |
dst.p.y = box->y1; |
v[6] = dst.f; |
|
v[7] = v[4] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; |
v[1] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; |
|
v[8] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; |
v[2] = v[5] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; |
|
v += 9; |
box++; |
} while (--nbox); |
} |
|
sse4_2 fastcall static void |
emit_primitive_simple_source__sse4_2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 3*3; |
|
dst.p.x = r->dst.x + r->width; |
dst.p.y = r->dst.y + r->height; |
v[0] = dst.f; |
v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; |
v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; |
|
dst.p.x = r->dst.x; |
v[3] = dst.f; |
v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx; |
|
dst.p.y = r->dst.y; |
v[6] = dst.f; |
v[8] = ((r->src.y + ty) * yy + y0) * sy; |
} |
|
sse4_2 fastcall static void |
emit_boxes_simple_source__sse4_2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[1] = ((box->x2 + tx) * xx + x0) * sx; |
v[5] = v[2] = ((box->y2 + ty) * yy + y0) * sy; |
|
dst.p.x = box->x1; |
v[3] = dst.f; |
v[7] = v[4] = ((box->x1 + tx) * xx + x0) * sx; |
|
dst.p.y = box->y1; |
v[6] = dst.f; |
v[8] = ((box->y1 + ty) * yy + y0) * sy; |
|
v += 9; |
box++; |
} while (--nbox); |
} |
|
sse4_2 fastcall static void |
emit_primitive_identity_mask__sse4_2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x, msk_y; |
float w, h; |
float *v; |
|
msk_x = r->mask.x + op->mask.offset[0]; |
msk_y = r->mask.y + op->mask.offset[1]; |
w = r->width; |
h = r->height; |
|
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 == 12); |
assert((sna->render.vertex_used % 4) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
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[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[4] = dst.f; |
v[10] = v[6] = msk_x * op->mask.scale[0]; |
|
dst.p.y = r->dst.y; |
v[8] = dst.f; |
v[11] = msk_y * op->mask.scale[1]; |
|
v[9] = v[5] = v[1] = .5; |
} |
|
sse4_2 fastcall static void |
emit_boxes_identity_mask__sse4_2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float msk_x = op->mask.offset[0]; |
float msk_y = op->mask.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[2] = (msk_x + box->x2) * op->mask.scale[0]; |
v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; |
|
dst.p.x = box->x1; |
v[4] = dst.f; |
v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; |
|
dst.p.y = box->y1; |
v[8] = dst.f; |
v[11] = (msk_y + box->y1) * op->mask.scale[1]; |
|
v[9] = v[5] = v[1] = .5; |
v += 12; |
box++; |
} while (--nbox); |
} |
|
sse4_2 fastcall static void |
emit_primitive_linear_identity_mask__sse4_2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x, msk_y; |
float w, h; |
float *v; |
|
msk_x = r->mask.x + op->mask.offset[0]; |
msk_y = r->mask.y + op->mask.offset[1]; |
w = r->width; |
h = r->height; |
|
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 == 12); |
assert((sna->render.vertex_used % 4) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
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[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[4] = dst.f; |
v[10] = v[6] = msk_x * op->mask.scale[0]; |
|
dst.p.y = r->dst.y; |
v[8] = dst.f; |
v[11] = msk_y * op->mask.scale[1]; |
|
v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); |
v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); |
v[9] = compute_linear(&op->src, r->src.x, r->src.y); |
} |
|
sse4_2 fastcall static void |
emit_boxes_linear_identity_mask__sse4_2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float msk_x = op->mask.offset[0]; |
float msk_y = op->mask.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[2] = (msk_x + box->x2) * op->mask.scale[0]; |
v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; |
|
dst.p.x = box->x1; |
v[4] = dst.f; |
v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; |
|
dst.p.y = box->y1; |
v[8] = dst.f; |
v[11] = (msk_y + box->y1) * op->mask.scale[1]; |
|
v[1] = compute_linear(&op->src, box->x2, box->y2); |
v[5] = compute_linear(&op->src, box->x1, box->y2); |
v[9] = compute_linear(&op->src, box->x1, box->y1); |
|
v += 12; |
box++; |
} while (--nbox); |
} |
|
#endif |
|
/* AVX2 */ |
#if defined(avx2) |
|
avx2 fastcall static void |
emit_primitive_linear__avx2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
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 += 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[2] = dst.f; |
dst.p.y = r->dst.y; |
v[4] = dst.f; |
|
v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); |
v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); |
v[5] = compute_linear(&op->src, r->src.x, r->src.y); |
} |
|
avx2 fastcall static void |
emit_boxes_linear__avx2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
do { |
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[2] = dst.f; |
dst.p.y = box->y1; |
v[4] = dst.f; |
|
v[1] = compute_linear(&op->src, box->x2, box->y2); |
v[3] = compute_linear(&op->src, box->x1, box->y2); |
v[5] = compute_linear(&op->src, box->x1, box->y1); |
|
v += 6; |
box++; |
} while (--nbox); |
} |
|
avx2 fastcall static void |
emit_primitive_identity_source__avx2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float *v; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 9; |
|
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; |
dst.p.y = r->dst.y; |
v[6] = dst.f; |
|
v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; |
v[1] = v[4] + r->width * op->src.scale[0]; |
|
v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; |
v[5] = v[2] = v[8] + r->height * op->src.scale[1]; |
} |
|
avx2 fastcall static void |
emit_boxes_identity_source__avx2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
dst.p.x = box->x1; |
v[3] = dst.f; |
dst.p.y = box->y1; |
v[6] = dst.f; |
|
v[7] = v[4] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; |
v[1] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; |
|
v[8] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; |
v[2] = v[5] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; |
|
v += 9; |
box++; |
} while (--nbox); |
} |
|
avx2 fastcall static void |
emit_primitive_simple_source__avx2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
float *v; |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
|
assert(op->floats_per_rect == 9); |
assert((sna->render.vertex_used % 3) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
sna->render.vertex_used += 3*3; |
|
dst.p.x = r->dst.x + r->width; |
dst.p.y = r->dst.y + r->height; |
v[0] = dst.f; |
v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; |
v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; |
|
dst.p.x = r->dst.x; |
v[3] = dst.f; |
v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx; |
|
dst.p.y = r->dst.y; |
v[6] = dst.f; |
v[8] = ((r->src.y + ty) * yy + y0) * sy; |
} |
|
avx2 fastcall static void |
emit_boxes_simple_source__avx2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float xx = op->src.transform->matrix[0][0]; |
float x0 = op->src.transform->matrix[0][2]; |
float yy = op->src.transform->matrix[1][1]; |
float y0 = op->src.transform->matrix[1][2]; |
float sx = op->src.scale[0]; |
float sy = op->src.scale[1]; |
int16_t tx = op->src.offset[0]; |
int16_t ty = op->src.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[1] = ((box->x2 + tx) * xx + x0) * sx; |
v[5] = v[2] = ((box->y2 + ty) * yy + y0) * sy; |
|
dst.p.x = box->x1; |
v[3] = dst.f; |
v[7] = v[4] = ((box->x1 + tx) * xx + x0) * sx; |
|
dst.p.y = box->y1; |
v[6] = dst.f; |
v[8] = ((box->y1 + ty) * yy + y0) * sy; |
|
v += 9; |
box++; |
} while (--nbox); |
} |
|
avx2 fastcall static void |
emit_primitive_identity_mask__avx2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x, msk_y; |
float w, h; |
float *v; |
|
msk_x = r->mask.x + op->mask.offset[0]; |
msk_y = r->mask.y + op->mask.offset[1]; |
w = r->width; |
h = r->height; |
|
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 == 12); |
assert((sna->render.vertex_used % 4) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
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[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[4] = dst.f; |
v[10] = v[6] = msk_x * op->mask.scale[0]; |
|
dst.p.y = r->dst.y; |
v[8] = dst.f; |
v[11] = msk_y * op->mask.scale[1]; |
|
v[9] = v[5] = v[1] = .5; |
} |
|
avx2 fastcall static void |
emit_boxes_identity_mask__avx2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float msk_x = op->mask.offset[0]; |
float msk_y = op->mask.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[2] = (msk_x + box->x2) * op->mask.scale[0]; |
v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; |
|
dst.p.x = box->x1; |
v[4] = dst.f; |
v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; |
|
dst.p.y = box->y1; |
v[8] = dst.f; |
v[11] = (msk_y + box->y1) * op->mask.scale[1]; |
|
v[9] = v[5] = v[1] = .5; |
v += 12; |
box++; |
} while (--nbox); |
} |
|
avx2 fastcall static void |
emit_primitive_linear_identity_mask__avx2(struct sna *sna, |
const struct sna_composite_op *op, |
const struct sna_composite_rectangles *r) |
{ |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
float msk_x, msk_y; |
float w, h; |
float *v; |
|
msk_x = r->mask.x + op->mask.offset[0]; |
msk_y = r->mask.y + op->mask.offset[1]; |
w = r->width; |
h = r->height; |
|
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 == 12); |
assert((sna->render.vertex_used % 4) == 0); |
v = sna->render.vertices + sna->render.vertex_used; |
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[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[4] = dst.f; |
v[10] = v[6] = msk_x * op->mask.scale[0]; |
|
dst.p.y = r->dst.y; |
v[8] = dst.f; |
v[11] = msk_y * op->mask.scale[1]; |
|
v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); |
v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); |
v[9] = compute_linear(&op->src, r->src.x, r->src.y); |
} |
|
avx2 fastcall static void |
emit_boxes_linear_identity_mask__avx2(const struct sna_composite_op *op, |
const BoxRec *box, int nbox, |
float *v) |
{ |
float msk_x = op->mask.offset[0]; |
float msk_y = op->mask.offset[1]; |
|
do { |
union { |
struct sna_coordinate p; |
float f; |
} dst; |
|
dst.p.x = box->x2; |
dst.p.y = box->y2; |
v[0] = dst.f; |
v[2] = (msk_x + box->x2) * op->mask.scale[0]; |
v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; |
|
dst.p.x = box->x1; |
v[4] = dst.f; |
v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; |
|
dst.p.y = box->y1; |
v[8] = dst.f; |
v[11] = (msk_y + box->y1) * op->mask.scale[1]; |
|
v[1] = compute_linear(&op->src, box->x2, box->y2); |
v[5] = compute_linear(&op->src, box->x1, box->y2); |
v[9] = compute_linear(&op->src, box->x1, box->y1); |
|
v += 12; |
box++; |
} while (--nbox); |
} |
|
#endif |
|
unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op *tmp) |
{ |
unsigned vb; |
|
if (tmp->mask.bo) { |
280,8 → 1701,38 |
if (tmp->mask.transform == NULL) { |
if (tmp->src.is_solid) { |
DBG(("%s: solid, identity mask\n", __FUNCTION__)); |
#if defined(avx2) |
if (sna->cpu_features & AVX2) { |
tmp->prim_emit = emit_primitive_identity_mask__avx2; |
} else |
#endif |
#if defined(sse4_2) |
if (sna->cpu_features & SSE4_2) { |
tmp->prim_emit = emit_primitive_identity_mask__sse4_2; |
} else |
#endif |
{ |
tmp->prim_emit = emit_primitive_identity_mask; |
} |
tmp->floats_per_vertex = 4; |
vb = 1 | 2 << 2; |
} else if (tmp->src.is_linear) { |
DBG(("%s: linear, identity mask\n", __FUNCTION__)); |
#if defined(avx2) |
if (sna->cpu_features & AVX2) { |
tmp->prim_emit = emit_primitive_linear_identity_mask__avx2; |
} else |
#endif |
#if defined(sse4_2) |
if (sna->cpu_features & SSE4_2) { |
tmp->prim_emit = emit_primitive_linear_identity_mask__sse4_2; |
} else |
#endif |
{ |
tmp->prim_emit = emit_primitive_linear_identity_mask; |
} |
tmp->floats_per_vertex = 4; |
vb = 1 | 2 << 2; |
} else if (tmp->src.transform == NULL) { |
DBG(("%s: identity source, identity mask\n", __FUNCTION__)); |
tmp->prim_emit = emit_primitive_identity_source_mask; |
288,17 → 1739,130 |
tmp->floats_per_vertex = 5; |
vb = 2 << 2 | 2; |
} else if (tmp->src.is_affine) { |
tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; |
tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; |
if (!sna_affine_transform_is_rotation(tmp->src.transform)) { |
DBG(("%s: simple src, identity mask\n", __FUNCTION__)); |
tmp->prim_emit = emit_primitive_simple_source_identity; |
} else { |
DBG(("%s: affine src, identity mask\n", __FUNCTION__)); |
tmp->prim_emit = emit_primitive_affine_source_identity; |
} |
tmp->floats_per_vertex = 5; |
vb = 2 << 2 | 2; |
} else { |
DBG(("%s: projective source, identity mask\n", __FUNCTION__)); |
tmp->prim_emit = emit_primitive_mask; |
tmp->floats_per_vertex = 6; |
vb = 2 << 2 | 3; |
} |
} else { |
tmp->prim_emit = emit_primitive_mask; |
tmp->floats_per_vertex = 1; |
vb = 0; |
if (tmp->mask.is_solid) { |
tmp->floats_per_vertex += 1; |
vb |= 1 << 2; |
} else if (tmp->mask.is_affine) { |
tmp->floats_per_vertex += 2; |
vb |= 2 << 2; |
}else { |
tmp->floats_per_vertex += 3; |
vb |= 3 << 2; |
} |
if (tmp->src.is_solid) { |
tmp->floats_per_vertex += 1; |
vb |= 1; |
} else if (tmp->src.is_affine) { |
tmp->floats_per_vertex += 2; |
vb |= 2 ; |
}else { |
tmp->floats_per_vertex += 3; |
vb |= 3; |
} |
DBG(("%s: general mask: floats-per-vertex=%d, vb=%x\n", |
__FUNCTION__,tmp->floats_per_vertex, vb)); |
} |
} else { |
#if 0 |
if (tmp->src.is_solid) { |
DBG(("%s: solid, no mask\n", __FUNCTION__)); |
tmp->prim_emit = emit_primitive_solid; |
if (tmp->src.is_opaque && tmp->op == PictOpOver) |
tmp->op = PictOpSrc; |
tmp->floats_per_vertex = 2; |
vb = 1; |
} else if (tmp->src.is_linear) { |
DBG(("%s: linear, no mask\n", __FUNCTION__)); |
#if defined(avx2) |
if (sna->cpu_features & AVX2) { |
tmp->prim_emit = emit_primitive_linear__avx2; |
} else |
#endif |
#if defined(sse4_2) |
if (sna->cpu_features & SSE4_2) { |
tmp->prim_emit = emit_primitive_linear__sse4_2; |
} else |
#endif |
{ |
tmp->prim_emit = emit_primitive_linear; |
} |
tmp->floats_per_vertex = 2; |
vb = 1; |
} else if (tmp->src.transform == NULL) { |
DBG(("%s: identity src, no mask\n", __FUNCTION__)); |
#if defined(avx2) |
if (sna->cpu_features & AVX2) { |
tmp->prim_emit = emit_primitive_identity_source__avx2; |
} else |
#endif |
#if defined(sse4_2) |
if (sna->cpu_features & SSE4_2) { |
tmp->prim_emit = emit_primitive_identity_source__sse4_2; |
} else |
#endif |
{ |
tmp->prim_emit = emit_primitive_identity_source; |
} |
tmp->floats_per_vertex = 3; |
vb = 2; |
} else if (tmp->src.is_affine) { |
tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; |
tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; |
if (!sna_affine_transform_is_rotation(tmp->src.transform)) { |
DBG(("%s: simple src, no mask\n", __FUNCTION__)); |
#if defined(avx2) |
if (sna->cpu_features & AVX2) { |
tmp->prim_emit = emit_primitive_simple_source__avx2; |
} else |
#endif |
#if defined(sse4_2) |
if (sna->cpu_features & SSE4_2) { |
tmp->prim_emit = emit_primitive_simple_source__sse4_2; |
} else |
#endif |
{ |
tmp->prim_emit = emit_primitive_simple_source; |
} |
} else { |
DBG(("%s: affine src, no mask\n", __FUNCTION__)); |
tmp->prim_emit = emit_primitive_affine_source; |
} |
tmp->floats_per_vertex = 3; |
vb = 2; |
} else { |
DBG(("%s: projective src, no mask\n", __FUNCTION__)); |
assert(!tmp->src.is_solid); |
tmp->prim_emit = emit_primitive; |
tmp->floats_per_vertex = 4; |
vb = 3; |
} |
#endif |
} |
tmp->floats_per_rect = 3 * tmp->floats_per_vertex; |
|
return vb; |
} |
|
|
|