xf86-video-intel: Branch 'exa' - 14 commits - src/i830_driver.c src/i830.h src/i830_rotate.c src/i915_3d.c src/i915_3d.h src/i915_exa_render.c src/i915_reg.h src/Makefile.am

Eric Anholt anholt at kemper.freedesktop.org
Wed Jul 19 13:28:46 PDT 2006


 src/Makefile.am       |    1 
 src/i830.h            |    2 
 src/i830_driver.c     |    2 
 src/i830_rotate.c     |  173 ++++++++++++-------
 src/i915_3d.c         |    4 
 src/i915_3d.h         |  448 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i915_exa_render.c |  225 ++++++++-----------------
 src/i915_reg.h        |   17 +
 8 files changed, 661 insertions(+), 211 deletions(-)

New commits:
diff-tree 36aa43bf73ee1268f0a250788eb637a4123f08eb (from adce6bd0fc9533156da09da7d029ba0d76606b4f)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 16:22:46 2006 -0400

    Force texture alpha channels to 1 if not present.

diff --git a/src/i915_3d.h b/src/i915_3d.h
index e9b0194..5a45882 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -350,8 +350,16 @@ _i915_fs_arith(int cmd, int dest_reg,
     return op;
 }
 
+/** Move operand0 to dest_reg */
+#define i915_fs_mov(dest_reg, operand0)					\
+do {									\
+    FS_OUT(i915_fs_arith(MOV, dest_reg, operand0,			\
+			 i915_fs_operand_none(),			\
+			 i915_fs_operand_none()));			\
+} while (0)
+
 /**
- * Move the values in operand0 to the dest reg with the masking/saturation
+ * Move the value in operand0 to the dest reg with the masking/saturation
  * specified.
  */
 #define i915_fs_mov_masked(dest_reg, dest_mask, operand0)		\
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 0b20e66..a570382 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -422,36 +422,40 @@ ErrorF("i915 prepareComposite\n");
 	ADVANCE_LP_RING();
     }
 
-	/* For (src In mask) operation */
-	/* IN operator: Multiply src by mask components or mask alpha.*/
-	/* TEXBLENDOP_MODULE: arg1*arg2 */
-
-	/* LOAD_IMMEDIATE_1 ss6 ??*/
-
-	/****
-	   shader program prototype:
-		dcl t0.xy
-		dcl t1.xy
-		dcl_2d s0   
-		dcl_2d s1
-		texld t0, s0
-		texld t1, s1
-		mul oC, t0, t1 ()
-	***/
     FS_BEGIN();
 
-    if (!pMask) {
-	i915_fs_dcl(FS_S0);
-	i915_fs_dcl(FS_T0);
-	i915_fs_texld(FS_OC, FS_S0, FS_T0);
-    } else {
-	i915_fs_dcl(FS_S0);
+    /* Declare the registers necessary for our program.  I don't think the
+     * S then T ordering is necessary.
+     */
+    i915_fs_dcl(FS_S0);
+    if (pMask)
 	i915_fs_dcl(FS_S1);
-	i915_fs_dcl(FS_T0);
+    i915_fs_dcl(FS_T0);
+    if (pMask)
 	i915_fs_dcl(FS_T1);
-	i915_fs_texld(FS_R0, FS_S0, FS_T0);
-	i915_fs_texld(FS_R1, FS_S1, FS_T1);
 
+    /* Load the pSrcPicture texel */
+    i915_fs_texld(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());
+
+    if (!pMask) {
+	/* No mask, so move to output color */
+	i915_fs_mov(FS_OC, i915_fs_operand_reg(FS_R0));
+    } else {
+	/* Load the pMaskPicture texel */
+	i915_fs_texld(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());
+
+	/* If component alpha is set in the mask, then we need to provide
+	 * the source alpha component (channelwise multiplication) as the
+	 * output color.  If it isn't set, then we need to provide the
+	 * source value component, which is the multipliction of the source
+	 * by the mask alpha.
+	 */
 	if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
 	    i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
 			i915_fs_operand_reg(FS_R1));
diff-tree adce6bd0fc9533156da09da7d029ba0d76606b4f (from 4e409ea44180f7ef2780d70c9d2f54629bbd0fc3)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 16:21:49 2006 -0400

    Add a trailing MI_NOOP to frag shader output for alignment if necessary.

diff --git a/src/i915_3d.h b/src/i915_3d.h
index f254c86..e9b0194 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -434,5 +434,7 @@ do {									\
 	     (_cur_shader_commands * 3 - 1));				\
     for (_i = 0; _i < _cur_shader_commands * 3; _i++)			\
 	OUT_RING(_shader_buf[_i]);					\
+    if ((_cur_shader_commands & 0x1) == 0)				\
+	OUT_RING(MI_NOOP);						\
     ADVANCE_LP_RING();							\
 } while (0);
diff-tree 4e409ea44180f7ef2780d70c9d2f54629bbd0fc3 (from 449e4be503c8b938d5bd46ee810244f8bcf54ceb)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 15:57:09 2006 -0400

    The map bits per pixel must come from the drawable, not the visible screen.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 181fb89..0b20e66 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -260,9 +260,9 @@ I915TextureSetup(PicturePtr pPict, Pixma
 
     {
 	CARD32 ms3;
-	if (pI830->cpp == 1)
+	if (pPix->drawable.bitsPerPixel == 8)
 		format |= MAPSURF_8BIT;
-	else if (pI830->cpp == 2)
+	else if (pPix->drawable.bitsPerPixel == 16)
 		format |= MAPSURF_16BIT;
 	else
 		format |= MAPSURF_32BIT;
diff-tree 449e4be503c8b938d5bd46ee810244f8bcf54ceb (from f1b62d890ca22e12d61f7ef67bc4e35d68cde019)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 13:34:06 2006 -0400

    Correct the DWORD count of several 3D instructions.

diff --git a/src/i915_3d.c b/src/i915_3d.c
index d8edb18..942dbd1 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -77,9 +77,7 @@ void I915EmitInvarientState( ScrnInfoPtr
 
    /* Need to initialize this to zero.
     */
-   OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 
-	     I1_LOAD_S(3) |
-	     (1));
+   OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
    OUT_RING(0);
  
    /* XXX: Use this */
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 4249869..181fb89 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -268,7 +268,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
 		format |= MAPSURF_32BIT;
 
 	BEGIN_LP_RING(6);
-	OUT_RING(_3DSTATE_MAP_STATE | (3 * (1 << unit)));
+	OUT_RING(_3DSTATE_MAP_STATE | 3);
 	OUT_RING(1<<unit);
 	OUT_RING(offset&MS2_ADDRESS_MASK);
 	ms3 = (pPix->drawable.height << MS3_HEIGHT_SHIFT) | 
@@ -286,7 +286,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
 	BEGIN_LP_RING(6);
 	/* max & min mip level ? or base mip level? */
 
-	OUT_RING(_3DSTATE_SAMPLER_STATE | (3*(1<<unit)));
+	OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
 	OUT_RING(1<<unit);
 	ss2 = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
 	ss2 |= filter;
@@ -390,8 +390,8 @@ ErrorF("i915 prepareComposite\n");
 	OUT_RING(0);
 	
 	/* XXX:S3? define vertex format with tex coord sets number*/
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(2)|I1_LOAD_S(3)|
-		I1_LOAD_S(4)|3);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
+		 I1_LOAD_S(3) | I1_LOAD_S(4) | 2);
 	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
 	if (pMask)
 		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
