xf86-video-intel: 4 commits - src/i830_exa.c src/i830.h src/i830_render.c src/i915_3d.h src/i915_reg.h src/i915_render.c src/i965_render.c

Keith Packard keithp at kemper.freedesktop.org
Tue Mar 18 14:18:05 PDT 2008


 src/i830.h        |    7 ++
 src/i830_exa.c    |   39 +++++++++++
 src/i830_render.c |  185 ++++++++++++++++++++++++++++++++++++------------------
 src/i915_3d.h     |    5 +
 src/i915_reg.h    |   10 ++
 src/i915_render.c |   22 ++++--
 src/i965_render.c |    2 
 7 files changed, 204 insertions(+), 66 deletions(-)

New commits:
commit 4b9b7b007d729f94b01b0031d8ae478134b501da
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 14:08:19 2008 -0700

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

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 0206ab9..f9df277 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -363,7 +363,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
     }
 }
 
-**
+/**
  * Returns the un-normalized floating-point coordinates transformed by the given transform.
  *
  * transform may be null.
diff --git a/src/i830_render.c b/src/i830_render.c
index 78ae40a..87543ef 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();
 }
 
 /**
diff --git a/src/i915_3d.h b/src/i915_3d.h
index c2efe9a..1a0bd45 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -236,6 +236,11 @@ do {									\
      FS_OUT(_i915_fs_texld(T0_TEXLD, dest_reg, sampler_reg, address_reg)); \
 } while (0)
 
+#define i915_fs_texldp(dest_reg, sampler_reg, address_reg)		\
+do {									\
+     FS_OUT(_i915_fs_texld(T0_TEXLDP, dest_reg, sampler_reg, address_reg)); \
+} while (0)
+
 static inline struct i915_fs_op
 _i915_fs_texld(int load_op, int dest_reg, int sampler_reg, int address_reg)
 {
diff --git a/src/i915_render.c b/src/i915_render.c
index 8ac1b78..9c6da09 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -320,6 +320,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
     uint32_t blendctl;
     int out_reg = FS_OC;
     FS_LOCALS(20);
+    Bool is_affine_src, is_affine_mask;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -339,6 +340,8 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	pI830->scale_units[1][0] = -1;
 	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 (pMask == NULL) {
 	BEGIN_BATCH(10);
@@ -389,9 +392,9 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 
 	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 		  I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
-	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+	ss2 = S2_TEXCOORD_FMT(0, is_affine_src ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
 	if (pMask)
-		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+		ss2 |= S2_TEXCOORD_FMT(1, is_affine_mask ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
 	else
 		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
 	ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
@@ -435,7 +438,12 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	i915_fs_dcl(FS_T1);
 
     /* Load the pSrcPicture texel */
-    i915_fs_texld(FS_R0, FS_S0, FS_T0);
+    if (is_affine_src) {
+	i915_fs_texld(FS_R0, FS_S0, FS_T0);
+    } else {
+	i915_fs_texldp(FS_R0, FS_S0, FS_T0);
+    }
+
     /* If the texture lacks an alpha channel, force the alpha to 1. */
     if (PICT_FORMAT_A(pSrcPicture->format) == 0)
 	i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
@@ -445,7 +453,11 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	i915_fs_mov(out_reg, i915_fs_operand_reg(FS_R0));
     } else {
 	/* Load the pMaskPicture texel */
-	i915_fs_texld(FS_R1, FS_S1, FS_T1);
+	if (is_affine_mask) {
+	    i915_fs_texld(FS_R1, FS_S1, FS_T1);
+	} else {
+	    i915_fs_texldp(FS_R1, FS_S1, FS_T1);
+	}
 	/* If the texture lacks an alpha channel, force the alpha to 1. */
 	if (PICT_FORMAT_A(pMaskPicture->format) == 0)
 	    i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
commit f699389818f1f11f3edddcdddcd0a43be21ba4c0
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 14:06:47 2008 -0700

    Add i830_transform_is_affine and i830_get_transformed_coordinates_3d.
    
    These are needed to deal with projective transforms in the composite
    operation.

diff --git a/src/i830.h b/src/i830.h
index ee0f03a..512938c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -790,6 +790,9 @@ Bool i830_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 Bool i830_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 			    PicturePtr pDst, PixmapPtr pSrcPixmap,
 			    PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+Bool
+i830_transform_is_affine (PictTransformPtr t);
+
 void i830_composite(PixmapPtr pDst, int srcX, int srcY,
 		    int maskX, int maskY, int dstX, int dstY, int w, int h);
 void i830_done_composite(PixmapPtr pDst);
@@ -812,6 +815,10 @@ void
 i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
 				 float *x_out, float *y_out);
 
