xf86-video-intel: 9 commits - src/intel_module.c src/sna/gen2_render.c src/sna/gen2_render.h src/sna/gen3_render.c src/sna/kgem.c src/sna/kgem_debug.c src/sna/kgem_debug_gen3.c src/sna/kgem_debug.h src/sna/kgem.h src/sna/Makefile.am src/sna/sna_render.c src/sna/sna_render.h src/sna/sna_trapezoids.c src/sna/sna_video.c src/sna/sna_video_overlay.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jul 1 14:19:18 PDT 2011
src/intel_module.c | 21
src/sna/Makefile.am | 1
src/sna/gen2_render.c | 1418 +++++++++++++++++++++++++++++++++++++-------
src/sna/gen2_render.h | 22
src/sna/gen3_render.c | 193 +++--
src/sna/kgem.c | 71 ++
src/sna/kgem.h | 6
src/sna/kgem_debug.c | 4
src/sna/kgem_debug.h | 3
src/sna/kgem_debug_gen3.c | 5
src/sna/sna_render.c | 227 ++++++-
src/sna/sna_render.h | 19
src/sna/sna_trapezoids.c | 2
src/sna/sna_video.c | 2
src/sna/sna_video_overlay.c | 4
15 files changed, 1645 insertions(+), 353 deletions(-)
New commits:
commit 5c8a108d2c99f542372efb1734c96ddd2af6bc76
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 21:24:43 2011 +0100
sna/gen2: Recompute blend pipeline for component-alpha pass
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index f1275e3..3f0b902 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -325,6 +325,7 @@ gen2_emit_texture(struct sna *sna,
static void
gen2_get_blend_factors(const struct sna_composite_op *op,
+ int blend,
uint32_t *c_out,
uint32_t *a_out)
{
@@ -348,7 +349,7 @@ gen2_get_blend_factors(const struct sna_composite_op *op,
/* Get the source picture's channels into TBx_ARG1 */
- if ((op->has_component_alpha && gen2_blend_op[op->op].src_alpha) ||
+ if ((op->has_component_alpha && gen2_blend_op[blend].src_alpha) ||
op->dst.format == PICT_a8) {
/* Producing source alpha value, so the first set of channels
* is src.A instead of src.X. We also do this if the destination
@@ -626,7 +627,7 @@ static void gen2_emit_composite_state(struct sna *sna,
gen2_disable_logic_op(sna);
- gen2_get_blend_factors(op, &cblend, &ablend);
+ gen2_get_blend_factors(op, op->op, &cblend, &ablend);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
LOAD_TEXTURE_BLEND_STAGE(0) | 1);
OUT_BATCH(cblend);
@@ -839,7 +840,7 @@ static void gen2_magic_ca_pass(struct sna *sna,
gen2_get_blend_cntl(PictOpAdd, TRUE, op->dst.format) |
S8_ENABLE_COLOR_BUFFER_WRITE);
- gen2_get_blend_factors(op, &cblend, &ablend);
+ gen2_get_blend_factors(op, PictOpAdd, &cblend, &ablend);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
LOAD_TEXTURE_BLEND_STAGE(0) | 1);
OUT_BATCH(cblend);
commit 121511d3bd63da5eca28edf971aae3d062aed46e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 16:54:28 2011 +0100
sna/gen2: Pack solid sources into the default diffuse component
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 495e3fa..f1275e3 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -355,28 +355,43 @@ gen2_get_blend_factors(const struct sna_composite_op *op,
* is a8, in which case src.G is what's written, and the other
* channels are ignored.
*/
- ablend |= TB0A_ARG1_SEL_TEXEL0;
- cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA;
+ if (op->src.is_solid) {
+ ablend |= TB0A_ARG1_SEL_DIFFUSE;
+ cblend |= TB0C_ARG1_SEL_DIFFUSE | TB0C_ARG1_REPLICATE_ALPHA;
+ } else {
+ ablend |= TB0A_ARG1_SEL_TEXEL0;
+ cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA;
+ }
} else {
- if (PICT_FORMAT_RGB(op->src.pict_format) != 0)
+ if (op->src.is_solid)
+ cblend |= TB0C_ARG1_SEL_DIFFUSE;
+ else if (PICT_FORMAT_RGB(op->src.pict_format) != 0)
cblend |= TB0C_ARG1_SEL_TEXEL0;
else
cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */
- if (op->src.is_opaque)
+ if (op->src.is_solid)
+ ablend |= TB0A_ARG1_SEL_DIFFUSE;
+ else if (op->src.is_opaque)
ablend |= TB0A_ARG1_SEL_ONE;
else
ablend |= TB0A_ARG1_SEL_TEXEL0;
}
if (op->mask.bo) {
- cblend |= TB0C_OP_MODULATE;
- cblend |= TB0C_ARG2_SEL_TEXEL1;
+ if (op->src.is_solid) {
+ cblend |= TB0C_ARG2_SEL_TEXEL0;
+ ablend |= TB0A_ARG2_SEL_TEXEL0;
+ } else {
+ cblend |= TB0C_ARG2_SEL_TEXEL1;
+ ablend |= TB0A_ARG2_SEL_TEXEL1;
+ }
+
if (op->dst.format == PICT_a8 ||
!op->has_component_alpha ||
PICT_FORMAT_RGB(op->mask.pict_format) == 0)
cblend |= TB0C_ARG2_REPLICATE_ALPHA;
- ablend |= TB0A_ARG2_SEL_TEXEL1;
+ cblend |= TB0C_OP_MODULATE;
ablend |= TB0A_OP_MODULATE;
} else {
cblend |= TB0C_OP_ARG1;
@@ -594,13 +609,14 @@ static void gen2_emit_composite_state(struct sna *sna,
{
uint32_t texcoordfmt;
uint32_t cblend, ablend;
+ int tex;
gen2_get_batch(sna, op);
gen2_emit_target(sna, op);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2);
- OUT_BATCH((1 + (op->mask.bo != NULL)) << 12);
+ OUT_BATCH((!op->src.is_solid + (op->mask.bo != NULL)) << 12);
OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |
gen2_get_blend_cntl(op->op,
@@ -616,22 +632,25 @@ static void gen2_emit_composite_state(struct sna *sna,
OUT_BATCH(cblend);
OUT_BATCH(ablend);
- texcoordfmt = 0;
- if (op->src.is_affine)
- texcoordfmt |= TEXCOORDFMT_2D << 0;
- else
- texcoordfmt |= TEXCOORDFMT_3D << 0;
+ tex = texcoordfmt = 0;
+ if (!op->src.is_solid) {
+ if (op->src.is_affine)
+ texcoordfmt |= TEXCOORDFMT_2D << (2*tex);
+ else
+ texcoordfmt |= TEXCOORDFMT_3D << (2*tex);
+ gen2_emit_texture(sna, &op->src, tex++);
+ } else {
+ OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_BATCH(op->src.u.gen2.pixel);
+ }
if (op->mask.bo) {
if (op->mask.is_affine)
- texcoordfmt |= TEXCOORDFMT_2D << 2;
+ texcoordfmt |= TEXCOORDFMT_2D << (2*tex);
else
- texcoordfmt |= TEXCOORDFMT_3D << 2;
+ texcoordfmt |= TEXCOORDFMT_3D << (2*tex);
+ gen2_emit_texture(sna, &op->mask, tex++);
}
OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt);
-
- gen2_emit_texture(sna, &op->src, 0);
- if (op->mask.bo)
- gen2_emit_texture(sna, &op->mask, 1);
}
static inline void
@@ -675,34 +694,136 @@ gen2_emit_composite_vertex(struct sna *sna,
int16_t dstX, int16_t dstY)
{
gen2_emit_composite_dstcoord(sna, dstX, dstY);
- gen2_emit_composite_texcoord(sna, &op->src, srcX, srcY);
+ if (!op->src.is_solid)
+ gen2_emit_composite_texcoord(sna, &op->src, srcX, srcY);
if (op->mask.bo)
gen2_emit_composite_texcoord(sna, &op->mask, mskX, mskY);
}
-static void
+fastcall static void
gen2_emit_composite_primitive(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,
- int16_t w, int16_t h)
+ const struct sna_composite_rectangles *r)
{
- dstX += op->dst.x;
- dstY += op->dst.y;
-
gen2_emit_composite_vertex(sna, op,
- srcX + w, srcY + h,
- mskX + w, mskY + h,
- dstX + w, dstY + h);
+ r->src.x + r->width,
+ r->src.y + r->height,
+ r->mask.x + r->width,
+ r->mask.y + r->height,
+ op->dst.x + r->dst.x + r->width,
+ op->dst.y + r->dst.y + r->height);
gen2_emit_composite_vertex(sna, op,
- srcX, srcY + h,
- mskX, mskY + h,
- dstX, dstY + h);
+ r->src.x,
+ r->src.y + r->height,
+ r->mask.x,
+ r->mask.y + r->height,
+ op->dst.x + r->dst.x,
+ op->dst.y + r->dst.y + r->height);
gen2_emit_composite_vertex(sna, op,
- srcX, srcY,
- mskX, mskY,
- dstX, dstY);
+ r->src.x,
+ r->src.y,
+ r->mask.x,
+ r->mask.y,
+ op->dst.x + r->dst.x,
+ op->dst.y + r->dst.y);
+}
+
+fastcall static void
+gen2_emit_composite_primitive_constant(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ int16_t dst_x = r->dst.x + op->dst.x;
+ int16_t dst_y = r->dst.y + op->dst.y;
+
+ gen2_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height);
+ gen2_emit_composite_dstcoord(sna, dst_x, dst_y + r->height);
+ gen2_emit_composite_dstcoord(sna, dst_x, dst_y);
+}
+
+fastcall static void
+gen2_emit_composite_primitive_identity(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ float w = r->width;
+ float h = r->height;
+ float *v;
+
+ v = (float *)sna->kgem.batch + sna->kgem.nbatch;
+ sna->kgem.nbatch += 12;
+
+ v[8] = v[4] = r->dst.x + op->dst.x;
+ v[0] = v[4] + w;
+
+ v[9] = r->dst.y + op->dst.y;
+ v[5] = v[1] = v[9] + h;
+
+ v[10] = v[6] = (r->src.x + op->src.offset[0]) * op->src.scale[0];
+ v[2] = v[6] + w * op->src.scale[0];
+
+ v[11] = (r->src.y + op->src.offset[1]) * op->src.scale[1];
+ v[7] = v[3] = v[11] + h * op->src.scale[1];
+}
+
+fastcall static void
+gen2_emit_composite_primitive_affine(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ PictTransform *transform = op->src.transform;
+ int16_t dst_x = r->dst.x + op->dst.x;
+ 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;
+
+ _sna_get_transformed_coordinates(src_x + r->width, src_y + r->height,
+ transform,
+ &sx, &sy);
+
+ gen2_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]);
+
+ _sna_get_transformed_coordinates(src_x, src_y + r->height,
+ transform,
+ &sx, &sy);
+ gen2_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_coordinates(src_x, src_y,
+ transform,
+ &sx, &sy);
+ gen2_emit_composite_dstcoord(sna, dst_x, dst_y);
+ OUT_VERTEX(sx * op->src.scale[0]);
+ OUT_VERTEX(sy * op->src.scale[1]);
+}
+
+fastcall static void
+gen2_emit_composite_primitive_constant_identity_mask(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ float w = r->width;
+ float h = r->height;
+ float *v;
+
+ v = (float *)sna->kgem.batch + sna->kgem.nbatch;
+ sna->kgem.nbatch += 12;
+
+ v[8] = v[4] = r->dst.x + op->dst.x;
+ v[0] = v[4] + w;
+
+ v[9] = r->dst.y + op->dst.y;
+ v[5] = v[1] = v[9] + h;
+
+ v[10] = v[6] = (r->mask.x + op->mask.offset[0]) * op->mask.scale[0];
+ v[2] = v[6] + w * op->mask.scale[0];
+
+ v[11] = (r->mask.y + op->mask.offset[1]) * op->mask.scale[1];
+ v[7] = v[3] = v[11] + h * op->mask.scale[1];
}
static void gen2_magic_ca_pass(struct sna *sna,
@@ -790,11 +911,7 @@ gen2_render_composite_blt(struct sna *sna,
gen2_get_rectangles(sna, op, 1);
}
- gen2_emit_composite_primitive(sna, op,
- r->src.x, r->src.y,
- r->mask.x, r->mask.y,
- r->dst.x, r->dst.y,
- r->width, r->height);
+ op->prim_emit(sna, op, r);
}
static void
@@ -813,12 +930,19 @@ gen2_render_composite_boxes(struct sna *sna,
nbox -= nbox_this_time;
do {
- gen2_emit_composite_primitive(sna, op,
- box->x1, box->y1,
- box->x1, box->y1,
- box->x1, box->y1,
- box->x2 - box->x1,
- box->y2 - box->y1);
+ struct sna_composite_rectangles r;
+
+ DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__,
+ box->x1, box->y1,
+ box->x2 - box->x1,
+ box->y2 - box->y1));
+
+ r.dst.x = box->x1; r.dst.y = box->y1;
+ r.width = box->x2 - box->x1;
+ r.height = box->y2 - box->y1;
+ r.src = r.mask = r.dst;
+
+ op->prim_emit(sna, op, &r);
box++;
} while (--nbox_this_time);
} while (nbox);
@@ -1099,8 +1223,6 @@ gen2_render_composite(struct sna *sna,
width, height,
tmp);
- memset(&tmp->u.gen2, 0, sizeof(tmp->u.gen2));
-
if (!gen2_composite_set_target(sna, tmp, dst)) {
DBG(("%s: unable to set render target\n",
__FUNCTION__));
@@ -1159,11 +1281,26 @@ gen2_render_composite(struct sna *sna,
}
tmp->floats_per_vertex = 2;
- if (tmp->src.bo)
+ if (!tmp->src.is_solid)
tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 3;
if (tmp->mask.bo)
tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 3;
+ tmp->prim_emit = gen2_emit_composite_primitive;
+ if (tmp->mask.bo) {
+ if (tmp->mask.transform == NULL) {
+ if (tmp->src.is_solid)
+ tmp->prim_emit = gen2_emit_composite_primitive_constant_identity_mask;
+ }
+ } else {
+ if (tmp->src.is_solid)
+ tmp->prim_emit = gen2_emit_composite_primitive_constant;
+ else if (tmp->src.transform == NULL)
+ tmp->prim_emit = gen2_emit_composite_primitive_identity;
+ else if (tmp->src.is_affine)
+ tmp->prim_emit = gen2_emit_composite_primitive_affine;
+ }
+
tmp->blt = gen2_render_composite_blt;
tmp->boxes = gen2_render_composite_boxes;
tmp->done = gen2_render_composite_done;
commit a303f85c163979276ff13e00b7c56f55b5fd1d07
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 16:27:11 2011 +0100
sna/gen2: Remove unused state from invariant setup
... and also some state that gets clobbered when we install the
composite pipelines.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index f4177f7..495e3fa 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -115,6 +115,7 @@ gen2_buf_tiling(uint32_t tiling)
{
uint32_t v = 0;
switch (tiling) {
+ default: assert(0);
case I915_TILING_Y: v |= BUF_3D_TILE_WALK_Y;
case I915_TILING_X: v |= BUF_3D_TILED_SURFACE;
case I915_TILING_NONE: break;
@@ -427,34 +428,22 @@ static void gen2_emit_invariant(struct sna *sna)
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(2));
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(3));
- OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
- MAP_UNIT(0) |
+ OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(0) |
DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(0) |
- ENABLE_TEX_STREAM_MAP_IDX |
- TEX_STREAM_MAP_IDX(0));
- OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
- MAP_UNIT(1) |
+ ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(0) |
+ ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0));
+ OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(1) |
DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(1) |
- ENABLE_TEX_STREAM_MAP_IDX |
- TEX_STREAM_MAP_IDX(1));
- OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
- MAP_UNIT(2) |
+ ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(1) |
+ ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1));
+ OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(2) |
DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(2) |
- ENABLE_TEX_STREAM_MAP_IDX |
- TEX_STREAM_MAP_IDX(2));
- OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
- MAP_UNIT(3) |
+ ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(2) |
+ ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2));
+ OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(3) |
DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(3) |
- ENABLE_TEX_STREAM_MAP_IDX |
- TEX_STREAM_MAP_IDX(3));
+ ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(3) |
+ ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3));
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0));
@@ -465,15 +454,11 @@ static void gen2_emit_invariant(struct sna *sna)
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
- OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- ENABLE_TRI_STRIP_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) |
- TRI_STRIP_PROVOKE_VRTX(2));
+ OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD);
+ OUT_BATCH(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
+ TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
+ TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
+ TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
@@ -484,12 +469,6 @@ static void gen2_emit_invariant(struct sna *sna)
OUT_BATCH(MAGIC_W_STATE_DWORD1);
OUT_BATCH_F(1.0);
- OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD);
- OUT_BATCH(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
- TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
- TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
- TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
-
OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD |
DISABLE_INDPT_ALPHA_BLEND |
ENABLE_ALPHA_BLENDFUNC | ABLENDFUNC_ADD);
@@ -498,70 +477,9 @@ static void gen2_emit_invariant(struct sna *sna)
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_MODES_1_CMD |
- ENABLE_COLR_BLND_FUNC |
- BLENDFUNC_ADD |
+ ENABLE_COLR_BLND_FUNC | BLENDFUNC_ADD |
ENABLE_SRC_BLND_FACTOR | SRC_BLND_FACT(BLENDFACTOR_ONE) |
ENABLE_DST_BLND_FACTOR | DST_BLND_FACT(BLENDFACTOR_ZERO));
- OUT_BATCH(_3DSTATE_MODES_2_CMD);
- OUT_BATCH(_3DSTATE_MODES_3_CMD |
- ENABLE_ALPHA_SHADE_MODE | ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_FOG_SHADE_MODE | FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_SPEC_SHADE_MODE | SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_COLOR_SHADE_MODE | COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_CULL_MODE | CULLMODE_NONE);
-
- OUT_BATCH(_3DSTATE_ENABLES_1_CMD |
- DISABLE_LOGIC_OP |
- DISABLE_STENCIL_TEST |
- DISABLE_DEPTH_BIAS |
- DISABLE_SPEC_ADD |
- DISABLE_FOG |
- DISABLE_ALPHA_TEST |
- ENABLE_COLOR_BLEND |
- DISABLE_DEPTH_TEST);
- OUT_BATCH(_3DSTATE_ENABLES_2_CMD |
- DISABLE_STENCIL_WRITE |
- ENABLE_TEX_CACHE |
- DISABLE_DITHER |
- ENABLE_COLOR_MASK |
- ENABLE_COLOR_WRITE |
- DISABLE_DEPTH_WRITE);
-
- OUT_BATCH(_3DSTATE_STIPPLE);
-
- /* Set default blend state */
- OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
- TEXPIPE_COLOR |
- ENABLE_TEXOUTPUT_WRT_SEL |
- TEXOP_OUTPUT_CURRENT |
- DISABLE_TEX_CNTRL_STAGE |
- TEXOP_SCALE_1X |
- TEXOP_MODIFY_PARMS |
- TEXOP_LAST_STAGE |
- TEXBLENDOP_ARG1);
- OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
- TEXPIPE_ALPHA |
- ENABLE_TEXOUTPUT_WRT_SEL |
- TEXOP_OUTPUT_CURRENT |
- TEXOP_SCALE_1X |
- TEXOP_MODIFY_PARMS |
- TEXBLENDOP_ARG1);
- OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
- TEXPIPE_COLOR |
- TEXBLEND_ARG1 |
- TEXBLENDARG_MODIFY_PARMS |
- TEXBLENDARG_DIFFUSE);
- OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
- TEXPIPE_ALPHA |
- TEXBLEND_ARG1 |
- TEXBLENDARG_MODIFY_PARMS |
- TEXBLENDARG_DIFFUSE);
-
- OUT_BATCH(_3DSTATE_AA_CMD |
- AA_LINE_ECAAR_WIDTH_ENABLE |
- AA_LINE_ECAAR_WIDTH_1_0 |
- AA_LINE_REGION_WIDTH_ENABLE |
- AA_LINE_REGION_WIDTH_1_0 | AA_LINE_DISABLE);
sna->render_state.gen2.need_invariant = FALSE;
}
commit 120c98ac10435c8e848a8337c1f544f81a05cd3a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 14:55:44 2011 +0100
sna: Downsample sources 2x too large to fit in the 3D pipeline
This is quite trivial to hit given the 2k limits on gen2/gen3. We
compromise on image quality by pre-downscaling the source by a fixed
factor to make it fit into the pipeline in preference to performing the
entire operation on the CPU.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index dfd8a57..d76480d 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -90,6 +90,7 @@ if DEBUG
libsna_la_SOURCES += \
kgem_debug.c \
kgem_debug.h \
+ kgem_debug_gen2.c \
kgem_debug_gen3.c \
kgem_debug_gen4.c \
kgem_debug_gen5.c \
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 88b1d83..6fe6e93 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1819,6 +1819,64 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
return bo;
}
+struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
+ pixman_format_code_t format,
+ const void *data,
+ int x, int y,
+ int width, int height,
+ int stride, int bpp)
+{
+ int dst_stride = ALIGN(width * bpp / 2, 32) >> 3;
+ int size = dst_stride * height / 2;
+ struct kgem_bo *bo;
+ pixman_image_t *src_image, *dst_image;
+ pixman_transform_t t;
+ void *dst;
+
+ DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
+ __FUNCTION__, x, y, width, height, stride, bpp));
+
+ bo = kgem_create_buffer(kgem, size, KGEM_BUFFER_WRITE, &dst);
+ if (bo == NULL)
+ return NULL;
+
+ dst_image = pixman_image_create_bits(format, width/2, height/2,
+ dst, dst_stride);
+ if (dst_image == NULL)
+ goto cleanup_bo;
+
+ src_image = pixman_image_create_bits(format, width, height,
+ (uint32_t*)data, stride);
+ if (src_image == NULL)
+ goto cleanup_dst;
+
+ memset(&t, 0, sizeof(t));
+ t.matrix[0][0] = 2 << 16;
+ t.matrix[1][1] = 2 << 16;
+ t.matrix[2][2] = 1 << 16;
+ pixman_image_set_transform(src_image, &t);
+ pixman_image_set_filter(src_image, PIXMAN_FILTER_BILINEAR, NULL, 0);
+
+ pixman_image_composite(PIXMAN_OP_SRC,
+ src_image, NULL, dst_image,
+ x, y,
+ 0, 0,
+ 0, 0,
+ width/2, height/2);
+
+ pixman_image_unref(src_image);
+ pixman_image_unref(dst_image);
+
+ bo->pitch = dst_stride;
+ return bo;
+
+cleanup_dst:
+ pixman_image_unref(dst_image);
+cleanup_bo:
+ kgem_bo_destroy(kgem, bo);
+ return NULL;
+}
+
void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *_bo)
{
struct kgem_partial_bo *bo;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index fac30af..013809c 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -141,6 +141,12 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
int x, int y,
int width, int height,
int stride, int bpp);
+struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
+ pixman_format_code_t format,
+ const void *data,
+ int x, int y,
+ int width, int height,
+ int stride, int bpp);
int kgem_choose_tiling(struct kgem *kgem,
int tiling, int width, int height, int bpp);
diff --git a/src/sna/kgem_debug.c b/src/sna/kgem_debug.c
index 0dcd706..20fe8a2 100644
--- a/src/sna/kgem_debug.c
+++ b/src/sna/kgem_debug.c
@@ -352,6 +352,8 @@ static int (*decode_3d(int gen))(struct kgem*, uint32_t)
return kgem_gen4_decode_3d;
} else if (gen >= 30) {
return kgem_gen3_decode_3d;
+ } else if (gen >= 20) {
+ return kgem_gen2_decode_3d;
}
assert(0);
}
@@ -366,6 +368,8 @@ static void (*finish_state(int gen))(struct kgem*)
return kgem_gen4_finish_state;
} else if (gen >= 30) {
return kgem_gen3_finish_state;
+ } else if (gen >= 20) {
+ return kgem_gen2_finish_state;
}
assert(0);
}
diff --git a/src/sna/kgem_debug.h b/src/sna/kgem_debug.h
index f9a931d..9211dcb 100644
--- a/src/sna/kgem_debug.h
+++ b/src/sna/kgem_debug.h
@@ -25,4 +25,7 @@ void kgem_gen4_finish_state(struct kgem *kgem);
int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset);
void kgem_gen3_finish_state(struct kgem *kgem);
+int kgem_gen2_decode_3d(struct kgem *kgem, uint32_t offset);
+void kgem_gen2_finish_state(struct kgem *kgem);
+
#endif
diff --git a/src/sna/kgem_debug_gen3.c b/src/sna/kgem_debug_gen3.c
index da1d9fc..6709a8e 100644
--- a/src/sna/kgem_debug_gen3.c
+++ b/src/sna/kgem_debug_gen3.c
@@ -1552,9 +1552,6 @@ out:
int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset)
{
- uint32_t opcode;
- unsigned int idx;
-
struct {
uint32_t opcode;
int min_len;
@@ -1572,6 +1569,8 @@ int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset)
{ 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
};
uint32_t *data = kgem->batch + offset;
+ uint32_t opcode;
+ unsigned int idx;
opcode = (data[0] & 0x1f000000) >> 24;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 72a3c1e..baf51c3 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -427,6 +427,212 @@ sna_render_pixmap_bo(struct sna *sna,
return bo != NULL;
}
+static int sna_render_picture_downsample(struct sna *sna,
+ PicturePtr picture,
+ struct sna_composite_channel *channel,
+ int16_t x, int16_t y,
+ int16_t w, int16_t h,
+ int16_t dst_x, int16_t dst_y)
+{
+ struct kgem_bo *bo = NULL;
+ PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable);
+ int16_t ox, oy, ow, oh;
+ BoxRec box;
+
+ assert(w && h);
+
+ DBG(("%s (%d, %d)x(%d, %d) [dst=(%d, %d)]\n",
+ __FUNCTION__, x, y, w, h, dst_x, dst_y));
+
+ ow = w;
+ oh = h;
+
+ ox = box.x1 = x;
+ oy = box.y1 = y;
+ box.x2 = x + w;
+ box.y2 = y + h;
+ if (channel->transform) {
+ pixman_vector_t v;
+
+ pixman_transform_bounds(channel->transform, &box);
+
+ v.vector[0] = ox << 16;
+ v.vector[1] = oy << 16;
+ v.vector[2] = 1 << 16;
+ pixman_transform_point(channel->transform, &v);
+ ox = v.vector[0] / v.vector[2];
+ oy = v.vector[1] / v.vector[2];
+ }
+
+ if (channel->repeat != RepeatNone) {
+ if (box.x1 < 0 ||
+ box.y1 < 0 ||
+ box.x2 > pixmap->drawable.width ||
+ box.y2 > pixmap->drawable.height) {
+ /* XXX tiled repeats? */
+ box.x1 = box.y1 = 0;
+ box.x2 = pixmap->drawable.width;
+ box.y2 = pixmap->drawable.height;
+
+ if (!channel->is_affine) {
+ DBG(("%s: fallback -- repeating project transform too large for texture\n",
+ __FUNCTION__));
+ return sna_render_picture_fixup(sna,
+ picture,
+ channel,
+ x, y, ow, oh,
+ dst_x, dst_y);
+ }
+ }
+ } else {
+ if (box.x1 < 0)
+ box.x1 = 0;
+ if (box.y1 < 0)
+ box.y1 = 0;
+ if (box.x2 > pixmap->drawable.width)
+ box.x2 = pixmap->drawable.width;
+ if (box.y2 > pixmap->drawable.height)
+ box.y2 = pixmap->drawable.height;
+ }
+
+ w = box.x2 - box.x1;
+ h = box.y2 - box.y1;
+ assert(w && h);
+ if (w > 2*sna->render.max_3d_size || h > 2*sna->render.max_3d_size)
+ goto fixup;
+
+ if (texture_is_cpu(pixmap, &box) && !move_to_gpu(pixmap, &box)) {
+ bo = kgem_upload_source_image_halved(&sna->kgem,
+ picture->format,
+ pixmap->devPrivate.ptr,
+ box.x1, box.y1, w, h,
+ pixmap->devKind,
+ pixmap->drawable.bitsPerPixel);
+ if (!bo) {
+ DBG(("%s: failed to upload source image, using clear\n",
+ __FUNCTION__));
+ return 0;
+ }
+ } else {
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ PicturePtr tmp_src, tmp_dst;
+ PictFormatPtr format;
+ struct sna_pixmap *priv;
+ pixman_transform_t t;
+ PixmapPtr tmp;
+ int error, i, j, ww, hh;
+
+ if (!sna_pixmap_force_to_gpu(pixmap))
+ goto fixup;
+
+ tmp = screen->CreatePixmap(screen,
+ w/2, h/2, pixmap->drawable.depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!tmp)
+ goto fixup;
+
+ priv = sna_pixmap(tmp);
+ if (!priv) {
+ screen->DestroyPixmap(tmp);
+ goto fixup;
+ }
+
+ format = PictureMatchFormat(screen,
+ pixmap->drawable.depth,
+ picture->format);
+
+ tmp_dst = CreatePicture(0, &tmp->drawable, format, 0, NULL,
+ serverClient, &error);
+
+ tmp_src = CreatePicture(0, &pixmap->drawable, format, 0, NULL,
+ serverClient, &error);
+ tmp_src->filter = PictFilterBilinear;
+ memset(&t, 0, sizeof(t));
+ t.matrix[0][0] = 2 << 16;
+ t.matrix[1][1] = 2 << 16;
+ t.matrix[2][2] = 1 << 16;
+ tmp_src->transform = &t;
+
+ ValidatePicture(tmp_dst);
+ ValidatePicture(tmp_src);
+
+ ww = w/4; hh = h/4;
+
+ DBG(("%s downsampling using %dx%d GPU tiles\n",
+ __FUNCTION__, ww, hh));
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ struct sna_composite_op op;
+ BoxRec b;
+
+ memset(&op, 0, sizeof(op));
+ if (!sna->render.composite(sna,
+ PictOpSrc,
+ tmp_src, NULL, tmp_dst,
+ box.x1 + ww*j, box.y1 + hh*i,
+ 0, 0,
+ ww*j, hh*i,
+ ww, hh,
+ &op)) {
+ tmp_src->transform = NULL;
+ FreePicture(tmp_src, 0);
+ FreePicture(tmp_dst, 0);
+ screen->DestroyPixmap(tmp);
+ goto fixup;
+ }
+
+ b.x1 = ww*j;
+ b.y1 = hh*i;
+ b.x2 = b.x1 + ww;
+ b.y2 = b.y1 + hh;
+
+ op.boxes(sna, &op, &b, 1);
+ op.done(sna, &op);
+ }
+ }
+
+ bo = kgem_bo_reference(priv->gpu_bo);
+
+ tmp_src->transform = NULL;
+ FreePicture(tmp_src, 0);
+ FreePicture(tmp_dst, 0);
+ screen->DestroyPixmap(tmp);
+ }
+
+ if (ox == x && oy == y) {
+ x = y = 0;
+ } else if (channel->transform) {
+ pixman_vector_t v;
+ pixman_transform_t m;
+
+ v.vector[0] = (ox - box.x1) << 16;
+ v.vector[1] = (oy - box.y1) << 16;
+ v.vector[2] = 1 << 16;
+ pixman_transform_invert(&m, channel->transform);
+ pixman_transform_point(&m, &v);
+ x = v.vector[0] / v.vector[2];
+ y = v.vector[1] / v.vector[2];
+ } else {
+ x = ox - box.x1;
+ y = oy - box.y1;
+ }
+
+ channel->offset[0] = x - dst_x;
+ channel->offset[1] = y - dst_y;
+ channel->scale[0] = 1./w;
+ channel->scale[1] = 1./h;
+ channel->width = w / 2;
+ channel->height = h / 2;
+ channel->bo = bo;
+ return 1;
+
+fixup:
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h,
+ dst_x, dst_y);
+}
+
int
sna_render_picture_extract(struct sna *sna,
PicturePtr picture,
@@ -517,8 +723,9 @@ sna_render_picture_extract(struct sna *sna,
if (w > sna->render.max_3d_size || h > sna->render.max_3d_size) {
DBG(("%s: fallback -- sample too large for texture (%d, %d)x(%d, %d)\n",
__FUNCTION__, box.x1, box.y1, w, h));
- return sna_render_picture_fixup(sna, picture, channel,
- x, y, ow, oh, dst_x, dst_y);
+ return sna_render_picture_downsample(sna, picture, channel,
+ x, y, ow, oh,
+ dst_x, dst_y);
}
if (texture_is_cpu(pixmap, &box) && !move_to_gpu(pixmap, &box)) {
commit f6c8c3bb6fd75bca6c7704b7d5869a5d44ce3832
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 11:17:32 2011 +0100
sna/gen2: Use specular component for solid spans
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 770ec7e..f4177f7 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 c10d540..2f41e9a 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 aba1b8d..ee8de2d 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 012b090..8330395 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;
commit de14e3c8595f9e315dc3ce23ad15b04e118499f4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 09:58:27 2011 +0100
sna/gen2: Add missing render fallbacks for blt ops
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 82c7e15..770ec7e 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -45,6 +45,18 @@
#define NDEBUG 1
#endif
+#define NO_COMPOSITE 0
+#define NO_COMPOSITE_SPANS 0
+#define NO_COPY 0
+#define NO_COPY_BOXES 0
+#define NO_FILL 0
+#define NO_FILL_BOXES 0
+
+#define PREFER_COPY 0
+#define PREFER_COPY_BOXES 0
+#define PREFER_FILL 0
+#define PREFER_FILL_BOXES 0
+
#define OUT_BATCH(v) batch_emit(sna, v)
#define OUT_BATCH_F(v) batch_emit_float(sna, v)
#define OUT_VERTEX(v) batch_emit_float(sna, v)
@@ -617,6 +629,48 @@ static void gen2_emit_target(struct sna *sna, const struct sna_composite_op *op)
sna->render_state.gen2.target = op->dst.bo->unique_id;
}
+static void gen2_disable_logic_op(struct sna *sna)
+{
+ if (!sna->render_state.gen2.logic_op_enabled)
+ return;
+
+ OUT_BATCH(_3DSTATE_ENABLES_1_CMD |
+ DISABLE_LOGIC_OP | ENABLE_COLOR_BLEND);
+
+ sna->render_state.gen2.logic_op_enabled = 0;
+}
+
+static void gen2_enable_logic_op(struct sna *sna, int op)
+{
+ uint8_t logic_op[] = {
+ LOGICOP_CLEAR, /* GXclear */
+ LOGICOP_AND, /* GXand */
+ LOGICOP_AND_RVRSE, /* GXandReverse */
+ LOGICOP_COPY, /* GXcopy */
+ LOGICOP_AND_INV, /* GXandInverted */
+ LOGICOP_NOOP, /* GXnoop */
+ LOGICOP_XOR, /* GXxor */
+ LOGICOP_OR, /* GXor */
+ LOGICOP_NOR, /* GXnor */
+ LOGICOP_EQUIV, /* GXequiv */
+ LOGICOP_INV, /* GXinvert */
+ LOGICOP_OR_RVRSE, /* GXorReverse */
+ LOGICOP_COPY_INV, /* GXcopyInverted */
+ LOGICOP_OR_INV, /* GXorInverted */
+ LOGICOP_NAND, /* GXnand */
+ LOGICOP_SET /* GXset */
+ };
+
+ if (!sna->render_state.gen2.logic_op_enabled) {
+ OUT_BATCH(_3DSTATE_ENABLES_1_CMD |
+ ENABLE_LOGIC_OP | DISABLE_COLOR_BLEND);
+ sna->render_state.gen2.logic_op_enabled = 1;
+ }
+
+ OUT_BATCH(_3DSTATE_MODES_4_CMD |
+ ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(logic_op[op]));
+}
+
static void gen2_emit_composite_state(struct sna *sna,
const struct sna_composite_op *op)
{
@@ -636,6 +690,8 @@ static void gen2_emit_composite_state(struct sna *sna,
op->dst.format) |
S8_ENABLE_COLOR_BUFFER_WRITE);
+ gen2_disable_logic_op(sna);
+
gen2_get_blend_factors(op, &cblend, &ablend);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
LOAD_TEXTURE_BLEND_STAGE(0) | 1);
@@ -1247,41 +1303,8 @@ gen2_emit_composite_spans_primitive(struct sna *sna,
gen2_emit_composite_spans_vertex(sna, op, box->x1, box->y1, opacity);
}
-#if 0
-static void gen2_emit_fill_blend_op(struct sna *sna)
-{
- /* Set default blend state */
- OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
- TEXPIPE_COLOR |
- ENABLE_TEXOUTPUT_WRT_SEL |
- TEXOP_OUTPUT_CURRENT |
- DISABLE_TEX_CNTRL_STAGE |
- TEXOP_SCALE_1X |
- TEXOP_MODIFY_PARMS |
- TEXOP_LAST_STAGE |
- TEXBLENDOP_ARG1);
- OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
- TEXPIPE_ALPHA |
- ENABLE_TEXOUTPUT_WRT_SEL |
- TEXOP_OUTPUT_CURRENT |
- TEXOP_SCALE_1X |
- TEXOP_MODIFY_PARMS |
- TEXBLENDOP_ARG1);
- OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
- TEXPIPE_COLOR |
- TEXBLEND_ARG1 |
- TEXBLENDARG_MODIFY_PARMS |
- TEXBLENDARG_DIFFUSE);
- OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
- TEXPIPE_ALPHA |
- TEXBLEND_ARG1 |
- TEXBLENDARG_MODIFY_PARMS |
- TEXBLENDARG_DIFFUSE);
-}
-#endif
-
static void
-gen2_emit_spans_blend_op(struct sna *sna,
+gen2_emit_spans_pipeline(struct sna *sna,
const struct sna_composite_spans_op *op)
{
uint32_t cblend, ablend;
@@ -1330,7 +1353,7 @@ static void gen2_emit_composite_spans_state(struct sna *sna,
gen2_get_blend_cntl(op->base.op, FALSE, op->base.dst.format) |
S8_ENABLE_COLOR_BUFFER_WRITE);
- gen2_emit_spans_blend_op(sna, op);
+ gen2_emit_spans_pipeline(sna, op);
OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD |
(op->base.src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_3D));
@@ -1478,20 +1501,20 @@ cleanup_dst:
}
static void
-gen2_emit_fill_blend_op(struct sna *sna, const struct sna_composite_op *op)
+gen2_emit_fill_pipeline(struct sna *sna, const struct sna_composite_op *op)
{
uint32_t blend;
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
LOAD_TEXTURE_BLEND_STAGE(0) | 1);
+
blend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_ARG1 |
TB0C_ARG1_SEL_DIFFUSE |
TB0C_OUTPUT_WRITE_CURRENT;
-
if (op->dst.format == PICT_a8)
blend |= TB0C_ARG1_REPLICATE_ALPHA;
-
OUT_BATCH(blend);
+
OUT_BATCH(TB0A_RESULT_SCALE_1X | TB0A_OP_ARG1 |
TB0A_ARG1_SEL_DIFFUSE |
TB0A_OUTPUT_WRITE_CURRENT);
@@ -1512,7 +1535,7 @@ static void gen2_emit_fill_composite_state(struct sna *sna,
gen2_get_blend_cntl(op->op, FALSE, op->dst.format) |
S8_ENABLE_COLOR_BUFFER_WRITE);
- gen2_emit_fill_blend_op(sna, op);
+ gen2_emit_fill_pipeline(sna, op);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(pixel);
@@ -1590,7 +1613,8 @@ gen2_render_fill_boxes(struct sna *sna,
dst, dst_bo,
box, n);
- if (gen2_render_fill_boxes_try_blt(sna, op, format, color,
+ if (!PREFER_FILL_BOXES &&
+ gen2_render_fill_boxes_try_blt(sna, op, format, color,
dst, dst_bo,
box, n))
return TRUE;
@@ -1649,10 +1673,383 @@ gen2_render_fill_boxes(struct sna *sna,
return TRUE;
}
+static void gen2_emit_fill_state(struct sna *sna,
+ const struct sna_composite_op *op)
+{
+ gen2_get_batch(sna, op);
+ gen2_emit_target(sna, op);
+
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+ I1_LOAD_S(2) |
+ I1_LOAD_S(3) |
+ I1_LOAD_S(8) |
+ 2);
+ OUT_BATCH(0);
+ OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
+ OUT_BATCH(S8_ENABLE_COLOR_BUFFER_WRITE);
+
+ gen2_enable_logic_op(sna, op->op);
+ gen2_emit_fill_pipeline(sna, op);
+
+ OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_BATCH(op->u.gen2.pixel);
+}
+
+static void
+gen2_render_fill_blt(struct sna *sna,
+ const struct sna_fill_op *op,
+ int16_t x, int16_t y, int16_t w, int16_t h)
+{
+ if (!gen2_get_rectangles(sna, &op->base, 1)) {
+ gen2_emit_fill_state(sna, &op->base);
+ gen2_get_rectangles(sna, &op->base, 1);
+ }
+
+ OUT_VERTEX(x+w);
+ OUT_VERTEX(y+h);
+ OUT_VERTEX(x);
+ OUT_VERTEX(y+h);
+ OUT_VERTEX(x);
+ OUT_VERTEX(y);
+}
+
+static void
+gen2_render_fill_done(struct sna *sna, const struct sna_fill_op *op)
+{
+ gen2_vertex_flush(sna);
+ _kgem_set_mode(&sna->kgem, KGEM_RENDER);
+}
+
+static Bool
+gen2_render_fill(struct sna *sna, uint8_t alu,
+ PixmapPtr dst, struct kgem_bo *dst_bo,
+ uint32_t color,
+ struct sna_fill_op *tmp)
+{
+#if NO_FILL
+ return sna_blt_fill(sna, alu,
+ dst_bo, dst->drawable.bitsPerPixel,
+ color,
+ tmp);
+#endif
+
+ /* Prefer to use the BLT if already engaged */
+ if (!PREFER_FILL && sna->kgem.mode == KGEM_BLT &&
+ sna_blt_fill(sna, alu,
+ dst_bo, dst->drawable.bitsPerPixel,
+ color,
+ tmp))
+ return TRUE;
+
+ /* Must use the BLT if we can't RENDER... */
+ if (dst->drawable.width > 2048 ||
+ dst->drawable.height > 2048 ||
+ dst_bo->pitch > 8192)
+ return sna_blt_fill(sna, alu,
+ dst_bo, dst->drawable.bitsPerPixel,
+ color,
+ tmp);
+
+ tmp->base.op = alu;
+ tmp->base.dst.pixmap = dst;
+ tmp->base.dst.width = dst->drawable.width;
+ tmp->base.dst.height = dst->drawable.height;
+ tmp->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp->base.dst.bo = dst_bo;
+ tmp->base.floats_per_vertex = 2;
+
+ tmp->base.u.gen2.pixel =
+ sna_rgba_for_color(color, dst->drawable.depth);
+
+ if (!kgem_check_bo(&sna->kgem, dst_bo))
+ kgem_submit(&sna->kgem);
+
+ tmp->blt = gen2_render_fill_blt;
+ tmp->done = gen2_render_fill_done;
+
+ gen2_emit_fill_state(sna, &tmp->base);
+ return TRUE;
+}
+
+static void
+gen2_render_copy_setup_source(struct sna *sna,
+ struct sna_composite_channel *channel,
+ PixmapPtr pixmap,
+ struct kgem_bo *bo)
+{
+ channel->filter = PictFilterNearest;
+ channel->repeat = RepeatNone;
+ channel->width = pixmap->drawable.width;
+ channel->height = pixmap->drawable.height;
+ channel->scale[0] = 1./pixmap->drawable.width;
+ channel->scale[1] = 1./pixmap->drawable.height;
+ channel->offset[0] = 0;
+ channel->offset[1] = 0;
+ channel->pict_format = sna_format_for_depth(pixmap->drawable.depth);
+ channel->bo = bo;
+ channel->is_affine = 1;
+}
+
+static void
+gen2_emit_copy_pipeline(struct sna *sna, const struct sna_composite_op *op)
+{
+ uint32_t blend;
+
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
+ LOAD_TEXTURE_BLEND_STAGE(0) | 1);
+
+ blend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_ARG1 |
+ TB0C_OUTPUT_WRITE_CURRENT;
+ if (op->dst.format == PICT_a8)
+ blend |= TB0C_ARG1_REPLICATE_ALPHA;
+ else if (PICT_FORMAT_RGB(op->src.pict_format) != 0)
+ blend |= TB0C_ARG1_SEL_TEXEL0;
+ else
+ blend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */
+ OUT_BATCH(blend);
+
+ blend = TB0A_RESULT_SCALE_1X | TB0A_OP_ARG1 |
+ TB0A_OUTPUT_WRITE_CURRENT;
+ if (PICT_FORMAT_A(op->src.pict_format) == 0)
+ blend |= TB0A_ARG1_SEL_ONE;
+ else
+ blend |= TB0A_ARG1_SEL_TEXEL0;
+ OUT_BATCH(blend);
+}
+
+static void gen2_emit_copy_state(struct sna *sna, const struct sna_composite_op *op)
+{
+ gen2_get_batch(sna, op);
+ gen2_emit_target(sna, op);
+
+ 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(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
+ OUT_BATCH(S8_ENABLE_COLOR_BUFFER_WRITE);
+
+ gen2_enable_logic_op(sna, op->op);
+ gen2_emit_copy_pipeline(sna, op);
+
+ OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | TEXCOORDFMT_2D);
+ gen2_emit_texture(sna, &op->src, 0);
+}
+
+static Bool
+gen2_render_copy_boxes(struct sna *sna, uint8_t alu,
+ PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
+ PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
+ const BoxRec *box, int n)
+{
+ struct sna_composite_op tmp;
+
+#if NO_COPY_BOXES
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
+ return sna_blt_copy_boxes(sna, alu,
+ src_bo, src_dx, src_dy,
+ dst_bo, dst_dx, dst_dy,
+ dst->drawable.bitsPerPixel,
+ box, n);
+#endif
+
+ DBG(("%s (%d, %d)->(%d, %d) x %d\n",
+ __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
+
+ if (!PREFER_COPY_BOXES &&
+ sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
+ sna_blt_copy_boxes(sna, alu,
+ src_bo, src_dx, src_dy,
+ dst_bo, dst_dx, dst_dy,
+ dst->drawable.bitsPerPixel,
+ box, n))
+ return TRUE;
+
+ if (src_bo == dst_bo || /* XXX handle overlap using 3D ? */
+ src_bo->pitch > 8192 ||
+ src->drawable.width > 2048 ||
+ src->drawable.height > 2048 ||
+ dst_bo->pitch > 8192 ||
+ dst->drawable.width > 2048 ||
+ dst->drawable.height > 2048) {
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
+ return sna_blt_copy_boxes(sna, alu,
+ src_bo, src_dx, src_dy,
+ dst_bo, dst_dx, dst_dy,
+ dst->drawable.bitsPerPixel,
+ box, n);
+ }
+
+ if (!kgem_check_bo(&sna->kgem, dst_bo))
+ kgem_submit(&sna->kgem);
+ if (!kgem_check_bo(&sna->kgem, src_bo))
+ kgem_submit(&sna->kgem);
+
+ if (kgem_bo_is_dirty(src_bo))
+ kgem_emit_flush(&sna->kgem);
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.op = alu;
+
+ tmp.dst.pixmap = dst;
+ tmp.dst.width = dst->drawable.width;
+ tmp.dst.height = dst->drawable.height;
+ tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp.dst.bo = dst_bo;
+
+ tmp.floats_per_vertex = 4;
+
+ gen2_render_copy_setup_source(sna, &tmp.src, src, src_bo);
+ gen2_emit_copy_state(sna, &tmp);
+ do {
+ int n_this_time;
+
+ n_this_time = gen2_get_rectangles(sna, &tmp, n);
+ if (n_this_time == 0) {
+ gen2_emit_copy_state(sna, &tmp);
+ n_this_time = gen2_get_rectangles(sna, &tmp, n);
+ }
+ n -= n_this_time;
+
+ do {
+ DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n",
+ box->x1 + src_dx, box->y1 + src_dy,
+ box->x1 + dst_dx, box->y1 + dst_dy,
+ box->x2 - box->x1, box->y2 - box->y1));
+ OUT_VERTEX(box->x2 + dst_dx);
+ OUT_VERTEX(box->y2 + dst_dy);
+ OUT_VERTEX((box->x2 + src_dx) * tmp.src.scale[0]);
+ OUT_VERTEX((box->y2 + src_dy) * tmp.src.scale[1]);
+
+ OUT_VERTEX(box->x1 + dst_dx);
+ OUT_VERTEX(box->y2 + dst_dy);
+ OUT_VERTEX((box->x1 + src_dx) * tmp.src.scale[0]);
+ OUT_VERTEX((box->y2 + src_dy) * tmp.src.scale[1]);
+
+ OUT_VERTEX(box->x1 + dst_dx);
+ OUT_VERTEX(box->y1 + dst_dy);
+ OUT_VERTEX((box->x1 + src_dx) * tmp.src.scale[0]);
+ OUT_VERTEX((box->y1 + src_dy) * tmp.src.scale[1]);
+
+ box++;
+ } while (--n_this_time);
+ } while (n);
+
+ gen2_vertex_flush(sna);
+ _kgem_set_mode(&sna->kgem, KGEM_RENDER);
+ return TRUE;
+}
+
+static void
+gen2_render_copy_blt(struct sna *sna,
+ const struct sna_copy_op *op,
+ int16_t sx, int16_t sy,
+ int16_t w, int16_t h,
+ int16_t dx, int16_t dy)
+{
+ if (!gen2_get_rectangles(sna, &op->base, 1)) {
+ gen2_emit_copy_state(sna, &op->base);
+ gen2_get_rectangles(sna, &op->base, 1);
+ }
+
+ OUT_VERTEX(dx+w);
+ OUT_VERTEX(dy+h);
+ OUT_VERTEX((sx+w)*op->base.src.scale[0]);
+ OUT_VERTEX((sy+h)*op->base.src.scale[1]);
+
+ OUT_VERTEX(dx);
+ OUT_VERTEX(dy+h);
+ OUT_VERTEX(sx*op->base.src.scale[0]);
+ OUT_VERTEX((sy+h)*op->base.src.scale[1]);
+
+ OUT_VERTEX(dx);
+ OUT_VERTEX(dy);
+ OUT_VERTEX(sx*op->base.src.scale[0]);
+ OUT_VERTEX(sy*op->base.src.scale[1]);
+}
+
+static void
+gen2_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
+{
+ gen2_vertex_flush(sna);
+ _kgem_set_mode(&sna->kgem, KGEM_RENDER);
+}
+
+static Bool
+gen2_render_copy(struct sna *sna, uint8_t alu,
+ PixmapPtr src, struct kgem_bo *src_bo,
+ PixmapPtr dst, struct kgem_bo *dst_bo,
+ struct sna_copy_op *tmp)
+{
+#if NO_COPY
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
+ return sna_blt_copy(sna, alu,
+ src_bo, dst_bo,
+ dst->drawable.bitsPerPixel,
+ tmp);
+#endif
+
+ /* Prefer to use the BLT */
+ if (!PREFER_COPY && sna->kgem.mode == KGEM_BLT &&
+ sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
+ sna_blt_copy(sna, alu,
+ src_bo, dst_bo,
+ dst->drawable.bitsPerPixel,
+ tmp))
+ return TRUE;
+
+ /* Must use the BLT if we can't RENDER... */
+ if (src->drawable.width > 2048 || src->drawable.height > 2048 ||
+ dst->drawable.width > 2048 || dst->drawable.height > 2048 ||
+ src_bo->pitch > 8192 || dst_bo->pitch > 8192) {
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
+ return sna_blt_copy(sna, alu, src_bo, dst_bo,
+ dst->drawable.bitsPerPixel,
+ tmp);
+ }
+
+ tmp->base.op = alu;
+
+ tmp->base.dst.pixmap = dst;
+ tmp->base.dst.width = dst->drawable.width;
+ tmp->base.dst.height = dst->drawable.height;
+ tmp->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp->base.dst.bo = dst_bo;
+
+ gen2_render_copy_setup_source(sna, &tmp->base.src, src, src_bo);
+
+ tmp->base.floats_per_vertex = 4;
+
+ if (!kgem_check_bo(&sna->kgem, dst_bo))
+ kgem_submit(&sna->kgem);
+ if (!kgem_check_bo(&sna->kgem, src_bo))
+ kgem_submit(&sna->kgem);
+
+ if (kgem_bo_is_dirty(src_bo))
+ kgem_emit_flush(&sna->kgem);
+
+ tmp->blt = gen2_render_copy_blt;
+ tmp->done = gen2_render_copy_done;
+
+ gen2_emit_composite_state(sna, &tmp->base);
+ return TRUE;
+}
+
static void
gen2_render_reset(struct sna *sna)
{
sna->render_state.gen2.need_invariant = TRUE;
+ sna->render_state.gen2.logic_op_enabled = FALSE;
sna->render_state.gen2.vertex_offset = 0;
sna->render_state.gen2.target = 0;
}
@@ -1674,7 +2071,11 @@ Bool gen2_render_init(struct sna *sna)
render->composite_spans = gen2_render_composite_spans;
render->fill_boxes = gen2_render_fill_boxes;
- /* XXX Y-tiling copies */
+ render->fill = gen2_render_fill;
+ render->copy = gen2_render_copy;
+ render->copy_boxes = gen2_render_copy_boxes;
+
+ /* XXX YUV color space conversion for video? */
render->reset = gen2_render_reset;
render->flush = gen2_render_flush;
diff --git a/src/sna/gen2_render.h b/src/sna/gen2_render.h
index a1767ad..c10d540 100644
--- a/src/sna/gen2_render.h
+++ b/src/sna/gen2_render.h
@@ -585,6 +585,7 @@
#define S3_ENABLE_LOCAL_DEPTH_BIAS (1<<3)
#define S3_ENABLE_SPRITE_POINT (1<<1)
#define S3_ENABLE_ANTIALIASING 1
+#define S7_ENABLE_LOGIC_OP (1<<0)
#define S8_ENABLE_ALPHA_TEST (1<<31)
#define S8_ALPHA_TEST_FUNC_SHIFT 28
#define S8_ALPHA_REFVALUE_SHIFT 20
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 92edc72..aba1b8d 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3448,6 +3448,9 @@ gen3_render_copy(struct sna *sna, uint8_t alu,
if (!kgem_check_bo(&sna->kgem, src_bo))
kgem_submit(&sna->kgem);
+ if (kgem_bo_is_dirty(src_bo))
+ kgem_emit_flush(&sna->kgem);
+
tmp->blt = gen3_render_copy_blt;
tmp->done = gen3_render_copy_done;
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 5b51be9..012b090 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -90,7 +90,7 @@ struct sna_composite_op {
} blt;
struct {
- int nothing;
+ uint32_t pixel;
} gen2;
struct {
@@ -238,6 +238,7 @@ struct sna_render {
struct gen2_render_state {
uint32_t target;
Bool need_invariant;
+ Bool logic_op_enabled;
uint16_t vertex_offset;
};
commit ecbf6bbd27b1205dcf76cfe34ae2a7a3f5ec195a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 1 08:50:58 2011 +0100
sna/gen2: Implement composite-spans
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 06cab3c..82c7e15 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -330,12 +330,9 @@ gen2_get_blend_factors(const struct sna_composite_op *op,
* pictures, but we need to implement it for 830/845 and there's no
* harm done in leaving it in.
*/
- cblend =
- TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
- TB0C_OUTPUT_WRITE_CURRENT;
- ablend =
- TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
- TB0A_OUTPUT_WRITE_CURRENT;
+ cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OUTPUT_WRITE_CURRENT;
+ ablend = TB0A_RESULT_SCALE_1X | TB0A_OUTPUT_WRITE_CURRENT;
+
/* Get the source picture's channels into TBx_ARG1 */
if ((op->has_component_alpha && gen2_blend_op[op->op].src_alpha) ||
@@ -359,13 +356,18 @@ gen2_get_blend_factors(const struct sna_composite_op *op,
}
if (op->mask.bo) {
+ cblend |= TB0C_OP_MODULATE;
cblend |= TB0C_ARG2_SEL_TEXEL1;
- if (op->dst.format == PICT_a8 || !op->has_component_alpha)
+ if (op->dst.format == PICT_a8 ||
+ !op->has_component_alpha ||
+ PICT_FORMAT_RGB(op->mask.pict_format) == 0)
cblend |= TB0C_ARG2_REPLICATE_ALPHA;
+
ablend |= TB0A_ARG2_SEL_TEXEL1;
+ ablend |= TB0A_OP_MODULATE;
} else {
- cblend |= TB0C_ARG2_SEL_ONE;
- ablend |= TB0A_ARG2_SEL_ONE;
+ cblend |= TB0C_OP_ARG1;
+ ablend |= TB0A_OP_ARG1;
}
*c_out = cblend;
@@ -413,21 +415,6 @@ static void gen2_emit_invariant(struct sna *sna)
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(2));
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(3));
- OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
- OUT_BATCH(0);
-
- OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
- OUT_BATCH(0);
-
- OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
- OUT_BATCH(0);
-
- OUT_BATCH(_3DSTATE_FOG_MODE_CMD);
- OUT_BATCH(FOGFUNC_ENABLE |
- FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY);
- OUT_BATCH(0);
- OUT_BATCH(0);
-
OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
MAP_UNIT(0) |
DISABLE_TEX_STREAM_BUMP |
@@ -473,12 +460,10 @@ static void gen2_emit_invariant(struct sna *sna)
ENABLE_TRI_FAN_PROVOKE_VRTX |
ENABLE_TRI_STRIP_PROVOKE_VRTX |
LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2));
+ TRI_FAN_PROVOKE_VRTX(2) |
+ TRI_STRIP_PROVOKE_VRTX(2));
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
- OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD);
- OUT_BATCH(0);
- OUT_BATCH(0);
OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM);
OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
@@ -487,9 +472,6 @@ static void gen2_emit_invariant(struct sna *sna)
OUT_BATCH(MAGIC_W_STATE_DWORD1);
OUT_BATCH_F(1.0);
- OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD);
- OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */
-
OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD);
OUT_BATCH(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
@@ -500,51 +482,22 @@ static void gen2_emit_invariant(struct sna *sna)
DISABLE_INDPT_ALPHA_BLEND |
ENABLE_ALPHA_BLENDFUNC | ABLENDFUNC_ADD);
- OUT_BATCH(_3DSTATE_FOG_COLOR_CMD |
- FOG_COLOR_RED(0) | FOG_COLOR_GREEN(0) | FOG_COLOR_BLUE(0));
-
OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_MODES_1_CMD |
ENABLE_COLR_BLND_FUNC |
BLENDFUNC_ADD |
- ENABLE_SRC_BLND_FACTOR |
- SRC_BLND_FACT(BLENDFACTOR_ONE) |
+ ENABLE_SRC_BLND_FACTOR | SRC_BLND_FACT(BLENDFACTOR_ONE) |
ENABLE_DST_BLND_FACTOR | DST_BLND_FACT(BLENDFACTOR_ZERO));
- OUT_BATCH(_3DSTATE_MODES_2_CMD |
- ENABLE_GLOBAL_DEPTH_BIAS |
- GLOBAL_DEPTH_BIAS(0) |
- ENABLE_ALPHA_TEST_FUNC |
- ALPHA_TEST_FUNC(0) | /* always */
- ALPHA_REF_VALUE(0));
+ OUT_BATCH(_3DSTATE_MODES_2_CMD);
OUT_BATCH(_3DSTATE_MODES_3_CMD |
- ENABLE_DEPTH_TEST_FUNC |
- DEPTH_TEST_FUNC(0x2) | /* COMPAREFUNC_LESS */
ENABLE_ALPHA_SHADE_MODE | ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
ENABLE_FOG_SHADE_MODE | FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
ENABLE_SPEC_SHADE_MODE | SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
ENABLE_COLOR_SHADE_MODE | COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
ENABLE_CULL_MODE | CULLMODE_NONE);
- OUT_BATCH(_3DSTATE_MODES_4_CMD |
- ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
- ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff) |
- ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff));
-
- OUT_BATCH(_3DSTATE_STENCIL_TEST_CMD |
- ENABLE_STENCIL_PARMS |
- STENCIL_FAIL_OP(0) | /* STENCILOP_KEEP */
- STENCIL_PASS_DEPTH_FAIL_OP(0) | /* STENCILOP_KEEP */
- STENCIL_PASS_DEPTH_PASS_OP(0) | /* STENCILOP_KEEP */
- ENABLE_STENCIL_TEST_FUNC | STENCIL_TEST_FUNC(0) | /* COMPAREFUNC_ALWAYS */
- ENABLE_STENCIL_REF_VALUE | STENCIL_REF_VALUE(0));
-
- OUT_BATCH(_3DSTATE_MODES_5_CMD |
- ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF |
- ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */
- ENABLE_FIXED_POINT_WIDTH | FIXED_POINT_WIDTH(1));
-
OUT_BATCH(_3DSTATE_ENABLES_1_CMD |
DISABLE_LOGIC_OP |
DISABLE_STENCIL_TEST |
@@ -567,22 +520,30 @@ static void gen2_emit_invariant(struct sna *sna)
/* Set default blend state */
OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
TEXPIPE_COLOR |
- ENABLE_TEXOUTPUT_WRT_SEL | TEXOP_OUTPUT_CURRENT |
+ ENABLE_TEXOUTPUT_WRT_SEL |
+ TEXOP_OUTPUT_CURRENT |
DISABLE_TEX_CNTRL_STAGE |
- TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS |
- TEXOP_LAST_STAGE | TEXBLENDOP_ARG1);
+ TEXOP_SCALE_1X |
+ TEXOP_MODIFY_PARMS |
+ TEXOP_LAST_STAGE |
+ TEXBLENDOP_ARG1);
OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
TEXPIPE_ALPHA |
- ENABLE_TEXOUTPUT_WRT_SEL | TEXOP_OUTPUT_CURRENT |
- TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1);
+ ENABLE_TEXOUTPUT_WRT_SEL |
+ TEXOP_OUTPUT_CURRENT |
+ TEXOP_SCALE_1X |
+ TEXOP_MODIFY_PARMS |
+ TEXBLENDOP_ARG1);
OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_COLOR |
TEXBLEND_ARG1 |
- TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
+ TEXBLENDARG_MODIFY_PARMS |
+ TEXBLENDARG_DIFFUSE);
OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_ALPHA |
TEXBLEND_ARG1 |
- TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
+ TEXBLENDARG_MODIFY_PARMS |
+ TEXBLENDARG_DIFFUSE);
OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -626,13 +587,12 @@ gen2_get_batch(struct sna *sna,
gen2_emit_invariant(sna);
}
-static void gen2_emit_composite_state(struct sna *sna,
- const struct sna_composite_op *op)
+static void gen2_emit_target(struct sna *sna, const struct sna_composite_op *op)
{
- uint32_t texcoordfmt;
- uint32_t cblend, ablend;
-
- gen2_get_batch(sna, op);
+ if (sna->render_state.gen2.target == op->dst.bo->unique_id) {
+ kgem_bo_mark_dirty(op->dst.bo);
+ return;
+ }
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(BUF_3D_ID_COLOR_BACK |
@@ -654,6 +614,18 @@ static void gen2_emit_composite_state(struct sna *sna,
DRAW_XMAX(op->dst.width - 1));
OUT_BATCH(0); /* yorig, xorig */
+ sna->render_state.gen2.target = op->dst.bo->unique_id;
+}
+
+static void gen2_emit_composite_state(struct sna *sna,
+ const struct sna_composite_op *op)
+{
+ uint32_t texcoordfmt;
+ uint32_t cblend, ablend;
+
+ gen2_get_batch(sna, op);
+ gen2_emit_target(sna, op);
+
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2);
OUT_BATCH((1 + (op->mask.bo != NULL)) << 12);
@@ -1042,7 +1014,7 @@ gen2_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
channel->pict_format = picture->format;
- if (pixmap->drawable.width > 8192 || pixmap->drawable.height > 8192)
+ if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048)
return sna_render_picture_extract(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
@@ -1228,8 +1200,16 @@ gen2_render_composite(struct sna *sna,
if (!kgem_check_bo(&sna->kgem, tmp->mask.bo))
kgem_submit(&sna->kgem);
- if (kgem_bo_is_dirty(tmp->src.bo) || kgem_bo_is_dirty(tmp->mask.bo))
- kgem_emit_flush(&sna->kgem);
+ if (kgem_bo_is_dirty(tmp->src.bo) || kgem_bo_is_dirty(tmp->mask.bo)) {
+ if (tmp->src.bo == tmp->dst.bo || tmp->mask.bo == tmp->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_state(sna, tmp);
@@ -1246,21 +1226,441 @@ cleanup_dst:
}
static void
-gen2_render_reset(struct sna *sna)
+gen2_emit_composite_spans_vertex(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ int16_t x, int16_t y,
+ float opacity)
{
- sna->render_state.gen2.need_invariant = TRUE;
- sna->render_state.gen2.vertex_offset = 0;
+ gen2_emit_composite_dstcoord(sna, x + op->base.dst.x, y + op->base.dst.y);
+ OUT_BATCH((uint8_t)(opacity * 255) << 24);
+ gen2_emit_composite_texcoord(sna, &op->base.src, x, y);
}
static void
-gen2_render_flush(struct sna *sna)
+gen2_emit_composite_spans_primitive(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ gen2_emit_composite_spans_vertex(sna, op, box->x2, box->y2, opacity);
+ gen2_emit_composite_spans_vertex(sna, op, box->x1, box->y2, opacity);
+ gen2_emit_composite_spans_vertex(sna, op, box->x1, box->y1, opacity);
+}
+
+#if 0
+static void gen2_emit_fill_blend_op(struct sna *sna)
+{
+ /* Set default blend state */
+ OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
+ TEXPIPE_COLOR |
+ ENABLE_TEXOUTPUT_WRT_SEL |
+ TEXOP_OUTPUT_CURRENT |
+ DISABLE_TEX_CNTRL_STAGE |
+ TEXOP_SCALE_1X |
+ TEXOP_MODIFY_PARMS |
+ TEXOP_LAST_STAGE |
+ TEXBLENDOP_ARG1);
+ OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) |
+ TEXPIPE_ALPHA |
+ ENABLE_TEXOUTPUT_WRT_SEL |
+ TEXOP_OUTPUT_CURRENT |
+ TEXOP_SCALE_1X |
+ TEXOP_MODIFY_PARMS |
+ TEXBLENDOP_ARG1);
+ OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
+ TEXPIPE_COLOR |
+ TEXBLEND_ARG1 |
+ TEXBLENDARG_MODIFY_PARMS |
+ TEXBLENDARG_DIFFUSE);
+ OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) |
+ TEXPIPE_ALPHA |
+ TEXBLEND_ARG1 |
+ TEXBLENDARG_MODIFY_PARMS |
+ TEXBLENDARG_DIFFUSE);
+}
+#endif
+
+static void
+gen2_emit_spans_blend_op(struct sna *sna,
+ const struct sna_composite_spans_op *op)
+{
+ uint32_t cblend, ablend;
+
+ cblend =
+ TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULATE |
+ TB0C_ARG1_SEL_DIFFUSE | TB0C_ARG1_REPLICATE_ALPHA |
+ TB0C_OUTPUT_WRITE_CURRENT;
+ ablend =
+ TB0A_RESULT_SCALE_1X | TB0A_OP_MODULATE |
+ TB0A_ARG1_SEL_DIFFUSE |
+ TB0A_OUTPUT_WRITE_CURRENT;
+
+ if (op->base.dst.format == PICT_a8) {
+ ablend |= TB0A_ARG2_SEL_TEXEL0;
+ 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;
+ else
+ cblend |= TB0C_ARG2_SEL_ONE | TB0C_ARG2_INVERT;
+
+ if (op->base.src.is_opaque)
+ ablend |= TB0A_ARG2_SEL_ONE;
+ else
+ ablend |= TB0A_ARG2_SEL_TEXEL0;
+ }
+
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
+ LOAD_TEXTURE_BLEND_STAGE(0) | 1);
+ OUT_BATCH(cblend);
+ OUT_BATCH(ablend);
+}
+
+static void gen2_emit_composite_spans_state(struct sna *sna,
+ const struct sna_composite_spans_op *op)
+{
+ gen2_get_batch(sna, &op->base);
+ gen2_emit_target(sna, &op->base);
+
+ 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(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_emit_spans_blend_op(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);
+}
+
+static void
+gen2_render_composite_spans_boxes(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box, int nbox,
+ float opacity)
+{
+ DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n",
+ __FUNCTION__, nbox,
+ op->base.src.offset[0], op->base.src.offset[1],
+ opacity,
+ op->base.dst.x, op->base.dst.y));
+
+ do {
+ int nbox_this_time;
+
+ nbox_this_time = gen2_get_rectangles(sna, &op->base, nbox);
+ if (nbox_this_time == 0) {
+ gen2_emit_composite_spans_state(sna, op);
+ nbox_this_time = gen2_get_rectangles(sna, &op->base, nbox);
+ }
+ nbox -= nbox_this_time;
+
+ do {
+ DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__,
+ box->x1, box->y1,
+ box->x2 - box->x1,
+ box->y2 - box->y1));
+
+ op->prim_emit(sna, op, box++, opacity);
+ } while (--nbox_this_time);
+ } while (nbox);
+}
+
+static void
+gen2_render_composite_spans_done(struct sna *sna,
+ const struct sna_composite_spans_op *op)
{
gen2_vertex_flush(sna);
+ _kgem_set_mode(&sna->kgem, KGEM_RENDER);
+
+ DBG(("%s()\n", __FUNCTION__));
+
+ sna_render_composite_redirect_done(sna, &op->base);
+ if (op->base.src.bo)
+ kgem_bo_destroy(&sna->kgem, op->base.src.bo);
+}
+
+static Bool
+gen2_render_composite_spans(struct sna *sna,
+ uint8_t op,
+ PicturePtr src,
+ PicturePtr dst,
+ int16_t src_x, int16_t src_y,
+ int16_t dst_x, int16_t dst_y,
+ int16_t width, int16_t height,
+ struct sna_composite_spans_op *tmp)
+{
+ DBG(("%s(src=(%d, %d), dst=(%d, %d), size=(%d, %d))\n", __FUNCTION__,
+ src_x, src_y, dst_x, dst_y, width, height));
+
+#if NO_COMPOSITE_SPANS
+ return FALSE;
+#endif
+
+ if (op >= ARRAY_SIZE(gen2_blend_op)) {
+ DBG(("%s: fallback due to unhandled blend op: %d\n",
+ __FUNCTION__, op));
+ return FALSE;
+ }
+
+ if (!gen2_check_dst_format(dst->format)) {
+ DBG(("%s: fallback due to unhandled dst format: %x\n",
+ __FUNCTION__, dst->format));
+ return FALSE;
+ }
+
+ if (need_tiling(sna, width, height))
+ return FALSE;
+
+ if (!gen2_composite_set_target(sna, &tmp->base, dst)) {
+ DBG(("%s: unable to set render target\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ tmp->base.op = op;
+ if (tmp->base.dst.width > 2048 ||
+ tmp->base.dst.height > 2048 ||
+ tmp->base.dst.bo->pitch > 8192) {
+ if (!sna_render_composite_redirect(sna, &tmp->base,
+ dst_x, dst_y, width, height))
+ return FALSE;
+ }
+
+ switch (gen2_composite_picture(sna, src, &tmp->base.src,
+ src_x, src_y,
+ width, height,
+ dst_x, dst_y)) {
+ case -1:
+ goto cleanup_dst;
+ case 0:
+ gen2_composite_solid_init(sna, &tmp->base.src, 0);
+ case 1:
+ break;
+ }
+
+ tmp->prim_emit = gen2_emit_composite_spans_primitive;
+ tmp->base.floats_per_vertex = 3;
+ if (tmp->base.src.bo)
+ tmp->base.floats_per_vertex += tmp->base.src.is_affine ? 2 : 3;
+
+ tmp->boxes = gen2_render_composite_spans_boxes;
+ tmp->done = gen2_render_composite_spans_done;
+
+ if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo))
+ kgem_submit(&sna->kgem);
+ 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;
+
+cleanup_dst:
+ if (tmp->base.redirect.real_bo)
+ kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo);
+ return FALSE;
}
static void
-gen2_render_fini(struct sna *sna)
+gen2_emit_fill_blend_op(struct sna *sna, const struct sna_composite_op *op)
{
+ uint32_t blend;
+
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
+ LOAD_TEXTURE_BLEND_STAGE(0) | 1);
+ blend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_ARG1 |
+ TB0C_ARG1_SEL_DIFFUSE |
+ TB0C_OUTPUT_WRITE_CURRENT;
+
+ if (op->dst.format == PICT_a8)
+ blend |= TB0C_ARG1_REPLICATE_ALPHA;
+
+ OUT_BATCH(blend);
+ OUT_BATCH(TB0A_RESULT_SCALE_1X | TB0A_OP_ARG1 |
+ TB0A_ARG1_SEL_DIFFUSE |
+ TB0A_OUTPUT_WRITE_CURRENT);
+}
+
+static void gen2_emit_fill_composite_state(struct sna *sna,
+ const struct sna_composite_op *op,
+ uint32_t pixel)
+{
+ gen2_get_batch(sna, op);
+ gen2_emit_target(sna, op);
+
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+ I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2);
+ OUT_BATCH(0);
+ OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
+ OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |
+ gen2_get_blend_cntl(op->op, FALSE, op->dst.format) |
+ S8_ENABLE_COLOR_BUFFER_WRITE);
+
+ gen2_emit_fill_blend_op(sna, op);
+
+ OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_BATCH(pixel);
+}
+
+static Bool
+gen2_render_fill_boxes_try_blt(struct sna *sna,
+ CARD8 op, PictFormat format,
+ const xRenderColor *color,
+ PixmapPtr dst, struct kgem_bo *dst_bo,
+ const BoxRec *box, int n)
+{
+ uint8_t alu = GXcopy;
+ uint32_t pixel;
+
+ if (!sna_get_pixel_from_rgba(&pixel,
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha,
+ format))
+ return FALSE;
+
+ if (op == PictOpClear) {
+ alu = GXclear;
+ pixel = 0;
+ op = PictOpSrc;
+ }
+
+ if (op == PictOpOver) {
+ if ((pixel & 0xff000000) == 0xff000000)
+ op = PictOpSrc;
+ }
+
+ if (op != PictOpSrc)
+ return FALSE;
+
+ return sna_blt_fill_boxes(sna, alu,
+ dst_bo, dst->drawable.bitsPerPixel,
+ pixel, box, n);
+}
+
+static Bool
+gen2_render_fill_boxes(struct sna *sna,
+ CARD8 op,
+ PictFormat format,
+ const xRenderColor *color,
+ PixmapPtr dst, struct kgem_bo *dst_bo,
+ const BoxRec *box, int n)
+{
+ struct sna_composite_op tmp;
+ uint32_t pixel;
+
+#if NO_FILL_BOXES
+ return gen2_render_fill_boxes_try_blt(sna, op, format, color,
+ dst, dst_bo,
+ box, n);
+#endif
+
+ DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x))\n",
+ __FUNCTION__, op, (int)format,
+ color->red, color->green, color->blue, color->alpha));
+
+ if (op >= ARRAY_SIZE(gen2_blend_op)) {
+ DBG(("%s: fallback due to unhandled blend op: %d\n",
+ __FUNCTION__, op));
+ return FALSE;
+ }
+
+ if (dst->drawable.width > 2048 ||
+ dst->drawable.height > 2048 ||
+ dst_bo->pitch > 8192 ||
+ !gen2_check_dst_format(format))
+ return gen2_render_fill_boxes_try_blt(sna, op, format, color,
+ dst, dst_bo,
+ box, n);
+
+ if (gen2_render_fill_boxes_try_blt(sna, op, format, color,
+ dst, dst_bo,
+ box, n))
+ return TRUE;
+
+ if (!sna_get_pixel_from_rgba(&pixel,
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha,
+ PICT_a8r8g8b8))
+ return FALSE;
+
+ DBG(("%s: using shader for op=%d, format=%x, pixel=%x\n",
+ __FUNCTION__, op, (int)format, pixel));
+
+ if (pixel == 0)
+ op = PictOpClear;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.op = op;
+ tmp.dst.pixmap = dst;
+ tmp.dst.width = dst->drawable.width;
+ tmp.dst.height = dst->drawable.height;
+ tmp.dst.format = format;
+ tmp.dst.bo = dst_bo;
+ tmp.floats_per_vertex = 2;
+
+ if (!kgem_check_bo(&sna->kgem, dst_bo))
+ kgem_submit(&sna->kgem);
+
+ gen2_emit_fill_composite_state(sna, &tmp, pixel);
+
+ do {
+ int n_this_time = gen2_get_rectangles(sna, &tmp, n);
+ if (n_this_time == 0) {
+ gen2_emit_fill_composite_state(sna, &tmp, pixel);
+ n_this_time = gen2_get_rectangles(sna, &tmp, n);
+ }
+ n -= n_this_time;
+
+ do {
+ DBG((" (%d, %d), (%d, %d): %x\n",
+ box->x1, box->y1, box->x2, box->y2, pixel));
+ OUT_VERTEX(box->x2);
+ OUT_VERTEX(box->y2);
+ OUT_VERTEX(box->x1);
+ OUT_VERTEX(box->y2);
+ OUT_VERTEX(box->x1);
+ OUT_VERTEX(box->y1);
+ box++;
+ } while (--n_this_time);
+ } while (n);
+
+ gen2_vertex_flush(sna);
+ _kgem_set_mode(&sna->kgem, KGEM_RENDER);
+ return TRUE;
+}
+
+static void
+gen2_render_reset(struct sna *sna)
+{
+ sna->render_state.gen2.need_invariant = TRUE;
+ sna->render_state.gen2.vertex_offset = 0;
+ sna->render_state.gen2.target = 0;
+}
+
+static void
+gen2_render_flush(struct sna *sna)
+{
+ gen2_vertex_flush(sna);
}
Bool gen2_render_init(struct sna *sna)
@@ -1271,12 +1671,13 @@ Bool gen2_render_init(struct sna *sna)
* use the texture combiners.
*/
render->composite = gen2_render_composite;
+ render->composite_spans = gen2_render_composite_spans;
+ render->fill_boxes = gen2_render_fill_boxes;
/* XXX Y-tiling copies */
render->reset = gen2_render_reset;
render->flush = gen2_render_flush;
- render->fini = gen2_render_fini;
render->max_3d_size = 2048;
return TRUE;
diff --git a/src/sna/gen2_render.h b/src/sna/gen2_render.h
index 945cd84..a1767ad 100644
--- a/src/sna/gen2_render.h
+++ b/src/sna/gen2_render.h
@@ -447,9 +447,8 @@
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
#define ENABLE_SPRITE_POINT_TEX (1<<23)
#define SPRITE_POINT_TEX_ON (1<<22)
-#define SPRITE_POINT_TEX_OFF 0
-#define FLUSH_RENDER_CACHE (1<<18)
-#define FLUSH_TEXTURE_CACHE (1<<16)
+#define PIPELINE_FLUSH_RENDER_CACHE (1<<18)
+#define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16)
#define FIXED_LINE_WIDTH_MASK 0xfc00
#define ENABLE_FIXED_LINE_WIDTH (1<<15)
#define FIXED_LINE_WIDTH(x) ((x)<<10)
@@ -735,7 +734,8 @@
#define TB0C_RESULT_SCALE_1X (0 << 29)
#define TB0C_RESULT_SCALE_2X (1 << 29)
#define TB0C_RESULT_SCALE_4X (2 << 29)
-#define TB0C_OP_MODULE (3 << 25)
+#define TB0C_OP_ARG1 (1 << 25)
+#define TB0C_OP_MODULATE (3 << 25)
#define TB0C_OUTPUT_WRITE_CURRENT (0 << 24)
#define TB0C_OUTPUT_WRITE_ACCUM (1 << 24)
#define TB0C_ARG3_REPLICATE_ALPHA (1<<23)
@@ -752,6 +752,7 @@
#define TB0C_ARG1_REPLICATE_ALPHA (1<<11)
#define TB0C_ARG1_INVERT (1<<10)
#define TB0C_ARG1_SEL_ONE (0 << 6)
+#define TB0C_ARG1_SEL_DIFFUSE (3 << 6)
#define TB0C_ARG1_SEL_TEXEL0 (6 << 6)
#define TB0C_ARG1_SEL_TEXEL1 (7 << 6)
#define TB0C_ARG1_SEL_TEXEL2 (8 << 6)
@@ -763,7 +764,8 @@
#define TB0A_RESULT_SCALE_1X (0 << 29)
#define TB0A_RESULT_SCALE_2X (1 << 29)
#define TB0A_RESULT_SCALE_4X (2 << 29)
-#define TB0A_OP_MODULE (3 << 25)
+#define TB0A_OP_ARG1 (1 << 25)
+#define TB0A_OP_MODULATE (3 << 25)
#define TB0A_OUTPUT_WRITE_CURRENT (0<<24)
#define TB0A_OUTPUT_WRITE_ACCUM (1<<24)
#define TB0A_CTR_STAGE_SEL_BITS_XXX
@@ -771,12 +773,14 @@
#define TB0A_ARG3_INVERT (1<<17)
#define TB0A_ARG2_INVERT (1<<16)
#define TB0A_ARG2_SEL_ONE (0 << 12)
+#define TB0A_ARG2_SEL_DIFFUSE (3 << 12)
#define TB0A_ARG2_SEL_TEXEL0 (6 << 12)
#define TB0A_ARG2_SEL_TEXEL1 (7 << 12)
#define TB0A_ARG2_SEL_TEXEL2 (8 << 12)
#define TB0A_ARG2_SEL_TEXEL3 (9 << 12)
#define TB0A_ARG1_INVERT (1<<10)
#define TB0A_ARG1_SEL_ONE (0 << 6)
+#define TB0A_ARG1_SEL_DIFFUSE (3 << 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/sna_render.c b/src/sna/sna_render.c
index 21afd26..72a3c1e 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -437,7 +437,7 @@ sna_render_picture_extract(struct sna *sna,
{
struct kgem_bo *bo = NULL;
PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable);
- int16_t ox, oy;
+ int16_t ox, oy, ow, oh;
BoxRec box;
#if NO_EXTRACT
@@ -452,6 +452,9 @@ sna_render_picture_extract(struct sna *sna,
return -1;
}
+ ow = w;
+ oh = h;
+
ox = box.x1 = x;
oy = box.y1 = y;
box.x2 = x + w;
@@ -482,7 +485,11 @@ sna_render_picture_extract(struct sna *sna,
if (!channel->is_affine) {
DBG(("%s: fallback -- repeating project transform too large for texture\n",
__FUNCTION__));
- return -1;
+ return sna_render_picture_fixup(sna,
+ picture,
+ channel,
+ x, y, ow, oh,
+ dst_x, dst_y);
}
}
} else {
@@ -510,7 +517,8 @@ sna_render_picture_extract(struct sna *sna,
if (w > sna->render.max_3d_size || h > sna->render.max_3d_size) {
DBG(("%s: fallback -- sample too large for texture (%d, %d)x(%d, %d)\n",
__FUNCTION__, box.x1, box.y1, w, h));
- return -1;
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, ow, oh, dst_x, dst_y);
}
if (texture_is_cpu(pixmap, &box) && !move_to_gpu(pixmap, &box)) {
@@ -528,7 +536,8 @@ sna_render_picture_extract(struct sna *sna,
if (!sna_pixmap_move_to_gpu(pixmap)) {
DBG(("%s: falback -- pixmap is not on the GPU\n",
__FUNCTION__));
- return -1;
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, ow, oh, dst_x, dst_y);
}
bo = kgem_create_2d(&sna->kgem, w, h,
@@ -550,7 +559,8 @@ sna_render_picture_extract(struct sna *sna,
&box, 1)) {
DBG(("%s: fallback -- unable to copy boxes\n",
__FUNCTION__));
- return -1;
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, ow, oh, dst_x, dst_y);
}
}
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index c2d6f12..5b51be9 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -236,6 +236,7 @@ struct sna_render {
};
struct gen2_render_state {
+ uint32_t target;
Bool need_invariant;
uint16_t vertex_offset;
};
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index db9e085..536034f 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -2073,7 +2073,7 @@ composite_unaligned_boxes(CARD8 op,
DBG(("%s\n", __FUNCTION__));
- /* XXX need a span converter to handle overlapping traps */
+ /* need a span converter to handle overlapping traps */
if (ntrap > 1 && maskFormat)
return false;
commit c89b37d7b43c9e588097b7fadcba3bc13a03f8bc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 30 17:53:49 2011 +0100
sna: Mappable aperture is region 0 on gen2
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 27ed78c..88b1d83 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -293,9 +293,9 @@ static struct list *inactive(struct kgem *kgem,
}
static size_t
-agp_aperture_size(struct pci_device *dev)
+agp_aperture_size(struct pci_device *dev, int gen)
{
- return dev->regions[2].size;
+ return dev->regions[gen < 30 ? 0 :2].size;
}
void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
@@ -358,12 +358,15 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
kgem->aperture_high = aperture.aper_size * 3/4;
kgem->aperture_low = aperture.aper_size * 1/4;
- DBG(("%s: aperture low=%d, high=%d\n", __FUNCTION__,
- kgem->aperture_low, kgem->aperture_high));
+ DBG(("%s: aperture low=%d [%d], high=%d [%d]\n", __FUNCTION__,
+ kgem->aperture_low, kgem->aperture_low / (1024*1024),
+ kgem->aperture_high, kgem->aperture_high / (1024*1024)));
- kgem->aperture_mappable = agp_aperture_size(dev);
+ kgem->aperture_mappable = agp_aperture_size(dev, gen);
if (kgem->aperture_mappable == 0)
kgem->aperture_mappable = aperture.aper_size;
+ DBG(("%s: aperture mappable=%d [%d]\n", __FUNCTION__,
+ kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
i = 8;
gp.param = I915_PARAM_NUM_FENCES_AVAIL;
commit c0434ab49035bf278dad6f5f84a541ea58536fb4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 30 16:31:28 2011 +0100
sna: Distinguish 830/845 vs 855/865 using the generation id
Remove the PCI ID device checks by using the simpler check on the
generation id for errata pertaining to 830/845.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/intel_module.c b/src/intel_module.c
index f6561bf..499814e 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -46,9 +46,18 @@ static const struct intel_device_info intel_i81x_info = {
.gen = 10,
};
-static const struct intel_device_info intel_i8xx_info = {
+static const struct intel_device_info intel_i830_info = {
.gen = 20,
};
+static const struct intel_device_info intel_i845_info = {
+ .gen = 20,
+};
+static const struct intel_device_info intel_i855_info = {
+ .gen = 21,
+};
+static const struct intel_device_info intel_i865_info = {
+ .gen = 21,
+};
static const struct intel_device_info intel_i915_info = {
.gen = 30,
@@ -142,11 +151,11 @@ static const struct pci_id_match intel_device_match[] = {
INTEL_DEVICE_MATCH (PCI_CHIP_I810_E, &intel_i81x_info ),
INTEL_DEVICE_MATCH (PCI_CHIP_I815, &intel_i81x_info ),
- INTEL_DEVICE_MATCH (PCI_CHIP_I830_M, &intel_i8xx_info ),
- INTEL_DEVICE_MATCH (PCI_CHIP_845_G, &intel_i8xx_info ),
- INTEL_DEVICE_MATCH (PCI_CHIP_I854, &intel_i8xx_info ),
- INTEL_DEVICE_MATCH (PCI_CHIP_I855_GM, &intel_i8xx_info ),
- INTEL_DEVICE_MATCH (PCI_CHIP_I865_G, &intel_i8xx_info ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_I830_M, &intel_i830_info ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_845_G, &intel_i845_info ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_I854, &intel_i855_info ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_I855_GM, &intel_i855_info ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_I865_G, &intel_i865_info ),
INTEL_DEVICE_MATCH (PCI_CHIP_I915_G, &intel_i915_info ),
INTEL_DEVICE_MATCH (PCI_CHIP_E7221_G, &intel_i915_info ),
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 34c053b..06cab3c 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -161,7 +161,7 @@ gen2_get_card_format(struct sna *sna, uint32_t format)
if (i8xx_tex_formats[i].fmt == format)
return i8xx_tex_formats[i].card_fmt;
- if (IS_I830(sna) || IS_845G(sna)) {
+ if (sna->kgem.gen < 21) {
/* Whilst these are not directly supported on 830/845,
* we only enable them when we can implicitly convert
* them to a supported variant through the texture
@@ -969,7 +969,7 @@ gen2_check_card_format(struct sna *sna,
for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) {
if (i85x_tex_formats[i].fmt == format) {
- if (!(IS_I830(sna) || IS_845G(sna)))
+ if (sna->kgem.gen >= 21)
return TRUE;
if ( source_is_covered(picture, x, y, w,h)) {
diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index c0b1451..e50b3dd 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -196,7 +196,7 @@ sna_video_frame_init(struct sna *sna,
* stride must be at least 512 bytes. Take the easy fix
* and align on 512 bytes unconditionally. */
align = 512;
- else if (IS_I830(sna) || IS_845G(sna))
+ else if (sna->kgem.gen < 21)
/* Harsh, errata on these chipsets limit the stride
* to be a multiple of 256 bytes.
*/
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index c4838c2..422ce53 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -540,7 +540,7 @@ sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn,
DBG(("%s: w is %d, h is %d\n", __FUNCTION__, *w, *h));
- if (IS_845G(sna) || IS_I830(sna)) {
+ if (sna->kgem.gen < 21) {
if (*w > IMAGE_MAX_WIDTH_LEGACY)
*w = IMAGE_MAX_WIDTH_LEGACY;
if (*h > IMAGE_MAX_HEIGHT_LEGACY)
@@ -651,7 +651,7 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
adaptor->nEncodings = 1;
adaptor->pEncodings = xnfalloc(sizeof(DummyEncoding));
memcpy(adaptor->pEncodings, DummyEncoding, sizeof(DummyEncoding));
- if (IS_845G(sna) || IS_I830(sna)) {
+ if (sna->kgem.gen < 21) {
adaptor->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
adaptor->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
}
More information about the xorg-commit
mailing list