@@ -467,7 +467,7 @@ ErrorF("i915 prepareComposite\n");
 	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
 
 	BEGIN_LP_RING(2);
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 1);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
 	ss6 = S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE;
 	OUT_RING(ss6 | (0 << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
 	ADVANCE_LP_RING();
diff-tree f1b62d890ca22e12d61f7ef67bc4e35d68cde019 (from 76a316d0cec92a04c8735926a76e76c21f960d7e)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 13:02:24 2006 -0400

    Replace hand register setting with new i915 fragmet program API.

diff --git a/src/i915_3d.h b/src/i915_3d.h
index fc4ca60..f254c86 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -375,6 +375,13 @@ do {									\
 			 i915_fs_operand_none()));			\
 } while (0)
 
+/** Add operand0 and operand1 and put the result in dest_reg */
+#define i915_fs_mul(dest_reg, operand0, operand1)			\
+do {									\
+    FS_OUT(i915_fs_arith(MUL, dest_reg, operand0, operand1,		\
+			 i915_fs_operand_none()));			\
+} while (0)
+
 /**
  * Perform a 3-component dot-product of operand0 and operand1 and put the
  * resulting scalar in the channels of dest_reg specified by the dest_mask.
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 60b8125..4249869 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -1,3 +1,5 @@
+/* -*- c-basic-offset: 4 -*- */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -5,6 +7,7 @@
 #include "xf86.h"
 #include "i830.h"
 #include "i915_reg.h"
+#include "i915_3d.h"
 
 #ifdef I830DEBUG
 #define DEBUG_I830FALLBACK 1