+void
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+				    float *x_out, float *y_out, float *z_out);
+
 void i830_enter_render(ScrnInfoPtr);
 
 static inline int i830_fb_compression_supported(I830Ptr pI830)
diff --git a/src/i830_exa.c b/src/i830_exa.c
index bf9fc66..0206ab9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -363,6 +363,45 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
     }
 }
 
+**
+ * Returns the un-normalized floating-point coordinates transformed by the given transform.
+ *
+ * transform may be null.
+ */
+void
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+				    float *x_out, float *y_out, float *w_out)
+{
+    if (transform == NULL) {
+	*x_out = x;
+	*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]);
+    }
+}
+
+/**
+ * Returns whether the provided transform is affine.
+ *
+ * transform may be null.
+ */
+Bool
+i830_transform_is_affine (PictTransformPtr t)
+{
+    if (t == NULL)
+	return TRUE;
+    return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
+}
+
 /*
  * TODO:
  *   - Dual head?
commit a55974b435224fe5726fa44298d051c71e4056a5
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 13:47:20 2008 -0700

    Add defines for 9xx S3 word in 3D_STATE_LOAD_STATE_IMMEDIATE
    
    These aren't used at this point, but what the heck.

diff --git a/src/i915_reg.h b/src/i915_reg.h
index 682a157..4340de9 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -360,6 +360,16 @@
 #define S2_TEXCOORD_FMT(unit, type)    ((type)<<(unit*4))
 #define S2_TEXCOORD_NONE               (~0)
 
+#define TEXCOORD_WRAP_SHORTEST_TCX	8
+#define TEXCOORD_WRAP_SHORTEST_TCY	4
+#define TEXCOORD_WRAP_SHORTEST_TCZ	2
+#define TEXCOORD_PERSPECTIVE_DISABLE	1
+
+#define S3_WRAP_SHORTEST_TCX(unit)	(TEXCOORD_WRAP_SHORTEST_TCX << ((unit) * 4))
+#define S3_WRAP_SHORTEST_TCY(unit)	(TEXCOORD_WRAP_SHORTEST_TCY << ((unit) * 4))
+#define S3_WRAP_SHORTEST_TCZ(unit)	(TEXCOORD_WRAP_SHORTEST_TCZ << ((unit) * 4))
+#define S3_PERSPECTIVE_DISABLE(unit)	(TEXCOORD_PERSPECTIVE_DISABLE << ((unit) * 4))
+
 /* S3 not interesting */
 
 #define S4_POINT_WIDTH_SHIFT           23
commit 4f5500abe209b92b39ae1f2d7a1118362ac95034
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 13:45:46 2008 -0700

    8xx/9xx can handle textures to 2kx2k. 965 can do 8kx8k

diff --git a/src/i830_render.c b/src/i830_render.c
index 949c700..78ae40a 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -231,7 +231,7 @@ static Bool i830_check_composite_texture(PicturePtr pPict, int unit)
     int h = pPict->pDrawable->height;
     int i;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if ((w > 2048) || (h > 2048))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
     for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
diff --git a/src/i915_render.c b/src/i915_render.c
index b15beef..8ac1b78 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -188,7 +188,7 @@ static Bool i915_check_composite_texture(PicturePtr pPict, int unit)
     int h = pPict->pDrawable->height;
     int i;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if ((w > 2048) || (h > 2048))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
     for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
diff --git a/src/i965_render.c b/src/i965_render.c
index 7f798e6..ada3919 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -182,7 +182,7 @@ static Bool i965_check_composite_texture(PicturePtr pPict, int unit)
     int h = pPict->pDrawable->height;
     int i;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if ((w > 8192) || (h > 8192))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
     for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);


More information about the xorg-commit mailing list