summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-01 11:17:32 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-01 21:41:23 +0100
commitf6c8c3bb6fd75bca6c7704b7d5869a5d44ce3832 (patch)
tree7432e5b68cddf0707ee4c5b75259e7dd0f3dd839
parentde14e3c8595f9e315dc3ce23ad15b04e118499f4 (diff)
sna/gen2: Use specular component for solid spans
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen2_render.c152
-rw-r--r--src/sna/gen2_render.h7
-rw-r--r--src/sna/gen3_render.c190
-rw-r--r--src/sna/sna_render.h15
4 files changed, 244 insertions, 120 deletions
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 770ec7ea..f4177f75 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -936,6 +936,7 @@ gen2_composite_solid_init(struct sna *sna,
channel->pict_format = PICT_a8r8g8b8;
channel->bo = sna_render_get_solid(sna, color);
+ channel->u.gen2.pixel = color;
channel->scale[0] = channel->scale[1] = 1;
channel->offset[0] = channel->offset[1] = 0;
@@ -1282,6 +1283,101 @@ cleanup_dst:
}
static void
+gen2_emit_composite_spans_primitive_constant(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ float *v = (float *)sna->kgem.batch + sna->kgem.nbatch;
+ uint32_t alpha = (uint8_t)(255 * opacity) << 24;
+ sna->kgem.nbatch += 9;
+
+ v[0] = op->base.dst.x + box->x2;
+ v[1] = op->base.dst.y + box->y2;
+ *((uint32_t *)v + 2) = alpha;
+
+ v[3] = op->base.dst.x + box->x1;
+ v[4] = v[1];
+ *((uint32_t *)v + 5) = alpha;
+
+ v[6] = v[3];
+ v[7] = op->base.dst.y + box->y1;
+ *((uint32_t *)v + 8) = alpha;
+}
+
+static void
+gen2_emit_composite_spans_primitive_identity_source(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ float *v = (float *)sna->kgem.batch + sna->kgem.nbatch;
+ uint32_t alpha = (uint8_t)(255 * opacity) << 24;
+ sna->kgem.nbatch += 15;
+
+ v[0] = op->base.dst.x + box->x2;
+ v[1] = op->base.dst.y + box->y2;
+ *((uint32_t *)v + 2) = alpha;
+ v[3] = (op->base.src.offset[0] + box->x2) * op->base.src.scale[0];
+ v[4] = (op->base.src.offset[1] + box->y2) * op->base.src.scale[1];
+
+ v[5] = op->base.dst.x + box->x1;
+ v[6] = v[1];
+ *((uint32_t *)v + 7) = alpha;
+ v[8] = (op->base.src.offset[0] + box->x1) * op->base.src.scale[0];
+ v[9] = v[4];
+
+ v[10] = v[5];
+ v[11] = op->base.dst.y + box->y1;
+ *((uint32_t *)v + 12) = alpha;
+ v[13] = v[8];
+ v[14] = (op->base.src.offset[1] + box->y1) * op->base.src.scale[1];
+}
+
+static void
+gen2_emit_composite_spans_primitive_affine_source(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ PictTransform *transform = op->base.src.transform;
+ uint32_t alpha = (uint8_t)(255 * opacity) << 24;
+ float x, y, *v;
+
+ v = (float *)sna->kgem.batch + sna->kgem.nbatch;
+ sna->kgem.nbatch += 15;
+
+ v[0] = op->base.dst.x + box->x2;
+ 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;
+ *((uint32_t *)v + 2) = alpha;
+ *((uint32_t *)v + 7) = alpha;
+ *((uint32_t *)v + 12) = alpha;
+
+ _sna_get_transformed_coordinates((int)op->base.src.offset[0] + box->x2,
+ (int)op->base.src.offset[1] + box->y2,
+ transform,
+ &x, &y);
+ v[3] = x * op->base.src.scale[0];
+ v[4] = 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[8] = x * op->base.src.scale[0];
+ v[9] = 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[13] = x * op->base.src.scale[0];
+ v[14] = y * op->base.src.scale[1];
+}
+
+static void
gen2_emit_composite_spans_vertex(struct sna *sna,
const struct sna_composite_spans_op *op,
int16_t x, int16_t y,
@@ -1318,9 +1414,14 @@ gen2_emit_spans_pipeline(struct sna *sna,
TB0A_ARG1_SEL_DIFFUSE |
TB0A_OUTPUT_WRITE_CURRENT;
- if (op->base.dst.format == PICT_a8) {
+ if (op->base.src.is_solid) {
+ ablend |= TB0A_ARG2_SEL_SPECULAR;
+ cblend |= TB0C_ARG2_SEL_SPECULAR;
+ if (op->base.dst.format == PICT_a8)
+ cblend |= TB0C_ARG2_REPLICATE_ALPHA;
+ } else if (op->base.dst.format == PICT_a8) {
ablend |= TB0A_ARG2_SEL_TEXEL0;
- cblend |= TB0C_ARG2_SEL_TEXEL0 | TB0C_ARG2_REPLICATE_ALPHA;;
+ cblend |= TB0C_ARG2_SEL_TEXEL0 | TB0C_ARG2_REPLICATE_ALPHA;
} else {
if (PICT_FORMAT_RGB(op->base.src.pict_format) != 0)
cblend |= TB0C_ARG2_SEL_TEXEL0;
@@ -1347,18 +1448,23 @@ static void gen2_emit_composite_spans_state(struct sna *sna,
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2);
- OUT_BATCH(1 << 12);
+ OUT_BATCH(!op->base.src.is_solid << 12);
OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY | S3_DIFFUSE_PRESENT);
OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |
gen2_get_blend_cntl(op->base.op, FALSE, op->base.dst.format) |
S8_ENABLE_COLOR_BUFFER_WRITE);
+ gen2_disable_logic_op(sna);
gen2_emit_spans_pipeline(sna, op);
- OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD |
- (op->base.src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_3D));
-
- gen2_emit_texture(sna, &op->base.src, 0);
+ if (op->base.src.is_solid) {
+ OUT_BATCH(_3DSTATE_DFLT_SPECULAR_CMD);
+ OUT_BATCH(op->base.src.u.gen2.pixel);
+ } else {
+ OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD |
+ (op->base.src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_3D));
+ gen2_emit_texture(sna, &op->base.src, 0);
+ }
}
static void
@@ -1469,8 +1575,27 @@ gen2_render_composite_spans(struct sna *sna,
tmp->prim_emit = gen2_emit_composite_spans_primitive;
tmp->base.floats_per_vertex = 3;
- if (tmp->base.src.bo)
+ if (tmp->base.src.is_solid) {
+ tmp->prim_emit = gen2_emit_composite_spans_primitive_constant;
+ } else {
+ assert(tmp->base.src.bo);
tmp->base.floats_per_vertex += tmp->base.src.is_affine ? 2 : 3;
+ if (tmp->base.src.transform == NULL)
+ tmp->prim_emit = gen2_emit_composite_spans_primitive_identity_source;
+ else if (tmp->base.src.is_affine)
+ tmp->prim_emit = gen2_emit_composite_spans_primitive_affine_source;
+
+ if (kgem_bo_is_dirty(tmp->base.src.bo)) {
+ if (tmp->base.src.bo == tmp->base.dst.bo) {
+ kgem_emit_flush(&sna->kgem);
+ } else {
+ OUT_BATCH(_3DSTATE_MODES_5_CMD |
+ PIPELINE_FLUSH_RENDER_CACHE |
+ PIPELINE_FLUSH_TEXTURE_CACHE);
+ kgem_clear_dirty(&sna->kgem);
+ }
+ }
+ }
tmp->boxes = gen2_render_composite_spans_boxes;
tmp->done = gen2_render_composite_spans_done;
@@ -1480,17 +1605,6 @@ gen2_render_composite_spans(struct sna *sna,
if (!kgem_check_bo(&sna->kgem, tmp->base.src.bo))
kgem_submit(&sna->kgem);
- if (kgem_bo_is_dirty(tmp->base.src.bo)) {
- if (tmp->base.src.bo == tmp->base.dst.bo) {
- kgem_emit_flush(&sna->kgem);
- } else {
- OUT_BATCH(_3DSTATE_MODES_5_CMD |
- PIPELINE_FLUSH_RENDER_CACHE |
- PIPELINE_FLUSH_TEXTURE_CACHE);
- kgem_clear_dirty(&sna->kgem);
- }
- }
-
gen2_emit_composite_spans_state(sna, tmp);
return TRUE;
diff --git a/src/sna/gen2_render.h b/src/sna/gen2_render.h
index c10d5402..2f41e9a1 100644
--- a/src/sna/gen2_render.h
+++ b/src/sna/gen2_render.h
@@ -80,7 +80,7 @@
#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16))
-#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16))
+#define _3DSTATE_DFLT_SPECULAR_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16))
#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16))
@@ -745,6 +745,8 @@
#define TB0C_ARG2_REPLICATE_ALPHA (1<<17)
#define TB0C_ARG2_INVERT (1<<16)
#define TB0C_ARG2_SEL_ONE (0 << 12)
+#define TB0C_ARG2_SEL_DIFFUSE (3 << 12)
+#define TB0C_ARG2_SEL_SPECULAR (4 << 12)
#define TB0C_ARG2_SEL_FACTOR (1 << 12)
#define TB0C_ARG2_SEL_TEXEL0 (6 << 12)
#define TB0C_ARG2_SEL_TEXEL1 (7 << 12)
@@ -754,6 +756,7 @@
#define TB0C_ARG1_INVERT (1<<10)
#define TB0C_ARG1_SEL_ONE (0 << 6)
#define TB0C_ARG1_SEL_DIFFUSE (3 << 6)
+#define TB0C_ARG1_SEL_SPECULAR (4 << 6)
#define TB0C_ARG1_SEL_TEXEL0 (6 << 6)
#define TB0C_ARG1_SEL_TEXEL1 (7 << 6)
#define TB0C_ARG1_SEL_TEXEL2 (8 << 6)
@@ -775,6 +778,7 @@
#define TB0A_ARG2_INVERT (1<<16)
#define TB0A_ARG2_SEL_ONE (0 << 12)
#define TB0A_ARG2_SEL_DIFFUSE (3 << 12)
+#define TB0A_ARG2_SEL_SPECULAR (4 << 12)
#define TB0A_ARG2_SEL_TEXEL0 (6 << 12)
#define TB0A_ARG2_SEL_TEXEL1 (7 << 12)
#define TB0A_ARG2_SEL_TEXEL2 (8 << 12)
@@ -782,6 +786,7 @@
#define TB0A_ARG1_INVERT (1<<10)
#define TB0A_ARG1_SEL_ONE (0 << 6)
#define TB0A_ARG1_SEL_DIFFUSE (3 << 6)
+#define TB0A_ARG1_SEL_SPECULAR (4 << 6)
#define TB0A_ARG1_SEL_TEXEL0 (6 << 6)
#define TB0A_ARG1_SEL_TEXEL1 (7 << 6)
#define TB0A_ARG1_SEL_TEXEL2 (8 << 6)
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index aba1b8d8..ee8de2d8 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -616,7 +616,7 @@ gen3_emit_composite_texcoord(struct sna *sna,
{
float s = 0, t = 0, w = 1;
- switch (channel->gen3.type) {
+ switch (channel->u.gen3.type) {
case SHADER_OPACITY:
case SHADER_NONE:
case SHADER_ZERO:
@@ -701,7 +701,7 @@ gen3_linear_coord(struct sna *sna,
const struct sna_composite_channel *channel,
int in, int out)
{
- int c = channel->gen3.constants;
+ int c = channel->u.gen3.constants;
if (!channel->is_affine) {
gen3_2d_perspective(sna, in, FS_U0);
@@ -719,14 +719,14 @@ gen3_radial_coord(struct sna *sna,
const struct sna_composite_channel *channel,
int in, int out)
{
- int c = channel->gen3.constants;
+ int c = channel->u.gen3.constants;
if (!channel->is_affine) {
gen3_2d_perspective(sna, in, FS_U0);
in = FS_U0;
}
- switch (channel->gen3.mode) {
+ switch (channel->u.gen3.mode) {
case RADIAL_ONE:
/*
pdx = (x - c1x) / dr, pdy = (y - c1y) / dr;
@@ -806,7 +806,7 @@ gen3_composite_emit_shader(struct sna *sna,
src = &op->src;
mask = &op->mask;
- if (mask->gen3.type == SHADER_NONE)
+ if (mask->u.gen3.type == SHADER_NONE)
mask = NULL;
if (mask && src->is_opaque &&
@@ -816,12 +816,12 @@ gen3_composite_emit_shader(struct sna *sna,
mask = NULL;
}
- id = (src->gen3.type |
+ id = (src->u.gen3.type |
src->is_affine << 4 |
src->alpha_fixup << 5 |
src->rb_reversed << 6);
if (mask) {
- id |= (mask->gen3.type << 8 |
+ id |= (mask->u.gen3.type << 8 |
mask->is_affine << 12 |
gen3_blend_op[blend].src_alpha << 13 |
op->has_component_alpha << 14 |
@@ -838,7 +838,7 @@ gen3_composite_emit_shader(struct sna *sna,
shader_offset = sna->kgem.nbatch++;
t = 0;
- switch (src->gen3.type) {
+ switch (src->u.gen3.type) {
case SHADER_NONE:
case SHADER_OPACITY:
assert(0);
@@ -858,7 +858,7 @@ gen3_composite_emit_shader(struct sna *sna,
}
if (mask == NULL) {
- if (src->gen3.type == SHADER_ZERO) {
+ if (src->u.gen3.type == SHADER_ZERO) {
gen3_fs_mov(FS_OC, gen3_fs_operand_zero());
goto done;
}
@@ -867,13 +867,13 @@ gen3_composite_emit_shader(struct sna *sna,
goto done;
}
/* No mask, so load directly to output color */
- if (src->gen3.type != SHADER_CONSTANT) {
+ if (src->u.gen3.type != SHADER_CONSTANT) {
if (dst_is_alpha || src->rb_reversed ^ op->rb_reversed)
src_reg = FS_R0;
else
src_reg = FS_OC;
}
- switch (src->gen3.type) {
+ switch (src->u.gen3.type) {
case SHADER_LINEAR:
gen3_linear_coord(sna, src, FS_T0, FS_R0);
gen3_fs_texld(src_reg, FS_S0, FS_R0);
@@ -916,7 +916,7 @@ gen3_composite_emit_shader(struct sna *sna,
if (op->rb_reversed)
out_reg = FS_U0;
- switch (mask->gen3.type) {
+ switch (mask->u.gen3.type) {
case SHADER_CONSTANT:
gen3_fs_dcl(FS_T9);
mask_reg = FS_T9;
@@ -935,7 +935,7 @@ gen3_composite_emit_shader(struct sna *sna,
}
t = 0;
- switch (src->gen3.type) {
+ switch (src->u.gen3.type) {
case SHADER_LINEAR:
gen3_linear_coord(sna, src, FS_T0, FS_R0);
gen3_fs_texld(FS_R0, FS_S0, FS_R0);
@@ -969,7 +969,7 @@ gen3_composite_emit_shader(struct sna *sna,
if (src->rb_reversed)
gen3_fs_mov(src_reg, gen3_fs_operand(src_reg, Z, Y, X, W));
- switch (mask->gen3.type) {
+ switch (mask->u.gen3.type) {
case SHADER_LINEAR:
gen3_linear_coord(sna, mask, FS_T0 + t, FS_R1);
gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
@@ -1188,17 +1188,17 @@ static void gen3_emit_composite_state(struct sna *sna,
ss2 = ~0;
tex_count = 0;
- switch (op->src.gen3.type) {
+ switch (op->src.u.gen3.type) {
case SHADER_OPACITY:
case SHADER_NONE:
assert(0);
case SHADER_ZERO:
break;
case SHADER_CONSTANT:
- if (op->src.gen3.mode != state->last_diffuse) {
+ if (op->src.u.gen3.mode != state->last_diffuse) {
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
- OUT_BATCH(op->src.gen3.mode);
- state->last_diffuse = op->src.gen3.mode;
+ OUT_BATCH(op->src.u.gen3.mode);
+ state->last_diffuse = op->src.u.gen3.mode;
}
break;
case SHADER_LINEAR:
@@ -1223,15 +1223,15 @@ static void gen3_emit_composite_state(struct sna *sna,
tex_count++;
break;
}
- switch (op->mask.gen3.type) {
+ switch (op->mask.u.gen3.type) {
case SHADER_NONE:
case SHADER_ZERO:
break;
case SHADER_CONSTANT:
- if (op->mask.gen3.mode != state->last_specular) {
+ if (op->mask.u.gen3.mode != state->last_specular) {
OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
- OUT_BATCH(op->mask.gen3.mode);
- state->last_specular = op->mask.gen3.mode;
+ OUT_BATCH(op->mask.u.gen3.mode);
+ state->last_specular = op->mask.u.gen3.mode;
}
break;
case SHADER_LINEAR:
@@ -1731,10 +1731,10 @@ gen3_init_solid(struct sna *sna,
struct sna_composite_channel *channel,
uint32_t color)
{
- channel->gen3.mode = color;
- channel->gen3.type = SHADER_CONSTANT;
+ channel->u.gen3.mode = color;
+ channel->u.gen3.type = SHADER_CONSTANT;
if (color == 0)
- channel->gen3.type = SHADER_ZERO;
+ channel->u.gen3.type = SHADER_ZERO;
if ((color & 0xff000000) == 0xff000000)
channel->is_opaque = true;
@@ -1749,7 +1749,7 @@ gen3_init_solid(struct sna *sna,
static void gen3_composite_channel_convert(struct sna_composite_channel *channel)
{
- if (channel->gen3.type == SHADER_TEXTURE)
+ if (channel->u.gen3.type == SHADER_TEXTURE)
channel->repeat = gen3_texture_repeat(channel->repeat);
else
channel->repeat = gen3_gradient_repeat(channel->repeat);
@@ -1837,7 +1837,7 @@ gen3_init_linear(struct sna *sna,
offset = dx*x0 + dy*y0;
n = op->u.gen3.num_constants;
- channel->gen3.constants = FS_C0 + n / 4;
+ channel->u.gen3.constants = FS_C0 + n / 4;
op->u.gen3.constants[n++] = dx;
op->u.gen3.constants[n++] = dy;
op->u.gen3.constants[n++] = -offset;
@@ -1846,11 +1846,11 @@ gen3_init_linear(struct sna *sna,
if (!gen3_gradient_setup(sna, picture, channel, ox, oy))
return 0;
- channel->gen3.type = SHADER_LINEAR;
+ channel->u.gen3.type = SHADER_LINEAR;
op->u.gen3.num_constants = n;
DBG(("%s: dx=%f, dy=%f, offset=%f, constants=%d\n",
- __FUNCTION__, dx, dy, -offset, channel->gen3.constants - FS_C0));
+ __FUNCTION__, dx, dy, -offset, channel->u.gen3.constants - FS_C0));
return 1;
}
@@ -1872,7 +1872,7 @@ gen3_init_radial(struct sna *sna,
r1 = xFixedToDouble(radial->c1.radius);
n = op->u.gen3.num_constants;
- channel->gen3.constants = FS_C0 + n / 4;
+ channel->u.gen3.constants = FS_C0 + n / 4;
if (radial->c2.x == radial->c1.x && radial->c2.y == radial->c1.y) {
if (radial->c2.radius == radial->c1.radius)
return 0;
@@ -1882,7 +1882,7 @@ gen3_init_radial(struct sna *sna,
op->u.gen3.constants[n++] = 1. / dr;
op->u.gen3.constants[n++] = -r1 / dr;
- channel->gen3.mode = RADIAL_ONE;
+ channel->u.gen3.mode = RADIAL_ONE;
} else {
op->u.gen3.constants[n++] = -xFixedToDouble(radial->c1.x);
op->u.gen3.constants[n++] = -xFixedToDouble(radial->c1.y);
@@ -1894,13 +1894,13 @@ gen3_init_radial(struct sna *sna,
op->u.gen3.constants[n++] = -2 * r1 * dr;
op->u.gen3.constants[n++] = 1 / (2 * (dx*dx + dy*dy - dr*dr));
- channel->gen3.mode = RADIAL_TWO;
+ channel->u.gen3.mode = RADIAL_TWO;
}
if (!gen3_gradient_setup(sna, picture, channel, ox, oy))
return 0;
- channel->gen3.type = SHADER_RADIAL;
+ channel->u.gen3.type = SHADER_RADIAL;
op->u.gen3.num_constants = n;
return 1;
}
@@ -2175,7 +2175,7 @@ gen3_render_composite(struct sna *sna,
return FALSE;
}
- tmp->src.gen3.type = SHADER_TEXTURE;
+ tmp->src.u.gen3.type = SHADER_TEXTURE;
tmp->src.is_affine = TRUE;
DBG(("%s: preparing source\n", __FUNCTION__));
switch (gen3_composite_picture(sna, src, tmp, &tmp->src,
@@ -2185,20 +2185,20 @@ gen3_render_composite(struct sna *sna,
case -1:
goto cleanup_dst;
case 0:
- tmp->src.gen3.type = SHADER_ZERO;
+ tmp->src.u.gen3.type = SHADER_ZERO;
break;
case 1:
gen3_composite_channel_convert(&tmp->src);
break;
}
- DBG(("%s: source type=%d\n", __FUNCTION__, tmp->src.gen3.type));
+ DBG(("%s: source type=%d\n", __FUNCTION__, tmp->src.u.gen3.type));
- tmp->mask.gen3.type = SHADER_NONE;
+ tmp->mask.u.gen3.type = SHADER_NONE;
tmp->mask.is_affine = TRUE;
tmp->need_magic_ca_pass = FALSE;
tmp->has_component_alpha = FALSE;
- if (mask && tmp->src.gen3.type != SHADER_ZERO) {
- tmp->mask.gen3.type = SHADER_TEXTURE;
+ if (mask && tmp->src.u.gen3.type != SHADER_ZERO) {
+ tmp->mask.u.gen3.type = SHADER_TEXTURE;
DBG(("%s: preparing mask\n", __FUNCTION__));
switch (gen3_composite_picture(sna, mask, tmp, &tmp->mask,
mask_x, mask_y,
@@ -2207,68 +2207,68 @@ gen3_render_composite(struct sna *sna,
case -1:
goto cleanup_src;
case 0:
- tmp->mask.gen3.type = SHADER_ZERO;
+ tmp->mask.u.gen3.type = SHADER_ZERO;
break;
case 1:
gen3_composite_channel_convert(&tmp->mask);
break;
}
- DBG(("%s: mask type=%d\n", __FUNCTION__, tmp->mask.gen3.type));
+ DBG(("%s: mask type=%d\n", __FUNCTION__, tmp->mask.u.gen3.type));
- if (tmp->mask.gen3.type == SHADER_ZERO) {
+ if (tmp->mask.u.gen3.type == SHADER_ZERO) {
if (tmp->src.bo) {
kgem_bo_destroy(&sna->kgem,
tmp->src.bo);
tmp->src.bo = NULL;
}
- tmp->src.gen3.type = SHADER_ZERO;
- tmp->mask.gen3.type = SHADER_NONE;
+ tmp->src.u.gen3.type = SHADER_ZERO;
+ tmp->mask.u.gen3.type = SHADER_NONE;
}
- if (tmp->mask.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.gen3.type == SHADER_CONSTANT &&
- tmp->mask.gen3.mode == 0xffffffff) {
- tmp->mask.gen3.type = SHADER_NONE;
+ if (tmp->mask.u.gen3.type == SHADER_CONSTANT &&
+ tmp->mask.u.gen3.mode == 0xffffffff) {
+ tmp->mask.u.gen3.type = SHADER_NONE;
tmp->has_component_alpha = FALSE;
- } else if (tmp->src.gen3.type == SHADER_CONSTANT &&
- tmp->src.gen3.mode == 0xffffffff) {
+ } else if (tmp->src.u.gen3.type == SHADER_CONSTANT &&
+ tmp->src.u.gen3.mode == 0xffffffff) {
tmp->src = tmp->mask;
- tmp->mask.gen3.type = SHADER_NONE;
+ tmp->mask.u.gen3.type = SHADER_NONE;
tmp->mask.bo = NULL;
tmp->has_component_alpha = FALSE;
- } else if (tmp->src.gen3.type == SHADER_CONSTANT &&
- tmp->mask.gen3.type == SHADER_CONSTANT) {
+ } else if (tmp->src.u.gen3.type == SHADER_CONSTANT &&
+ tmp->mask.u.gen3.type == SHADER_CONSTANT) {
uint32_t a,r,g,b;
- a = mult(tmp->src.gen3.mode,
- tmp->mask.gen3.mode,
+ a = mult(tmp->src.u.gen3.mode,
+ tmp->mask.u.gen3.mode,
24);
- r = mult(tmp->src.gen3.mode,
- tmp->mask.gen3.mode,
+ r = mult(tmp->src.u.gen3.mode,
+ tmp->mask.u.gen3.mode,
16);
- g = mult(tmp->src.gen3.mode,
- tmp->mask.gen3.mode,
+ g = mult(tmp->src.u.gen3.mode,
+ tmp->mask.u.gen3.mode,
8);
- b = mult(tmp->src.gen3.mode,
- tmp->mask.gen3.mode,
+ 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.gen3.mode,
- tmp->mask.gen3.mode,
+ tmp->src.u.gen3.mode,
+ tmp->mask.u.gen3.mode,
a << 24 | r << 16 | g << 8 | b));
- tmp->src.gen3.mode =
+ tmp->src.u.gen3.mode =
a << 24 | r << 16 | g << 8 | b;
- tmp->mask.gen3.type = SHADER_NONE;
+ 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)) {
@@ -2282,13 +2282,13 @@ gen3_render_composite(struct sna *sna,
}
}
DBG(("%s: final src/mask type=%d/%d, affine=%d/%d\n", __FUNCTION__,
- tmp->src.gen3.type, tmp->mask.gen3.type,
+ tmp->src.u.gen3.type, tmp->mask.u.gen3.type,
tmp->src.is_affine, tmp->mask.is_affine));
tmp->prim_emit = gen3_emit_composite_primitive;
- if (tmp->mask.gen3.type == SHADER_NONE ||
- tmp->mask.gen3.type == SHADER_CONSTANT) {
- switch (tmp->src.gen3.type) {
+ if (tmp->mask.u.gen3.type == SHADER_NONE ||
+ tmp->mask.u.gen3.type == SHADER_CONSTANT) {
+ switch (tmp->src.u.gen3.type) {
case SHADER_NONE:
case SHADER_CONSTANT:
tmp->prim_emit = gen3_emit_composite_primitive_constant;
@@ -2307,9 +2307,9 @@ gen3_render_composite(struct sna *sna,
tmp->prim_emit = gen3_emit_composite_primitive_affine_source;
break;
}
- } else if (tmp->mask.gen3.type == SHADER_TEXTURE) {
+ } else if (tmp->mask.u.gen3.type == SHADER_TEXTURE) {
if (tmp->mask.transform == NULL) {
- if (tmp->src.gen3.type == SHADER_CONSTANT)
+ if (tmp->src.u.gen3.type == SHADER_CONSTANT)
tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask;
else if (tmp->src.transform == NULL)
tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask;
@@ -2319,18 +2319,18 @@ gen3_render_composite(struct sna *sna,
}
tmp->floats_per_vertex = 2;
- if (tmp->src.gen3.type != SHADER_CONSTANT &&
- tmp->src.gen3.type != SHADER_ZERO)
+ if (tmp->src.u.gen3.type != SHADER_CONSTANT &&
+ tmp->src.u.gen3.type != SHADER_ZERO)
tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 4;
- if (tmp->mask.gen3.type != SHADER_NONE &&
- tmp->mask.gen3.type != SHADER_CONSTANT)
+ if (tmp->mask.u.gen3.type != SHADER_NONE &&
+ tmp->mask.u.gen3.type != SHADER_CONSTANT)
tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 4;
DBG(("%s: floats_per_vertex = 2 + %d + %d = %d\n", __FUNCTION__,
- (tmp->src.gen3.type != SHADER_CONSTANT &&
- tmp->src.gen3.type != SHADER_ZERO) ?
+ (tmp->src.u.gen3.type != SHADER_CONSTANT &&
+ tmp->src.u.gen3.type != SHADER_ZERO) ?
tmp->src.is_affine ? 2 : 4 : 0,
- (tmp->mask.gen3.type != SHADER_NONE &&
- tmp->mask.gen3.type != SHADER_CONSTANT) ?
+ (tmp->mask.u.gen3.type != SHADER_NONE &&
+ tmp->mask.u.gen3.type != SHADER_CONSTANT) ?
tmp->mask.is_affine ? 2 : 4 : 0,
tmp->floats_per_vertex));
@@ -2670,7 +2670,7 @@ gen3_render_composite_spans(struct sna *sna,
return FALSE;
}
- tmp->base.src.gen3.type = SHADER_TEXTURE;
+ tmp->base.src.u.gen3.type = SHADER_TEXTURE;
tmp->base.src.is_affine = TRUE;
DBG(("%s: preparing source\n", __FUNCTION__));
switch (gen3_composite_picture(sna, src, &tmp->base, &tmp->base.src,
@@ -2680,19 +2680,19 @@ gen3_render_composite_spans(struct sna *sna,
case -1:
goto cleanup_dst;
case 0:
- tmp->base.src.gen3.type = SHADER_ZERO;
+ tmp->base.src.u.gen3.type = SHADER_ZERO;
break;
case 1:
gen3_composite_channel_convert(&tmp->base.src);
break;
}
- DBG(("%s: source type=%d\n", __FUNCTION__, tmp->base.src.gen3.type));
+ DBG(("%s: source type=%d\n", __FUNCTION__, tmp->base.src.u.gen3.type));
- if (tmp->base.src.gen3.type != SHADER_ZERO)
- tmp->base.mask.gen3.type = SHADER_OPACITY;
+ if (tmp->base.src.u.gen3.type != SHADER_ZERO)
+ tmp->base.mask.u.gen3.type = SHADER_OPACITY;
tmp->prim_emit = gen3_emit_composite_spans_primitive;
- switch (tmp->base.src.gen3.type) {
+ switch (tmp->base.src.u.gen3.type) {
case SHADER_NONE:
assert(0);
case SHADER_ZERO:
@@ -2717,11 +2717,11 @@ gen3_render_composite_spans(struct sna *sna,
}
tmp->base.floats_per_vertex = 2;
- if (tmp->base.src.gen3.type != SHADER_CONSTANT &&
- tmp->base.src.gen3.type != SHADER_ZERO)
+ if (tmp->base.src.u.gen3.type != SHADER_CONSTANT &&
+ tmp->base.src.u.gen3.type != SHADER_ZERO)
tmp->base.floats_per_vertex += tmp->base.src.is_affine ? 2 : 3;
tmp->base.floats_per_vertex +=
- tmp->base.mask.gen3.type == SHADER_OPACITY;
+ tmp->base.mask.u.gen3.type == SHADER_OPACITY;
tmp->boxes = gen3_render_composite_spans_boxes;
tmp->done = gen3_render_composite_spans_done;
@@ -3230,7 +3230,7 @@ gen3_render_copy_setup_source(struct sna *sna,
PixmapPtr pixmap,
struct kgem_bo *bo)
{
- channel->gen3.type = SHADER_TEXTURE;
+ channel->u.gen3.type = SHADER_TEXTURE;
channel->filter = gen3_filter(PictFilterNearest);
channel->repeat = gen3_texture_repeat(RepeatNone);
channel->width = pixmap->drawable.width;
@@ -3313,7 +3313,7 @@ gen3_render_copy_boxes(struct sna *sna, uint8_t alu,
gen3_render_copy_setup_source(sna, &tmp.src, src, src_bo);
tmp.floats_per_vertex = 4;
- tmp.mask.gen3.type = SHADER_NONE;
+ tmp.mask.u.gen3.type = SHADER_NONE;
gen3_emit_composite_state(sna, &tmp);
gen3_align_vertex(sna, &tmp);
@@ -3441,7 +3441,7 @@ gen3_render_copy(struct sna *sna, uint8_t alu,
gen3_render_copy_setup_source(sna, &tmp->base.src, src, src_bo);
tmp->base.floats_per_vertex = 4;
- tmp->base.mask.gen3.type = SHADER_NONE;
+ tmp->base.mask.u.gen3.type = SHADER_NONE;
if (!kgem_check_bo(&sna->kgem, dst_bo))
kgem_submit(&sna->kgem);
@@ -3559,8 +3559,8 @@ gen3_render_fill_boxes(struct sna *sna,
tmp.dst.bo = dst_bo;
tmp.floats_per_vertex = 2;
- tmp.src.gen3.type = op == PictOpClear ? SHADER_ZERO : SHADER_CONSTANT;
- tmp.src.gen3.mode = pixel;
+ tmp.src.u.gen3.type = op == PictOpClear ? SHADER_ZERO : SHADER_CONSTANT;
+ tmp.src.u.gen3.mode = pixel;
if (!kgem_check_bo(&sna->kgem, dst_bo))
kgem_submit(&sna->kgem);
@@ -3660,8 +3660,8 @@ gen3_render_fill(struct sna *sna, uint8_t alu,
tmp->base.dst.bo = dst_bo;
tmp->base.floats_per_vertex = 2;
- tmp->base.src.gen3.type = SHADER_CONSTANT;
- tmp->base.src.gen3.mode =
+ tmp->base.src.u.gen3.type = SHADER_CONSTANT;
+ tmp->base.src.u.gen3.mode =
sna_rgba_for_color(color, dst->drawable.depth);
if (!kgem_check_bo(&sna->kgem, dst_bo))
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 012b0902..8330395f 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -53,11 +53,16 @@ struct sna_composite_op {
int16_t offset[2];
float scale[2];
- struct gen3_shader_channel {
- int type;
- uint32_t mode;
- uint32_t constants;
- } gen3;
+ union {
+ struct {
+ uint32_t pixel;
+ } gen2;
+ struct gen3_shader_channel {
+ int type;
+ uint32_t mode;
+ uint32_t constants;
+ } gen3;
+ } u;
} src, mask;
uint32_t is_affine : 1;
uint32_t has_component_alpha : 1;