summaryrefslogtreecommitdiff
path: root/src/i830_render.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-03-18 14:08:19 -0700
committerKeith Packard <keithp@keithp.com>2008-03-18 14:19:12 -0700
commit4b9b7b007d729f94b01b0031d8ae478134b501da (patch)
tree6bc0a712f35720a9d83a2972d08cb6190862656f /src/i830_render.c
parentf699389818f1f11f3edddcdddcd0a43be21ba4c0 (diff)
Handle projective transforms on 9xx for Composite.
Projective transforms require un-normalized texture coordinates and the use of the texldp instruction. The coordinates are passed as x/y/z/w (the z is unused, but there isn't a vertext format for just x/y/w).
Diffstat (limited to 'src/i830_render.c')
-rw-r--r--src/i830_render.c183
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();
}
/**