diff options
-rw-r--r-- | src/i830.h | 5 | ||||
-rw-r--r-- | src/i830_exa.c | 55 | ||||
-rw-r--r-- | src/i830_render.c | 118 | ||||
-rw-r--r-- | src/i915_render.c | 10 | ||||
-rw-r--r-- | src/i965_render.c | 42 |
5 files changed, 143 insertions, 87 deletions
@@ -524,6 +524,7 @@ typedef struct _I830Rec { float scale_units[2][2]; /** Transform pointers for src/mask, or NULL if identity */ PictTransform *transform[2]; + float coord_adjust; /* i915 EXA render state */ uint32_t mapstate[6]; uint32_t samplerstate[6]; @@ -827,11 +828,11 @@ Bool i965_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask, void i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h); -void +Bool i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, float *x_out, float *y_out); -void +Bool i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, float *x_out, float *y_out, float *z_out); diff --git a/src/i830_exa.c b/src/i830_exa.c index f9df277e..9b5bb936 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -339,12 +339,31 @@ I830EXADoneCopy(PixmapPtr pDstPixmap) #define xFixedToFloat(val) \ ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)) +static Bool +_i830_transform_point (PictTransformPtr transform, + float x, + float y, + float result[3]) +{ + int j; + + for (j = 0; j < 3; j++) + { + result[j] = (xFixedToFloat (transform->matrix[j][0]) * x + + xFixedToFloat (transform->matrix[j][1]) * y + + xFixedToFloat (transform->matrix[j][2])); + } + if (!result[2]) + return FALSE; + return TRUE; +} + /** * Returns the floating-point coordinates transformed by the given transform. * * transform may be null. */ -void +Bool i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, float *x_out, float *y_out) { @@ -352,15 +371,14 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, *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]); + float result[3]; + + if (!_i830_transform_point (transform, (float) x, (float) y, result)) + return FALSE; + *x_out = result[0] / result[2]; + *y_out = result[1] / result[2]; } + return TRUE; } /** @@ -368,7 +386,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, * * transform may be null. */ -void +Bool i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, float *x_out, float *y_out, float *w_out) { @@ -377,16 +395,15 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, *y_out = y; *w_out = 1; } else { - PictVector v; - - v.vector[0] = IntToxFixed(x); - v.vector[1] = IntToxFixed(y); - v.vector[2] = xFixed1; - PictureTransformPoint3d(transform, &v); - *x_out = xFixedToFloat(v.vector[0]); - *y_out = xFixedToFloat(v.vector[1]); - *w_out = xFixedToFloat(v.vector[2]); + float result[3]; + + if (!_i830_transform_point (transform, (float) x, (float) y, result)) + return FALSE; + *x_out = result[0]; + *y_out = result[1]; + *w_out = result[2]; } + return TRUE; } /** diff --git a/src/i830_render.c b/src/i830_render.c index 87543ef6..195e9a8c 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -396,6 +396,7 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, I830Ptr pI830 = I830PTR(pScrn); uint32_t dst_format, dst_offset, dst_pitch; Bool is_affine_src, is_affine_mask; + Bool is_nearest = FALSE; IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; @@ -407,9 +408,13 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, if (!i830_texture_setup(pSrcPicture, pSrc, 0)) I830FALLBACK("fail to setup src texture\n"); + if (pSrcPicture->filter == PictFilterNearest) + is_nearest = TRUE; if (pMask != NULL) { if (!i830_texture_setup(pMaskPicture, pMask, 1)) I830FALLBACK("fail to setup mask texture\n"); + if (pMaskPicture->filter == PictFilterNearest) + is_nearest = TRUE; } else { pI830->transform[1] = NULL; pI830->scale_units[1][0] = -1; @@ -419,6 +424,11 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, is_affine_src = i830_transform_is_affine (pI830->transform[0]); is_affine_mask = i830_transform_is_affine (pI830->transform[1]); + if (is_nearest) + pI830->coord_adjust = -0.125; + else + pI830->coord_adjust = 0; + if (!is_affine_src || !is_affine_mask) I830FALLBACK("non-affine transform unsupported on 8xx hardware\n"); @@ -591,56 +601,68 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, per_vertex = 2; /* dest x/y */ if (is_affine_src) { - 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 (!i830_get_transformed_coordinates(srcX, srcY, + pI830->transform[0], + &src_x[0], &src_y[0])) + return; + if (!i830_get_transformed_coordinates(srcX, srcY + h, + pI830->transform[0], + &src_x[1], &src_y[1])) + return; + if (!i830_get_transformed_coordinates(srcX + w, srcY + h, + pI830->transform[0], + &src_x[2], &src_y[2])) + return; 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]); + if (!i830_get_transformed_coordinates_3d(srcX, srcY, + pI830->transform[0], + &src_x[0], &src_y[0], + &src_w[0])) + return; + if (!i830_get_transformed_coordinates_3d(srcX, srcY + h, + pI830->transform[0], + &src_x[1], &src_y[1], + &src_w[1])) + return; + if (!i830_get_transformed_coordinates_3d(srcX + w, srcY + h, + pI830->transform[0], + &src_x[2], &src_y[2], + &src_w[2])) + return; 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]); + if (!i830_get_transformed_coordinates(maskX, maskY, + pI830->transform[1], + &mask_x[0], &mask_y[0])) + return; + if (!i830_get_transformed_coordinates(maskX, maskY + h, + pI830->transform[1], + &mask_x[1], &mask_y[1])) + return; + if (!i830_get_transformed_coordinates(maskX + w, maskY + h, + pI830->transform[1], + &mask_x[2], &mask_y[2])) + return; 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]); + if (!i830_get_transformed_coordinates_3d(maskX, maskY, + pI830->transform[1], + &mask_x[0], &mask_y[0], + &mask_w[0])) + return; + if (!i830_get_transformed_coordinates_3d(maskX, maskY + h, + pI830->transform[1], + &mask_x[1], &mask_y[1], + &mask_w[1])) + return; + if (!i830_get_transformed_coordinates_3d(maskX + w, maskY + h, + pI830->transform[1], + &mask_x[2], &mask_y[2], + &mask_w[2])) + return; per_vertex += 4; /* mask x/y/z/w */ } } @@ -655,8 +677,8 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 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(pI830->coord_adjust + dstX + w); + OUT_BATCH_F(pI830->coord_adjust + 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) { @@ -672,8 +694,8 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } } - OUT_BATCH_F(-0.125 + dstX); - OUT_BATCH_F(-0.125 + dstY + h); + OUT_BATCH_F(pI830->coord_adjust + dstX); + OUT_BATCH_F(pI830->coord_adjust + 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) { @@ -689,8 +711,8 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } } - OUT_BATCH_F(-0.125 + dstX); - OUT_BATCH_F(-0.125 + dstY); + OUT_BATCH_F(pI830->coord_adjust + dstX); + OUT_BATCH_F(pI830->coord_adjust + 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) { diff --git a/src/i915_render.c b/src/i915_render.c index 9c6da095..2b9ed04e 100644 --- a/src/i915_render.c +++ b/src/i915_render.c @@ -321,6 +321,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, int out_reg = FS_OC; FS_LOCALS(20); Bool is_affine_src, is_affine_mask; + Bool is_nearest = FALSE; IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; @@ -332,9 +333,13 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, if (!i915_texture_setup(pSrcPicture, pSrc, 0)) I830FALLBACK("fail to setup src texture\n"); + if (pSrcPicture->filter == PictFilterNearest) + is_nearest = TRUE; if (pMask != NULL) { if (!i915_texture_setup(pMaskPicture, pMask, 1)) I830FALLBACK("fail to setup mask texture\n"); + if (pMaskPicture->filter == PictFilterNearest) + is_nearest = TRUE; } else { pI830->transform[1] = NULL; pI830->scale_units[1][0] = -1; @@ -343,6 +348,11 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, is_affine_src = i830_transform_is_affine (pI830->transform[0]); is_affine_mask = i830_transform_is_affine (pI830->transform[1]); + if (is_nearest) + pI830->coord_adjust = -0.125; + else + pI830->coord_adjust = 0; + if (pMask == NULL) { BEGIN_BATCH(10); OUT_BATCH(_3DSTATE_MAP_STATE | 3); diff --git a/src/i965_render.c b/src/i965_render.c index ada3919a..93583b0a 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -1093,29 +1093,35 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, float src_x[3], src_y[3], mask_x[3], mask_y[3]; int i; - 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 (!i830_get_transformed_coordinates(srcX, srcY, + pI830->transform[0], + &src_x[0], &src_y[0])) + return; + if (!i830_get_transformed_coordinates(srcX, srcY + h, + pI830->transform[0], + &src_x[1], &src_y[1])) + return; + if (!i830_get_transformed_coordinates(srcX + w, srcY + h, + pI830->transform[0], + &src_x[2], &src_y[2])) + return; 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]); + if (!i830_get_transformed_coordinates(maskX, maskY, + pI830->transform[1], + &mask_x[0], &mask_y[0])) + return; + if (!i830_get_transformed_coordinates(maskX, maskY + h, + pI830->transform[1], + &mask_x[1], &mask_y[1])) + return; + if (!i830_get_transformed_coordinates(maskX + w, maskY + h, + pI830->transform[1], + &mask_x[2], &mask_y[2])) + return; } /* Wait for any existing composite rectangles to land before we overwrite |