@@ -36,7 +39,8 @@ struct formatinfo {
 struct blendinfo {
     Bool dst_alpha;
     Bool src_alpha;
-    CARD32 blend_cntl;
+    CARD32 src_blend;
+    CARD32 dst_blend;
 };
 
 extern Bool
@@ -48,96 +52,33 @@ I915EXAPrepareComposite(int op, PictureP
 			PicturePtr pMaskPicture, PicturePtr pDstPicture,
 			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
 
-/* copy from Eric's texture-video branch, move to header.. */
-#define OUT_DCL(type, nr) do {                                          \
-   CARD32 chans = 0;                                                    \
-   if (REG_TYPE_##type == REG_TYPE_T)                                   \
-      chans = D0_CHANNEL_ALL;                                           \
-   else if (REG_TYPE_##type != REG_TYPE_S)                              \
-      FatalError("wrong reg type %d to declare\n", REG_TYPE_##type);    \
-   OUT_RING(D0_DCL |                                                    \
-            (REG_TYPE_##type << D0_TYPE_SHIFT) | (nr << D0_NR_SHIFT) |  \
-            chans);                                                     \
-   OUT_RING(0x00000000);                                                \
-   OUT_RING(0x00000000);                                                \
-} while (0)
-
-#define OUT_TEXLD(dest_type, dest_nr, sampler_nr, addr_type, addr_nr)   \
-do {                                                                    \
-      OUT_RING(T0_TEXLD |                                               \
-               (REG_TYPE_##dest_type << T0_DEST_TYPE_SHIFT) |           \
-               (dest_nr << T0_DEST_NR_SHIFT) |                          \
-               (sampler_nr << T0_SAMPLER_NR_SHIFT));                    \
-      OUT_RING((REG_TYPE_##addr_type << T1_ADDRESS_REG_TYPE_SHIFT) |    \
-               (addr_nr << T1_ADDRESS_REG_NR_SHIFT));                   \
-      OUT_RING(0x00000000);                                             \
-} while (0)
-
-/* XXX: It seems that offset of 915's blendfactor in Load_immediate_1
-   is _different_ with i830, so I should just define plain value
-   and use it with shift bits*/
-
-#define I915_SRC_BLENDFACTOR_ZERO 		(1 << 8)
-#define I915_SRC_BLENDFACTOR_ONE 		(2 << 8)
-#define I915_SRC_BLENDFACTOR_SRC_COLOR		(3 << 8)
-#define I915_SRC_BLENDFACTOR_INV_SRC_COLOR	(4 << 8)
-#define I915_SRC_BLENDFACTOR_SRC_ALPHA		(5 << 8)
-#define I915_SRC_BLENDFACTOR_INV_SRC_ALPHA	(6 << 8)
-#define I915_SRC_BLENDFACTOR_DST_ALPHA		(7 << 8)
-#define I915_SRC_BLENDFACTOR_INV_DST_ALPHA	(8 << 8)
-#define I915_SRC_BLENDFACTOR_DST_COLOR		(9 << 8)
-#define I915_SRC_BLENDFACTOR_INV_DST_COLOR	(0xa << 8)
-#define I915_SRC_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 8)
-#define I915_SRC_BLENDFACTOR_CONST_COLOR	(0xc << 8)
-#define I915_SRC_BLENDFACTOR_INV_CONST_COLOR	(0xd << 8)
-#define I915_SRC_BLENDFACTOR_CONST_ALPHA	(0xe << 8)
-#define I915_SRC_BLENDFACTOR_INV_CONST_ALPHA	(0xf << 8)
-#define I915_SRC_BLENDFACTOR_MASK		(0xf << 8)
-
-#define I915_DST_BLENDFACTOR_ZERO 		(1 << 4)
-#define I915_DST_BLENDFACTOR_ONE 		(2 << 4)
-#define I915_DST_BLENDFACTOR_SRC_COLOR		(3 << 4)
-#define I915_DST_BLENDFACTOR_INV_SRC_COLOR	(4 << 4)
-#define I915_DST_BLENDFACTOR_SRC_ALPHA		(5 << 4)
-#define I915_DST_BLENDFACTOR_INV_SRC_ALPHA	(6 << 4)
-#define I915_DST_BLENDFACTOR_DST_ALPHA		(7 << 4)
-#define I915_DST_BLENDFACTOR_INV_DST_ALPHA	(8 << 4)
-#define I915_DST_BLENDFACTOR_DST_COLOR		(9 << 4)
-#define I915_DST_BLENDFACTOR_INV_DST_COLOR	(0xa << 4)
-#define I915_DST_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 4)
-#define I915_DST_BLENDFACTOR_CONST_COLOR	(0xc << 4)
-#define I915_DST_BLENDFACTOR_INV_CONST_COLOR	(0xd << 4)
-#define I915_DST_BLENDFACTOR_CONST_ALPHA	(0xe << 4)
-#define I915_DST_BLENDFACTOR_INV_CONST_ALPHA	(0xf << 4)
-#define I915_DST_BLENDFACTOR_MASK		(0xf << 4)
-
 static struct blendinfo I915BlendOp[] = { 
     /* Clear */
-    {0, 0, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_ZERO},
+    {0, 0, BLENDFACT_ZERO,          BLENDFACT_ZERO},
     /* Src */
-    {0, 0, I915_SRC_BLENDFACTOR_ONE            | I915_DST_BLENDFACTOR_ZERO},
+    {0, 0, BLENDFACT_ONE,           BLENDFACT_ZERO},
     /* Dst */
-    {0, 0, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_ONE},
+    {0, 0, BLENDFACT_ZERO,          BLENDFACT_ONE},
     /* Over */
-    {0, 1, I915_SRC_BLENDFACTOR_ONE            | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {0, 1, BLENDFACT_ONE,           BLENDFACT_INV_SRC_ALPHA},
     /* OverReverse */
-    {1, 0, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_ONE},
+    {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
     /* In */
-    {1, 0, I915_SRC_BLENDFACTOR_DST_ALPHA     | I915_DST_BLENDFACTOR_ZERO},
+    {1, 0, BLENDFACT_DST_ALPHA,     BLENDFACT_ZERO},
     /* InReverse */
-    {0, 1, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_SRC_ALPHA},
+    {0, 1, BLENDFACT_ZERO,          BLENDFACT_SRC_ALPHA},
     /* Out */
-    {1, 0, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_ZERO},
+    {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
     /* OutReverse */
-    {0, 1, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {0, 1, BLENDFACT_ZERO,          BLENDFACT_INV_SRC_ALPHA},
     /* Atop */
-    {1, 1, I915_SRC_BLENDFACTOR_DST_ALPHA     | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {1, 1, BLENDFACT_DST_ALPHA,     BLENDFACT_INV_SRC_ALPHA},
     /* AtopReverse */
-    {1, 1, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_SRC_ALPHA},
+    {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
     /* Xor */
-    {1, 1, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
     /* Add */
-    {0, 0, I915_SRC_BLENDFACTOR_ONE            | I915_DST_BLENDFACTOR_ONE},
+    {0, 0, BLENDFACT_ONE,           BLENDFACT_ONE},
 };
 
 static struct formatinfo I915TexFormats[] = {
@@ -155,17 +96,17 @@ static CARD32 I915GetBlendCntl(int op, P
 {
     CARD32 sblend, dblend;
 
-    sblend = I915BlendOp[op].blend_cntl & I915_SRC_BLENDFACTOR_MASK;
-    dblend = I915BlendOp[op].blend_cntl & I915_DST_BLENDFACTOR_MASK;
+    sblend = I915BlendOp[op].src_blend;
+    dblend = I915BlendOp[op].dst_blend;
 
     /* If there's no dst alpha channel, adjust the blend op so that we'll treat
      * it as always 1.
      */
     if (PICT_FORMAT_A(dst_format) == 0 && I915BlendOp[op].dst_alpha) {
-        if (sblend == I915_SRC_BLENDFACTOR_DST_ALPHA)
-            sblend = I915_SRC_BLENDFACTOR_ONE;
-        else if (sblend == I915_SRC_BLENDFACTOR_INV_DST_ALPHA)
-            sblend = I915_SRC_BLENDFACTOR_ZERO;
+        if (sblend == BLENDFACT_DST_ALPHA)
+            sblend = BLENDFACT_ONE;
+        else if (sblend == BLENDFACT_INV_DST_ALPHA)
+            sblend = BLENDFACT_ZERO;
     }
 
     /* If the source alpha is being used, then we should only be in a case where
@@ -173,14 +114,15 @@ static CARD32 I915GetBlendCntl(int op, P
      * channels multiplied by the source picture's alpha.
      */
     if (pMask && pMask->componentAlpha && I915BlendOp[op].src_alpha) {
-        if (dblend == I915_DST_BLENDFACTOR_SRC_ALPHA) {
-            dblend = I915_DST_BLENDFACTOR_SRC_COLOR;
-        } else if (dblend == I915_DST_BLENDFACTOR_INV_SRC_ALPHA) {
-            dblend = I915_DST_BLENDFACTOR_INV_SRC_COLOR;
+        if (dblend == BLENDFACT_SRC_ALPHA) {
+	    dblend = BLENDFACT_SRC_COLR;
+        } else if (dblend == BLENDFACT_INV_SRC_ALPHA) {
+	    dblend = BLENDFACT_INV_SRC_COLR;
         }
     }
 
-    return sblend | dblend;
+    return (sblend <<S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+	(dblend <<S6_CBUF_DST_BLEND_FACT_SHIFT);
 }
 
 static Bool I915GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
@@ -257,8 +199,7 @@ I915EXACheckComposite(int op, PicturePtr
          * source value that we get to blend with.
          */
         if (I915BlendOp[op].src_alpha &&
-            (I915BlendOp[op].blend_cntl & I915_SRC_BLENDFACTOR_MASK) !=
-             I915_SRC_BLENDFACTOR_ZERO)
+            (I915BlendOp[op].src_blend != BLENDFACT_ZERO))
             	I830FALLBACK("Component alpha not supported with source "
                             "alpha and source value blending.\n");
     }
@@ -410,6 +351,7 @@ ErrorF("i915 prepareComposite\n");
     draw_coords[2][1] = pDst->drawable.y;
     scale_units[2][0] = pDst->drawable.width;
     scale_units[2][1] = pDst->drawable.height;
+    FS_LOCALS(20);
     
     I915DefCtxSetup(pScrn);
 
@@ -426,6 +368,7 @@ ErrorF("i915 prepareComposite\n");
 
     {
 	CARD32 ss2;
+
 	BEGIN_LP_RING(24);
 	/*color buffer*/
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
@@ -495,46 +438,30 @@ ErrorF("i915 prepareComposite\n");
 		texld t1, s1
 		mul oC, t0, t1 ()
 	***/
+    FS_BEGIN();
+
     if (!pMask) {
-	BEGIN_LP_RING(1+3+3+3);
-	OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |(3*3-1));
-	OUT_DCL(S, 0);
-	OUT_DCL(T, 0);
-	OUT_TEXLD(OC, 0, 0, T, 0);
-	ADVANCE_LP_RING();
+	i915_fs_dcl(FS_S0);
+	i915_fs_dcl(FS_T0);
+	i915_fs_texld(FS_OC, FS_S0, FS_T0);
     } else {
-	BEGIN_LP_RING(1+3*6+3);
-	OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |(3*7-1));
-	OUT_DCL(S, 0);
-	OUT_DCL(S, 1);
-	OUT_DCL(T, 0);
-	OUT_DCL(T, 1);
-	OUT_TEXLD(R, 0, 0, T, 0);
-	OUT_TEXLD(R, 1, 1, T, 1);
+	i915_fs_dcl(FS_S0);
+	i915_fs_dcl(FS_S1);
+	i915_fs_dcl(FS_T0);
+	i915_fs_dcl(FS_T1);
+	i915_fs_texld(FS_R0, FS_S0, FS_T0);
+	i915_fs_texld(FS_R1, FS_S1, FS_T1);
+
 	if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
-		/* then just mul */
-		OUT_RING(A0_MUL | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | 
-			(0 << A0_DEST_NR_SHIFT) | A0_DEST_CHANNEL_ALL | 
-			(REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
-		OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT)|(SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT)|
-			(SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT)|(SRC_W << A1_SRC0_CHANNEL_W_SHIFT)|
-			(REG_TYPE_R << A1_SRC1_TYPE_SHIFT) | (1 << A1_SRC1_NR_SHIFT) |
-			(SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT));
-		OUT_RING((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+	    i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+			i915_fs_operand_reg(FS_R1));
 	} else {
-		/* we should duplicate R1's w for all channel, Arithemic can choose channel to use! */
-		OUT_RING(A0_MUL | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
-			(0 << A0_DEST_NR_SHIFT) | A0_DEST_CHANNEL_ALL |
-			(REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
-		OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) |
-			(SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | (SRC_W << A1_SRC0_CHANNEL_W_SHIFT) |
-			(REG_TYPE_R << A1_SRC1_TYPE_SHIFT) | (1 << A1_SRC1_NR_SHIFT) |
-			(SRC_W << A1_SRC1_CHANNEL_X_SHIFT) | (SRC_W << A1_SRC1_CHANNEL_Y_SHIFT));
-		OUT_RING((SRC_W << A2_SRC1_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+	    i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+			i915_fs_operand(FS_R1, W, W, W, W));
 	}
-	ADVANCE_LP_RING();
     }
-		
+    FS_END();
+
     {
 	CARD32 ss6;
 	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
diff-tree 76a316d0cec92a04c8735926a76e76c21f960d7e (from parents)
Merge: 433cb6ba82698676f6f72e09834aba4d64611d54 84805167ab8a422966355b9753bfcb4dad802413
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 12:31:36 2006 -0400

    Merge branch 'master' into exa
    
    Conflicts:
    
    	src/Makefile.am

diff --cc src/Makefile.am
index 9c2a5c2,f97dc52..c2e49ac
@@@ -58,11 -58,8 +58,12 @@@
  	 i830_3d.c \
  	 i830_reg.h \
  	 i915_3d.c \
+ 	 i915_3d.h \
 -	 i915_reg.h
 +	 i915_reg.h \
 +	 i830_exa.c \
 +	 i830_xaa.c \
 +	 i830_exa_render.c \
 +	 i915_exa_render.c
  
  if DRI
  i810_drv_la_SOURCES += \
diff-tree 84805167ab8a422966355b9753bfcb4dad802413 (from 5176d62ba58c100c87f75a4f333d00129d780c99)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jul 18 18:27:10 2006 -0400

    Convert i915 rotate code to the new fragment program API.

diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 3192762..716f425 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 3 -*- */
 /**************************************************************************
 
 Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
@@ -58,6 +59,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #include "i830.h"
 #include "i915_reg.h"
+#include "i915_3d.h"
 
 #ifdef XF86DRI
 #include "dri.h"
@@ -260,12 +262,13 @@ I915UpdateRotate (ScreenPtr      pScreen
 #endif
 
    if (updateInvarient) {
+      FS_LOCALS(3);
       *pI830->used3D = pScrn->scrnIndex;
 #ifdef XF86DRI
       if (sarea)
          sarea->ctxOwner = myContext;
 #endif
-      BEGIN_LP_RING(64);
+      BEGIN_LP_RING(54);
       /* invarient state */
       OUT_RING(MI_NOOP);
       OUT_RING(_3DSTATE_AA_CMD |
@@ -373,18 +376,6 @@ I915UpdateRotate (ScreenPtr      pScreen
       OUT_RING(_3DSTATE_STIPPLE);
       OUT_RING(0x00000000);
 
-      /* fragment program - texture blend replace*/
-      OUT_RING(0x7d050008);
-      OUT_RING(0x19180000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x19083c00);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x15200000);
-      OUT_RING(0x01000000);
-      OUT_RING(0x00000000);
-
       /* texture sampler state */
       OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
       OUT_RING(0x00000001);
@@ -425,6 +416,13 @@ I915UpdateRotate (ScreenPtr      pScreen
       OUT_RING(use_fence | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
       OUT_RING(((((pScrn->displayWidth * pI830->cpp) / 4) - 1) << 21));
       ADVANCE_LP_RING();
+
+      /* fragment program - texture blend replace*/
+      FS_BEGIN();
+      i915_fs_dcl(FS_S0);
+      i915_fs_dcl(FS_T0);
+      i915_fs_texld(FS_OC, FS_S0, FS_T0);
+      FS_END();
    }
    
    {
diff-tree 5176d62ba58c100c87f75a4f333d00129d780c99 (from 148ef9bdd9e0ef3e7ac86b56a8662b53a3ea9168)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jul 18 16:18:18 2006 -0400

    Add an API for programming i915 fragment programs.

diff --git a/src/Makefile.am b/src/Makefile.am
index 2745e8c..f97dc52 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,7 @@ i810_drv_la_SOURCES = \
 	 i830_3d.c \
 	 i830_reg.h \
 	 i915_3d.c \
+	 i915_3d.h \
 	 i915_reg.h
 
 if DRI
diff --git a/src/i915_3d.h b/src/i915_3d.h
new file mode 100644
index 0000000..fc4ca60
--- /dev/null
+++ b/src/i915_3d.h
@@ -0,0 +1,431 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+/* MASK_* are the unshifted bitmasks of the destination mask in arithmetic
+ * operations
+ */
+#define MASK_X			0x1
+#define MASK_Y			0x2
+#define MASK_Z			0x4
+#define MASK_W			0x8
+#define MASK_XYZ		(MASK_X | MASK_Y | MASK_W)
+#define MASK_XYZW		(MASK_XYZ | MASK_W)
+#define MASK_SATURATE		0x10
+
+/* Temporary, undeclared regs. Preserved between phases */
+#define FS_R0			((REG_TYPE_R << 8) | 0)
+#define FS_R1			((REG_TYPE_R << 8) | 1)
+#define FS_R2			((REG_TYPE_R << 8) | 2)
+#define FS_R3			((REG_TYPE_R << 8) | 3)
+
+/* Texture coordinate regs.  Must be declared. */
+#define FS_T0			((REG_TYPE_T << 8) | 0)
+#define FS_T1			((REG_TYPE_T << 8) | 1)
+#define FS_T2			((REG_TYPE_T << 8) | 2)
+#define FS_T3			((REG_TYPE_T << 8) | 3)
+#define FS_T4			((REG_TYPE_T << 8) | 4)
+#define FS_T5			((REG_TYPE_T << 8) | 5)
+#define FS_T6			((REG_TYPE_T << 8) | 6)
+#define FS_T7			((REG_TYPE_T << 8) | 7)
+#define FS_T8			((REG_TYPE_T << 8) | 8)
+#define FS_T9			((REG_TYPE_T << 8) | 9)
+#define FS_T10			((REG_TYPE_T << 8) | 10)
+
+/* Constant values */
+#define FS_C0			((REG_TYPE_CONST << 8) | 0)
+#define FS_C1			((REG_TYPE_CONST << 8) | 1)
+#define FS_C2			((REG_TYPE_CONST << 8) | 2)
+#define FS_C3			((REG_TYPE_CONST << 8) | 3)
+
+/* Sampler regs */
+#define FS_S0			((REG_TYPE_S << 8) | 0)
+#define FS_S1			((REG_TYPE_S << 8) | 1)
+#define FS_S2			((REG_TYPE_S << 8) | 2)
+#define FS_S3			((REG_TYPE_S << 8) | 3)
+
+/* Output color */
+#define FS_OC			((REG_TYPE_OC << 8) | 0)
+
+/* Output depth */
+#define FS_OD			((REG_TYPE_OD << 8) | 0)
+
+/* Unpreserved temporary regs */
+#define FS_U0			((REG_TYPE_U << 8) | 0)
+#define FS_U1			((REG_TYPE_U << 8) | 1)
+#define FS_U2			((REG_TYPE_U << 8) | 2)
+#define FS_U3			((REG_TYPE_U << 8) | 3)
+
+#define REG_TYPE(reg)		((reg) >> 8)
+#define REG_NR(reg)		((reg) & 0xff)
+
+struct i915_fs_op {
+    CARD32 ui[3];
+};
+
+#define X_CHANNEL_VAL		1
+#define Y_CHANNEL_VAL		2
+#define Z_CHANNEL_VAL		3
+#define W_CHANNEL_VAL		4
+#define ZERO_CHANNEL_VAL	5
+#define ONE_CHANNEL_VAL		6
+
+/**
+ * This structure represents the contents of an operand to an i915 fragment
+ * shader.
+ *
+ * It is not a hardware representation, though closely related.
+ */
+struct i915_fs_operand {
+    /**< REG_TYPE_* register type */
+    int reg;
+    /**< *_CHANNEL_VAL swizzle value, with optional negation */
+    int x;
+    /**< *_CHANNEL_VAL swizzle value, with optional negation */
+    int y;
+    /**< *_CHANNEL_VAL swizzle value, with optional negation */
+    int z;
+    /**< *_CHANNEL_VAL swizzle value, with optional negation */
+    int w;
+};
+
+/**
+ * Construct an operand description for the fragment shader.
+ *
+ * \param regtype FS_* register used as the source value for X/Y/Z/W sources.
+ * \param x *_CHANNEL_VAL swizzle value prefix for operand X channel, with
+ *          optional negation.
+ * \param y *_CHANNEL_VAL swizzle value prefix for operand Y channel, with
+ *          optional negation.
+ * \param z *_CHANNEL_VAL swizzle value prefix for operand Z channel, with
+ *          optional negation.
+ * \param w *_CHANNEL_VAL swizzle value prefix for operand W channel, with
+ *          optional negation.
+ */
+#define i915_fs_operand(reg, x, y, z, w)				\
+    _i915_fs_operand(reg,						\
+		     x##_CHANNEL_VAL, y##_CHANNEL_VAL,			\
+		     z##_CHANNEL_VAL, w##_CHANNEL_VAL)
+
+/**
+ * Construct an oeprand description for using a register with no swizzling
+ */
+#define i915_fs_operand_reg(reg)					\
+    i915_fs_operand(reg, X, Y, Z, W)
+
+static inline struct i915_fs_operand
+_i915_fs_operand(int reg, int x, int y, int z, int w)
+{
+    struct i915_fs_operand operand;
+
+    operand.reg = reg;
+    operand.x = x;
+    operand.y = y;
+    operand.z = z;
+    operand.w = w;
+
+    return operand;
+}
+
+/**
+ * Returns an operand containing (0.0, 0.0, 0.0, 0.0).
+ */
+static inline struct i915_fs_operand
+i915_fs_operand_zero(void)
+{
+    return i915_fs_operand(FS_R0, ZERO, ZERO, ZERO, ZERO);
+}
+
+/**
+ * Returns an unused operand
+ */
+#define i915_fs_operand_none() i915_fs_operand_zero()
+
+/**
+ * Returns an operand containing (1.0, 1.0, 1.0, 1.0).
+ */
+static inline struct i915_fs_operand
+i915_fs_operand_one(void)
+{
+    return i915_fs_operand(FS_R0, ONE, ONE, ONE, ONE);
+}
+
+static inline int
+i915_get_hardware_channel_val(int channel_val)
+{
+    if (channel_val < 0)
+	channel_val = -channel_val;
+
+    switch (channel_val) {
+    case X_CHANNEL_VAL:
+	return SRC_X;
+    case Y_CHANNEL_VAL:
+	return SRC_Y;
+    case Z_CHANNEL_VAL:
+	return SRC_Z;
+    case W_CHANNEL_VAL:
+	return SRC_W;
+    case ZERO_CHANNEL_VAL:
+	return SRC_ZERO;
+    case ONE_CHANNEL_VAL:
+	return SRC_ONE;
+    }
+    FatalError("Bad channel value %d\n", channel_val);
+}
+
+/**
+ * Outputs a fragment shader command to declare a sampler or texture register.
+ */
+#define i915_fs_dcl(reg)						\
+do {									\
+    FS_OUT(_i915_fs_dcl(reg));						\
+} while (0)
+
+/**
+ * Constructs a fragment shader command to declare a sampler or texture
+ * register.
+ */
+static inline struct i915_fs_op
+_i915_fs_dcl(int reg)
+{
+    struct i915_fs_op op;
+
+    op.ui[0] = D0_DCL | (REG_TYPE(reg) << D0_TYPE_SHIFT) |
+	(REG_NR(reg) << D0_NR_SHIFT);
+    op.ui[1] = 0;
+    op.ui[2] = 0;
+    if (REG_TYPE(reg) != REG_TYPE_S)
+	op.ui[0] |= D0_CHANNEL_ALL;
+
+    return op;
+}
+
+/**
+ * Constructs a fragment shader command to load from a texture sampler.
+ */
+#define i915_fs_texld(dest_reg, sampler_reg, address_reg)		\
+do {									\
+     FS_OUT(_i915_fs_texld(T0_TEXLD, 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)
+{
+    struct i915_fs_op op;
+
+    op.ui[0] = 0;
+    op.ui[1] = 0;
+    op.ui[2] = 0;
+
+    if (REG_TYPE(sampler_reg) != REG_TYPE_S)
+	FatalError("Bad sampler reg type\n");
+
+    op.ui[0] |= load_op;
+    op.ui[0] |= REG_TYPE(dest_reg) << T0_DEST_TYPE_SHIFT;
+    op.ui[0] |= REG_NR(dest_reg) << T0_DEST_NR_SHIFT;
+    op.ui[0] |= REG_NR(sampler_reg) << T0_SAMPLER_NR_SHIFT;
+    op.ui[1] |= REG_TYPE(address_reg) << T1_ADDRESS_REG_TYPE_SHIFT;
+    op.ui[1] |= REG_NR(address_reg) << T1_ADDRESS_REG_NR_SHIFT;
+
+    return op;
+}
+
+#define i915_fs_arith(op, dest_reg, operand0, operand1, operand2)	\
+    _i915_fs_arith(A0_##op, dest_reg, operand0, operand1, operand2)
+
+static inline struct i915_fs_op
+_i915_fs_arith(int cmd, int dest_reg,
+	       struct i915_fs_operand operand0,
+	       struct i915_fs_operand operand1,
+	       struct i915_fs_operand operand2)
+{
+    struct i915_fs_op op;
+
+    op.ui[0] = 0;
+    op.ui[1] = 0;
+    op.ui[2] = 0;
+
+    /* Set up destination register and write mask */
+    op.ui[0] |= cmd;
+    op.ui[0] |= REG_TYPE(dest_reg) << A0_DEST_TYPE_SHIFT;
+    op.ui[0] |= REG_NR(dest_reg) << A0_DEST_NR_SHIFT;
+    op.ui[0] |= A0_DEST_CHANNEL_ALL;
+
+    /* Set up operand 0 */
+    op.ui[0] |= REG_TYPE(operand0.reg) << A0_SRC0_TYPE_SHIFT;
+    op.ui[0] |= REG_NR(operand0.reg) << A0_SRC0_NR_SHIFT;
+
+    op.ui[1] |= i915_get_hardware_channel_val(operand0.x) <<
+	A1_SRC0_CHANNEL_X_SHIFT;
+    if (operand0.x < 0)
+	op.ui[1] |= A1_SRC0_CHANNEL_X_NEGATE;
+
+    op.ui[1] |= i915_get_hardware_channel_val(operand0.y) <<
+	A1_SRC0_CHANNEL_Y_SHIFT;
+    if (operand0.y < 0)
+	op.ui[1] |= A1_SRC0_CHANNEL_Y_NEGATE;
+
+    op.ui[1] |= i915_get_hardware_channel_val(operand0.z) <<
+	A1_SRC0_CHANNEL_Z_SHIFT;
+    if (operand0.z < 0)
+	op.ui[1] |= A1_SRC0_CHANNEL_Z_NEGATE;
+
+    op.ui[1] |= i915_get_hardware_channel_val(operand0.w) <<
+	A1_SRC0_CHANNEL_W_SHIFT;
+    if (operand0.w < 0)
+	op.ui[1] |= A1_SRC0_CHANNEL_W_NEGATE;
+
+    /* Set up operand 1 */
+    op.ui[1] |= REG_TYPE(operand1.reg) << A1_SRC1_TYPE_SHIFT;
+    op.ui[1] |= REG_NR(operand1.reg) << A1_SRC1_NR_SHIFT;
+
+    op.ui[1] |= i915_get_hardware_channel_val(operand1.x) <<
+	A1_SRC1_CHANNEL_X_SHIFT;
+    if (operand1.x < 0)
+	op.ui[1] |= A1_SRC1_CHANNEL_X_NEGATE;
+
+    op.ui[1] |= i915_get_hardware_channel_val(operand1.y) <<
+	A1_SRC1_CHANNEL_Y_SHIFT;
+    if (operand1.y < 0)
+	op.ui[1] |= A1_SRC1_CHANNEL_Y_NEGATE;
+
+    op.ui[2] |= i915_get_hardware_channel_val(operand1.z) <<
+	A2_SRC1_CHANNEL_Z_SHIFT;
+    if (operand1.z < 0)
+	op.ui[2] |= A2_SRC1_CHANNEL_Z_NEGATE;
+
+    op.ui[2] |= i915_get_hardware_channel_val(operand1.w) <<
+	A2_SRC1_CHANNEL_W_SHIFT;
+    if (operand1.w < 0)
+	op.ui[2] |= A2_SRC1_CHANNEL_W_NEGATE;
+
+    /* Set up operand 2 */
+    op.ui[2] |= REG_TYPE(operand2.reg) << A2_SRC2_TYPE_SHIFT;
+    op.ui[2] |= REG_NR(operand2.reg) << A2_SRC2_NR_SHIFT;
+
+    op.ui[2] |= i915_get_hardware_channel_val(operand2.x) <<
+	A2_SRC2_CHANNEL_X_SHIFT;
+    if (operand2.x < 0)
+	op.ui[2] |= A2_SRC2_CHANNEL_X_NEGATE;
+
+    op.ui[2] |= i915_get_hardware_channel_val(operand2.y) <<
+	A2_SRC2_CHANNEL_Y_SHIFT;
+    if (operand2.y < 0)
+	op.ui[2] |= A2_SRC2_CHANNEL_Y_NEGATE;
+
+    op.ui[2] |= i915_get_hardware_channel_val(operand2.z) <<
+	A2_SRC2_CHANNEL_Z_SHIFT;
+    if (operand2.z < 0)
+	op.ui[2] |= A2_SRC2_CHANNEL_Z_NEGATE;
+
+    op.ui[2] |= i915_get_hardware_channel_val(operand2.w) <<
+	A2_SRC2_CHANNEL_W_SHIFT;
+    if (operand2.w < 0)
+	op.ui[2] |= A2_SRC2_CHANNEL_W_NEGATE;
+
+    return op;
+}
+
+/**
+ * Move the values in operand0 to the dest reg with the masking/saturation
+ * specified.
+ */
+#define i915_fs_mov_masked(dest_reg, dest_mask, operand0)		\
+do {									\
+    struct i915_fs_op op;						\
+									\
+    op = i915_fs_arith(MOV, dest_reg, operand0, i915_fs_operand_none(),	\
+		       i915_fs_operand_none());				\
+    op.ui[0] &= ~A0_DEST_CHANNEL_ALL;					\
+    op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \
+    if ((dest_mask) & MASK_SATURATE)					\
+	op.ui[0] |= A0_DEST_SATURATE;					\
+									\
+    FS_OUT(op);								\
+} while (0)
+
+/** Add operand0 and operand1 and put the result in dest_reg */
+#define i915_fs_add(dest_reg, operand0, operand1)			\
+do {									\
+    FS_OUT(i915_fs_arith(ADD, dest_reg, operand0, operand1,		\
+			 i915_fs_operand_none()));			\
+} while (0)
+
+/**
+ * Perform a 3-component dot-product of operand0 and operand1 and put the
+ * resulting scalar in the channels of dest_reg specified by the dest_mask.
+ */
+#define i915_fs_dp3_masked(dest_reg, dest_mask, operand0, operand1)	\
+do {									\
+    struct i915_fs_op op;						\
+									\
+    op = i915_fs_arith(DP3, dest_reg, operand0, i915_fs_operand_none(),	\
+		       i915_fs_operand_none());				\
+    op.ui[0] &= ~A0_DEST_CHANNEL_ALL;					\
+    op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \
+    if ((dest_mask) & MASK_SATURATE)					\
+	op.ui[0] |= A0_DEST_SATURATE;					\
+									\
+    FS_OUT(op);								\
+} while (0)
+
+/**
+ * Sets up local state for accumulating a fragment shader buffer.
+ *
+ * \param x maximum number of shader commands that may be used between
+ *        a FS_START and FS_END
+ */
+#define FS_LOCALS(x)							\
+    CARD32 _shader_buf[(x) * 3];					\
+    int _max_shader_commands = x;					\
+    int _cur_shader_commands
+
+#define FS_BEGIN()							\
+do {									\
+    _cur_shader_commands = 0;						\
+} while (0)
+
+#define FS_OUT(_shaderop)						\
+do {									\
+    _shader_buf[_cur_shader_commands * 3 + 0] = _shaderop.ui[0];	\
+    _shader_buf[_cur_shader_commands * 3 + 1] = _shaderop.ui[1];	\
+    _shader_buf[_cur_shader_commands * 3 + 2] = _shaderop.ui[2];	\
+    if (++_cur_shader_commands > _max_shader_commands)			\
+	 FatalError("fragment shader command buffer exceeded (%d)\n",	\
+		    _cur_shader_commands);				\
+} while (0)
+
+#define FS_END()							\
+do {									\
+    int _i;								\
+    BEGIN_LP_RING(_cur_shader_commands * 3 + 1);			\
+    OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |				\
+	     (_cur_shader_commands * 3 - 1));				\
+    for (_i = 0; _i < _cur_shader_commands * 3; _i++)			\
+	OUT_RING(_shader_buf[_i]);					\
+    ADVANCE_LP_RING();							\
+} while (0);
diff-tree 148ef9bdd9e0ef3e7ac86b56a8662b53a3ea9168 (from 16d6263e6518a4a05562e2842ff2d0fdb4710304)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jul 17 22:32:25 2006 -0700

    Convert magic numbers to symbolic names in i915 rotate code.
    
    This doesn't cover the fragment shader yet, which we need to make a sensible
    set of macros for (at least the basic bits).
    
    Reviewed by:	md5

diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 4d7237f..3192762 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -57,6 +57,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "shadow.h"
 
 #include "i830.h"
+#include "i915_reg.h"
 
 #ifdef XF86DRI
 #include "dri.h"
@@ -267,58 +268,111 @@ I915UpdateRotate (ScreenPtr      pScreen
       BEGIN_LP_RING(64);
       /* invarient state */
       OUT_RING(MI_NOOP);
-      OUT_RING(0x66014140);
-      OUT_RING(0x7d990000);
+      OUT_RING(_3DSTATE_AA_CMD |
+	       AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 |
+	       AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
+
+      OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
       OUT_RING(0x00000000);
-      OUT_RING(0x7d9a0000);
+
+      OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
       OUT_RING(0x00000000);
-      OUT_RING(0x7d980000);
+
+      OUT_RING(_3DSTATE_DFLT_Z_CMD);
       OUT_RING(0x00000000);
-      OUT_RING(0x76fac688);
-      OUT_RING(0x6700a770);
-      OUT_RING(0x7d040081);
+
+      OUT_RING(_3DSTATE_COORD_SET_BINDINGS |
+	       CSB_TCB(0, 0) | CSB_TCB(1, 1) |
+	       CSB_TCB(2, 2) | CSB_TCB(3, 3) |
+	       CSB_TCB(4, 4) | CSB_TCB(5, 5) |
+	       CSB_TCB(6, 6) | CSB_TCB(7, 7));
+
+      OUT_RING(_3DSTATE_RASTER_RULES_CMD |
+	       ENABLE_TRI_FAN_PROVOKE_VRTX | TRI_FAN_PROVOKE_VRTX(2) |
+	       ENABLE_LINE_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) |
+	       ENABLE_TEXKILL_3D_4D | TEXKILL_4D |
+	       ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
+
+      OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
       OUT_RING(0x00000000);
+
       /* flush map & render cache */
       OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
       OUT_RING(0x00000000);
+
       /* draw rect */
-      OUT_RING(0x7d800003);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      /* scissor */
-      OUT_RING(0x7c800002);
-      OUT_RING(0x7d810001);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x7c000003);
+      OUT_RING(_3DSTATE_DRAW_RECT_CMD);
+      OUT_RING(DRAW_DITHER_OFS_X(0) | DRAW_DITHER_OFS_Y(0));
+      OUT_RING(DRAW_XMIN(0) | DRAW_YMIN(0));
+      OUT_RING(DRAW_XMAX(pScrn->virtualX - 1) |
+	       DRAW_YMAX(pScrn->virtualY - 1));
+      OUT_RING(DRAW_XORG(0) | DRAW_YORG(0));
+
+      OUT_RING(MI_NOOP);
+
+      OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
+      OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
+      OUT_RING(0x00000000); /* ymin, xmin */
+      OUT_RING(0x00000000); /* ymax, xmax */
+
+      OUT_RING(0x7c000003); /* XXX: magic numbers */
       OUT_RING(0x7d070000);
       OUT_RING(0x00000000);
       OUT_RING(0x68000002);
+
       /* context setup */
-      OUT_RING(0x6db3ffff);
-      OUT_RING(0x7d040744);
-      OUT_RING(0xfffffff0);
-      OUT_RING(0x00902c80);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00020216);
-      OUT_RING(0x6ba008a1);
-      OUT_RING(0x7d880000);
-      OUT_RING(0x00000000);
-      /* dv0 */
-      OUT_RING(0x7d850000);
-      /* dv1 */
-      if (pI830->cpp == 1)
-         OUT_RING(0x10880000);
-      else if (pI830->cpp == 2)
-            OUT_RING(0x10880200);
-         else
-            OUT_RING(0x10880308);
-      /* stipple */
-      OUT_RING(0x7d830000);
+      OUT_RING(_3DSTATE_MODES_4_CMD |
+	       ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
+	       MODE4_ENABLE_STENCIL_WRITE_MASK |
+	       MODE4_ENABLE_STENCIL_TEST_MASK);
+
+      OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+	       I1_LOAD_S(2) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
+
+      OUT_RING(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
+	       S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
+	       S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
+	       S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
+	       S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
+	       S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
+	       S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
+	       S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
+      OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
+	       S4_CULLMODE_NONE | S4_VFMT_SPEC_FOG | S4_VFMT_COLOR |
+	       S4_VFMT_XYZW);
+      OUT_RING(0x00000000); /* S5 -- enable bits */
+      OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
+	       (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+	       (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE |
+	       (2 << S6_TRISTRIP_PV_SHIFT));
+
+      OUT_RING(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
+	       IAB_MODIFY_ENABLE |
+	       IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
+	       IAB_MODIFY_SRC_FACTOR |
+	       (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) |
+	       IAB_MODIFY_DST_FACTOR |
+	       (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT));
+
+      OUT_RING(_3DSTATE_CONST_BLEND_COLOR_CMD);
+      OUT_RING(0x00000000);
+
+      OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
+      if (pI830->cpp == 1) {
+	 OUT_RING(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) |
+		  DSTORG_VERT_BIAS(0x8) | COLR_BUF_8BIT);
+      } else if (pI830->cpp == 2) {
+	 OUT_RING(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) |
+		  DSTORG_VERT_BIAS(0x8) | COLR_BUF_RGB565);
+      } else {
+	 OUT_RING(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) |
+		  DSTORG_VERT_BIAS(0x8) | COLR_BUF_ARGB8888 |
+		  DEPTH_FRMT_24_FIXED_8_OTHER);
+      }
+
+      OUT_RING(_3DSTATE_STIPPLE);
       OUT_RING(0x00000000);
+
       /* fragment program - texture blend replace*/
       OUT_RING(0x7d050008);
       OUT_RING(0x19180000);
@@ -330,22 +384,25 @@ I915UpdateRotate (ScreenPtr      pScreen
       OUT_RING(0x15200000);
       OUT_RING(0x01000000);
       OUT_RING(0x00000000);
+
       /* texture sampler state */
-      OUT_RING(0x7d010003);
+      OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
       OUT_RING(0x00000001);
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
+
       /* front buffer, pitch, offset */
-      OUT_RING(0x7d8e0001);
-      OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+      OUT_RING(_3DSTATE_BUF_INFO_CMD);
+      OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
+	       BUF_3D_PITCH(pI830->displayWidth * pI830->cpp));
       if (I830IsPrimary(pScrn))
          OUT_RING(pI830->FrontBuffer.Start);
       else 
          OUT_RING(pI8301->FrontBuffer2.Start);
 
       /* Set the entire frontbuffer up as a texture */
-      OUT_RING(0x7d000003);
+      OUT_RING(_3DSTATE_MAP_STATE | 3);
       OUT_RING(0x00000001);
 
       if (I830IsPrimary(pScrn)) 
@@ -359,12 +416,12 @@ I915UpdateRotate (ScreenPtr      pScreen
          use_fence = 4;
       
       if (pI830->cpp == 1)
-         use_fence |= 0x80; /* MAPSURF_8BIT */
+	 use_fence |= MAPSURF_8BIT;
       else
       if (pI830->cpp == 2)
-         use_fence |= 0x100; /* MAPSURF_16BIT */
+	 use_fence |= MAPSURF_16BIT;
       else
-         use_fence |= 0x180; /* MAPSURF_32BIT */
+	 use_fence |= MAPSURF_32BIT;
       OUT_RING(use_fence | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
       OUT_RING(((((pScrn->displayWidth * pI830->cpp) / 4) - 1) << 21));
       ADVANCE_LP_RING();
@@ -395,7 +452,7 @@ I915UpdateRotate (ScreenPtr      pScreen
       OUT_RING(MI_NOOP);
 
       /* vertex data */
-      OUT_RING(0x7f0c001f);
+      OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (32 - 1));
       verts[0][0] = box_x1; verts[0][1] = box_y1;
       verts[1][0] = box_x2; verts[1][1] = box_y1;
       verts[2][0] = box_x2; verts[2][1] = box_y2;
diff --git a/src/i915_reg.h b/src/i915_reg.h
index 886ae81..6d4f8fc 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -233,6 +233,22 @@
 #define IAB_DST_FACTOR_SHIFT		0
 #define IAB_DST_FACTOR_MASK		(BLENDFACT_MASK<<0)
 
+#define BLENDFACT_ZERO			0x01
+#define BLENDFACT_ONE			0x02
+#define BLENDFACT_SRC_COLR		0x03
+#define BLENDFACT_INV_SRC_COLR 		0x04
+#define BLENDFACT_SRC_ALPHA		0x05
+#define BLENDFACT_INV_SRC_ALPHA 	0x06
+#define BLENDFACT_DST_ALPHA		0x07
+#define BLENDFACT_INV_DST_ALPHA 	0x08
+#define BLENDFACT_DST_COLR		0x09
+#define BLENDFACT_INV_DST_COLR		0x0a
+#define BLENDFACT_SRC_ALPHA_SATURATE	0x0b
+#define BLENDFACT_CONST_COLOR		0x0c
+#define BLENDFACT_INV_CONST_COLOR	0x0d
+#define BLENDFACT_CONST_ALPHA		0x0e
+#define BLENDFACT_INV_CONST_ALPHA	0x0f
+#define BLENDFACT_MASK          	0x0f
 
 #define BLENDFUNC_ADD			0x0
 #define BLENDFUNC_SUBTRACT		0x1
@@ -430,6 +446,7 @@
 #define ENABLE_LOGIC_OP_FUNC		(1<<23)
 #define LOGIC_OP_FUNC(x)		((x)<<18)
 #define LOGICOP_MASK			(0xf<<18)
+#define LOGICOP_COPY			0xc
 #define MODE4_ENABLE_STENCIL_TEST_MASK	((1<<17)|(0xff00))
 #define ENABLE_STENCIL_TEST_MASK	(1<<17)
 #define STENCIL_TEST_MASK(x)		((x)<<8)
diff-tree 16d6263e6518a4a05562e2842ff2d0fdb4710304 (from 2f50f6d1b1b3fa4fbec98bd8fa5818df890070e7)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Sun Jul 16 20:39:52 2006 +0100

    whoops, reverse part of that.

diff --git a/src/i830.h b/src/i830.h
index 2584e22..14e921d 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -141,7 +141,7 @@ typedef struct {
 } I830RingBuffer;
 
 typedef struct {
-   unsigned int Fence[FENCE_NEW_NR * 2]; /* i965 has more fence regs */
+   unsigned int Fence[8];
 } I830RegRec, *I830RegPtr;
 
 typedef struct {
@@ -238,12 +238,6 @@ typedef struct _I830Rec {
    int TexGranularity;
    int drmMinor;
    Bool have3DWindows;
-
-   unsigned int front_tiled;
-   unsigned int back_tiled;
-   unsigned int depth_tiled;
-   unsigned int rotated_tiled;
-   unsigned int rotated2_tiled;
 #endif
 
    Bool NeedRingBufferLow;
@@ -383,9 +377,6 @@ typedef struct _I830Rec {
    Bool devicePresence;
 
    OsTimerPtr devicesTimer;
-
-   CARD32 savedAsurf;
-   CARD32 savedBsurf;
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
diff-tree 2f50f6d1b1b3fa4fbec98bd8fa5818df890070e7 (from b1c2ea653502dd8547079e7014b698f241433dff)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Sun Jul 16 20:17:38 2006 +0100

    move ContextMem out of XF86DRI

diff --git a/src/i830.h b/src/i830.h
index 79eb310..2584e22 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -141,7 +141,7 @@ typedef struct {
 } I830RingBuffer;
 
 typedef struct {
-   unsigned int Fence[8];
+   unsigned int Fence[FENCE_NEW_NR * 2]; /* i965 has more fence regs */
 } I830RegRec, *I830RegPtr;
 
 typedef struct {
@@ -230,14 +230,20 @@ typedef struct _I830Rec {
    CreateScreenResourcesProcPtr    CreateScreenResources;
    int *used3D;
 
+   I830MemRange ContextMem;
 #ifdef XF86DRI
    I830MemRange BackBuffer;
    I830MemRange DepthBuffer;
    I830MemRange TexMem;
    int TexGranularity;
-   I830MemRange ContextMem;
    int drmMinor;
    Bool have3DWindows;
+
+   unsigned int front_tiled;
+   unsigned int back_tiled;
+   unsigned int depth_tiled;
+   unsigned int rotated_tiled;
+   unsigned int rotated2_tiled;
 #endif
 
    Bool NeedRingBufferLow;
@@ -377,6 +383,9 @@ typedef struct _I830Rec {
    Bool devicePresence;
 
    OsTimerPtr devicesTimer;
+
+   CARD32 savedAsurf;
+   CARD32 savedBsurf;
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
diff-tree b1c2ea653502dd8547079e7014b698f241433dff (from 8a44a7acfcadbba2410dca750afc9d32bc83706e)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Jul 11 08:13:30 2006 +0100

    whoops, revert some unnecessary changes

diff --git a/src/i830_driver.c b/src/i830_driver.c
index e55e421..5ce88e1 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -955,8 +955,6 @@ I830Set640x480(ScrnInfoPtr pScrn)
    if (VBESetVBEMode(pI830->pVbe, m, NULL))
 	   return TRUE;
 
-   ErrorF("Set640x480 failed1\n");
-
    /* if the first failed, let's try the next - usually 800x600 */
    m = 0x32;
    switch (pScrn->depth) {
@@ -972,8 +970,6 @@ I830Set640x480(ScrnInfoPtr pScrn)
    if (VBESetVBEMode(pI830->pVbe, m, NULL))
 	   return TRUE;
 
-   ErrorF("Set640x480 failed2\n");
-
    return FALSE;
 }
 
@@ -5576,10 +5572,6 @@ I830BIOSEnterVT(int scrnIndex, int flags
 
    pI830->leaving = FALSE;
 
-   /* Detect monitor change and switch to suitable mode */
-   if (!pI830->starting)
-      I830DetectMonitorChange(pScrn);
-
 #if 1
    /* Clear the framebuffer */
    memset(pI830->FbBase + pScrn->fbOffset, 0,
@@ -5638,11 +5630,9 @@ I830BIOSEnterVT(int scrnIndex, int flags
    ResetState(pScrn, FALSE);
    SetHWOperatingState(pScrn);
 
-#if 0
    /* Detect monitor change and switch to suitable mode */
    if (!pI830->starting)
       I830DetectMonitorChange(pScrn);
-#endif
 	    
    if (!I830VESASetMode(pScrn, pScrn->currentMode))
       return FALSE;
diff-tree 8a44a7acfcadbba2410dca750afc9d32bc83706e (from parents)
Merge: 584b544987be5cf23dce29ddaf3130e59cfe6fa8 e7723a4e5725147d3bd9ba22c5a3314b0556e440
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Jul 11 07:41:27 2006 +0100

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-video-intel

diff-tree 584b544987be5cf23dce29ddaf3130e59cfe6fa8 (from 5a1b68993f3a3a2e8dcd428a7118e29c36703cd6)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Jul 11 07:40:40 2006 +0100

    Add an additional check before rotating

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 80a46a4..e55e421 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -955,6 +955,8 @@ I830Set640x480(ScrnInfoPtr pScrn)
    if (VBESetVBEMode(pI830->pVbe, m, NULL))
 	   return TRUE;
 
+   ErrorF("Set640x480 failed1\n");
+
    /* if the first failed, let's try the next - usually 800x600 */
    m = 0x32;
    switch (pScrn->depth) {
@@ -970,6 +972,8 @@ I830Set640x480(ScrnInfoPtr pScrn)
    if (VBESetVBEMode(pI830->pVbe, m, NULL))
 	   return TRUE;
 
+   ErrorF("Set640x480 failed2\n");
+
    return FALSE;
 }
 
@@ -5572,6 +5576,10 @@ I830BIOSEnterVT(int scrnIndex, int flags
 
    pI830->leaving = FALSE;
 
+   /* Detect monitor change and switch to suitable mode */
+   if (!pI830->starting)
+      I830DetectMonitorChange(pScrn);
+
 #if 1
    /* Clear the framebuffer */
    memset(pI830->FbBase + pScrn->fbOffset, 0,
@@ -5630,9 +5638,11 @@ I830BIOSEnterVT(int scrnIndex, int flags
    ResetState(pScrn, FALSE);
    SetHWOperatingState(pScrn);
 
+#if 0
    /* Detect monitor change and switch to suitable mode */
    if (!pI830->starting)
       I830DetectMonitorChange(pScrn);
+#endif
 	    
    if (!I830VESASetMode(pScrn, pScrn->currentMode))
       return FALSE;
@@ -5718,7 +5728,7 @@ I830BIOSSwitchMode(int scrnIndex, Displa
     * The extra WindowTable check detects a rotation at startup.
     */
    if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) &&
-         !pI830->DGAactive ) {
+         !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) ) {
       if (!I830Rotate(pScrn, mode))
          ret = FALSE;
    }



More information about the xorg-commit mailing list