diff options
Diffstat (limited to 'src/i830_render.c')
-rw-r--r-- | src/i830_render.c | 183 |
1 files changed, 124 insertions, 59 deletions
diff --git a/src/i830_render.c b/src/i830_render.c index 78ae40a0..87543ef6 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -395,6 +395,7 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); uint32_t dst_format, dst_offset, dst_pitch; + Bool is_affine_src, is_affine_mask; IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; @@ -415,6 +416,12 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, pI830->scale_units[1][1] = -1; } + is_affine_src = i830_transform_is_affine (pI830->transform[0]); + is_affine_mask = i830_transform_is_affine (pI830->transform[1]); + + if (!is_affine_src || !is_affine_mask) + I830FALLBACK("non-affine transform unsupported on 8xx hardware\n"); + { uint32_t cblend, ablend, blendctl, vf2; @@ -556,7 +563,6 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, return TRUE; } - /** * Do a single rectangle composite operation. * @@ -569,79 +575,138 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); Bool has_mask; - float src_x[3], src_y[3], mask_x[3], mask_y[3]; - - i830_get_transformed_coordinates(srcX, srcY, - pI830->transform[0], - &src_x[0], &src_y[0]); - i830_get_transformed_coordinates(srcX, srcY + h, - pI830->transform[0], - &src_x[1], &src_y[1]); - i830_get_transformed_coordinates(srcX + w, srcY + h, - pI830->transform[0], - &src_x[2], &src_y[2]); + Bool is_affine_src, is_affine_mask; + int per_vertex, num_floats; + float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; + + is_affine_src = i830_transform_is_affine (pI830->transform[0]); + is_affine_mask = i830_transform_is_affine (pI830->transform[1]); if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) { has_mask = FALSE; } else { has_mask = TRUE; - i830_get_transformed_coordinates(maskX, maskY, - pI830->transform[1], - &mask_x[0], &mask_y[0]); - i830_get_transformed_coordinates(maskX, maskY + h, - pI830->transform[1], - &mask_x[1], &mask_y[1]); - i830_get_transformed_coordinates(maskX + w, maskY + h, - pI830->transform[1], - &mask_x[2], &mask_y[2]); } + per_vertex = 2; /* dest x/y */ + if (is_affine_src) { - int vertex_count; - - if (has_mask) - vertex_count = 3*6; - else - vertex_count = 3*4; - - BEGIN_BATCH(6+vertex_count); - - OUT_BATCH(MI_NOOP); - OUT_BATCH(MI_NOOP); - OUT_BATCH(MI_NOOP); - OUT_BATCH(MI_NOOP); - OUT_BATCH(MI_NOOP); - - OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1)); + i830_get_transformed_coordinates(srcX, srcY, + pI830->transform[0], + &src_x[0], &src_y[0]); + i830_get_transformed_coordinates(srcX, srcY + h, + pI830->transform[0], + &src_x[1], &src_y[1]); + i830_get_transformed_coordinates(srcX + w, srcY + h, + pI830->transform[0], + &src_x[2], &src_y[2]); + per_vertex += 2; /* src x/y */ + } else { + i830_get_transformed_coordinates_3d(srcX, srcY, + pI830->transform[0], + &src_x[0], &src_y[0], + &src_w[0]); + i830_get_transformed_coordinates_3d(srcX, srcY + h, + pI830->transform[0], + &src_x[1], &src_y[1], + &src_w[1]); + i830_get_transformed_coordinates_3d(srcX + w, srcY + h, + pI830->transform[0], + &src_x[2], &src_y[2], + &src_w[2]); + per_vertex += 4; /* src x/y/z/w */ + } + if (has_mask) { + if (is_affine_mask) { + i830_get_transformed_coordinates(maskX, maskY, + pI830->transform[1], + &mask_x[0], &mask_y[0]); + i830_get_transformed_coordinates(maskX, maskY + h, + pI830->transform[1], + &mask_x[1], &mask_y[1]); + i830_get_transformed_coordinates(maskX + w, maskY + h, + pI830->transform[1], + &mask_x[2], &mask_y[2]); + per_vertex += 2; /* mask x/y */ + } else { + i830_get_transformed_coordinates_3d(maskX, maskY, + pI830->transform[1], + &mask_x[0], &mask_y[0], + &mask_w[0]); + i830_get_transformed_coordinates_3d(maskX, maskY + h, + pI830->transform[1], + &mask_x[1], &mask_y[1], + &mask_w[1]); + i830_get_transformed_coordinates_3d(maskX + w, maskY + h, + pI830->transform[1], + &mask_x[2], &mask_y[2], + &mask_w[2]); + per_vertex += 4; /* mask x/y/z/w */ + } + } - OUT_BATCH_F(-0.125 + dstX + w); - OUT_BATCH_F(-0.125 + dstY + h); - OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]); - OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]); - if (has_mask) { - OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]); - OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]); + num_floats = 3 * per_vertex; + BEGIN_BATCH(6 + num_floats); + + OUT_BATCH(MI_NOOP); + OUT_BATCH(MI_NOOP); + OUT_BATCH(MI_NOOP); + OUT_BATCH(MI_NOOP); + OUT_BATCH(MI_NOOP); + + OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (num_floats-1)); + OUT_BATCH_F(-0.125 + dstX + w); + OUT_BATCH_F(-0.125 + dstY + h); + OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]); + OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]); + if (!is_affine_src) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(src_w[2]); + } + if (has_mask) { + OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]); + OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]); + if (!is_affine_mask) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(mask_w[2]); } + } - OUT_BATCH_F(-0.125 + dstX); - OUT_BATCH_F(-0.125 + dstY + h); - OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]); - OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]); - if (has_mask) { - OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]); - OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]); + OUT_BATCH_F(-0.125 + dstX); + OUT_BATCH_F(-0.125 + dstY + h); + OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]); + OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]); + if (!is_affine_src) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(src_w[1]); + } + if (has_mask) { + OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]); + OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]); + if (!is_affine_mask) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(mask_w[1]); } + } - OUT_BATCH_F(-0.125 + dstX); - OUT_BATCH_F(-0.125 + dstY); - OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]); - OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]); - if (has_mask) { - OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]); - OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]); + OUT_BATCH_F(-0.125 + dstX); + OUT_BATCH_F(-0.125 + dstY); + OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]); + OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]); + if (!is_affine_src) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(src_w[0]); + } + if (has_mask) { + OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]); + OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]); + if (!is_affine_mask) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(mask_w[0]); } - ADVANCE_BATCH(); } + + ADVANCE_BATCH(); } /** |