sna/gen2: Implement composite-spans

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-07-01 08:50:58 +01:00
parent c89b37d7b4
commit ecbf6bbd27
5 changed files with 511 additions and 95 deletions

View File

@ -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);
@ -1245,11 +1225,436 @@ cleanup_dst:
return FALSE;
}
static void
gen2_emit_composite_spans_vertex(struct sna *sna,
const struct sna_composite_spans_op *op,
int16_t x, int16_t y,
float opacity)
{
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_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_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
@ -1258,11 +1663,6 @@ gen2_render_flush(struct sna *sna)
gen2_vertex_flush(sna);
}
static void
gen2_render_fini(struct sna *sna)
{
}
Bool gen2_render_init(struct sna *sna)
{
struct sna_render *render = &sna->render;
@ -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;

View File

@ -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)

View File

@ -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);
}
}

View File

@ -236,6 +236,7 @@ struct sna_render {
};
struct gen2_render_state {
uint32_t target;
Bool need_invariant;
uint16_t vertex_offset;
};

View File

@ -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;