summaryrefslogtreecommitdiff
path: root/src/i830_exa.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-01-30 16:34:50 -0800
committerEric Anholt <eric@anholt.net>2007-01-30 16:34:50 -0800
commit4cd552e8f4851e029e43bf778cd8340f6c2c4881 (patch)
tree9a8a411ba11f4dcf6685dc64cce9a4415e0ea04a /src/i830_exa.c
parent6a628ae12b0568d656059891c5bca4415d8a735f (diff)
Fix accelerated Render transformations.
Previously, we tried to use 2 points instead of 3 to describe the source rectangles, which mostly just worked for scaling.
Diffstat (limited to 'src/i830_exa.c')
-rw-r--r--src/i830_exa.c137
1 files changed, 72 insertions, 65 deletions
diff --git a/src/i830_exa.c b/src/i830_exa.c
index b976f548..b0d886b0 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -282,69 +282,76 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
#endif
}
+#define xFixedToFloat(val) \
+ ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
+
+/**
+ * Returns the floating-point coordinates transformed by the given transform.
+ *
+ * transform may be null.
+ */
+void
+i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
+ float *x_out, float *y_out)
+{
+ if (transform == NULL) {
+ *x_out = x;
+ *y_out = y;
+ } else {
+ PictVector v;
+
+ v.vector[0] = IntToxFixed(x);
+ v.vector[1] = IntToxFixed(y);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(transform, &v);
+ *x_out = xFixedToFloat(v.vector[0]);
+ *y_out = xFixedToFloat(v.vector[1]);
+ }
+}
+
+/**
+ * Do a single rectangle composite operation.
+ *
+ * This function is shared between i830 and i915 generation code.
+ */
static void
IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int w, int h)
{
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- int srcXend, srcYend, maskXend, maskYend;
- PictVector v;
- int pMask = 1;
-
- DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
- "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
- "src_scale_x %f, src_scale_y %f, "
- "mask_scale_x %f, mask_scale_y %f\n",
- srcX, srcY, maskX, maskY, dstX, dstY, w, h,
- pI830->scale_units[0][0], pI830->scale_units[0][1],
- pI830->scale_units[1][0], pI830->scale_units[1][1]);
+ 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]);
if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) {
- pMask = 0;
- }
-
- srcXend = srcX + w;
- srcYend = srcY + h;
- maskXend = maskX + w;
- maskYend = maskY + h;
- if (pI830->transform[0] != NULL) {
- v.vector[0] = IntToxFixed(srcX);
- v.vector[1] = IntToxFixed(srcY);
- v.vector[2] = xFixed1;
- PictureTransformPoint(pI830->transform[0], &v);
- srcX = xFixedToInt(v.vector[0]);
- srcY = xFixedToInt(v.vector[1]);
- v.vector[0] = IntToxFixed(srcXend);
- v.vector[1] = IntToxFixed(srcYend);
- v.vector[2] = xFixed1;
- PictureTransformPoint(pI830->transform[0], &v);
- srcXend = xFixedToInt(v.vector[0]);
- srcYend = xFixedToInt(v.vector[1]);
- }
- if (pI830->transform[1] != NULL) {
- v.vector[0] = IntToxFixed(maskX);
- v.vector[1] = IntToxFixed(maskY);
- v.vector[2] = xFixed1;
- PictureTransformPoint(pI830->transform[1], &v);
- maskX = xFixedToInt(v.vector[0]);
- maskY = xFixedToInt(v.vector[1]);
- v.vector[0] = IntToxFixed(maskXend);
- v.vector[1] = IntToxFixed(maskYend);
- v.vector[2] = xFixed1;
- PictureTransformPoint(pI830->transform[1], &v);
- maskXend = xFixedToInt(v.vector[0]);
- maskYend = xFixedToInt(v.vector[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]);
}
- DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
- "maskX %d, maskY %d, maskXend %d, maskYend %d\n\t"
- "dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
- maskX, maskY, maskXend, maskYend, dstX, dstY);
{
int vertex_count;
- if (pMask)
+ if (has_mask)
vertex_count = 3*6;
else
vertex_count = 3*4;
@@ -361,29 +368,29 @@ IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
OUT_RING_F(dstX);
OUT_RING_F(dstY);
- OUT_RING_F(srcX / pI830->scale_units[0][0]);
- OUT_RING_F(srcY / pI830->scale_units[0][1]);
- if (pMask) {
- OUT_RING_F(maskX / pI830->scale_units[1][0]);
- OUT_RING_F(maskY / pI830->scale_units[1][1]);
+ OUT_RING_F(src_x[0] / pI830->scale_units[0][0]);
+ OUT_RING_F(src_y[0] / pI830->scale_units[0][1]);
+ if (has_mask) {
+ OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]);
+ OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]);
}
OUT_RING_F(dstX);
OUT_RING_F(dstY + h);
- OUT_RING_F(srcX / pI830->scale_units[0][0]);
- OUT_RING_F(srcYend / pI830->scale_units[0][1]);
- if (pMask) {
- OUT_RING_F(maskX / pI830->scale_units[1][0]);
- OUT_RING_F(maskYend / pI830->scale_units[1][1]);
+ OUT_RING_F(src_x[1] / pI830->scale_units[0][0]);
+ OUT_RING_F(src_y[1] / pI830->scale_units[0][1]);
+ if (has_mask) {
+ OUT_RING_F(mask_x[1] / pI830->scale_units[1][0]);
+ OUT_RING_F(mask_y[1] / pI830->scale_units[1][1]);
}
OUT_RING_F(dstX + w);
OUT_RING_F(dstY + h);
- OUT_RING_F(srcXend / pI830->scale_units[0][0]);
- OUT_RING_F(srcYend / pI830->scale_units[0][1]);
- if (pMask) {
- OUT_RING_F(maskXend / pI830->scale_units[1][0]);
- OUT_RING_F(maskYend / pI830->scale_units[1][1]);
+ OUT_RING_F(src_x[2] / pI830->scale_units[0][0]);
+ OUT_RING_F(src_y[2] / pI830->scale_units[0][1]);
+ if (has_mask) {
+ OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]);
+ OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]);
}
ADVANCE_LP_RING();
}